宣告:部分內容來自網路收集需求
線上user表目前存在四個欄位user(uid, name, passwd, nick),現在需要增加兩個欄位age, ***,變為user(uid, name, passwd, nick, age, ***)
背景
目前user表資料量較大,且併發請求量較大
解決方案:
方案一、
alter table add column
優勢:方案最為簡單
因為背景以及交代了,資料量較大,且併發請求高,mysql在alter table時會鎖表,且資料量較大,導致鎖表時間過長,無法接受
方案二、
在專案上線初期,預留字段
優勢:可以在需要擴充套件表字段的時候,自動使用預留的字段,因為欄位在第一次建表時已經建立了,因此不需要擴充,直接使用已經存在的字段
劣勢:1、預留欄位的數量無法確定,預留多了,浪費儲存空間,預留少了,未來還是要在表上增加字段(只是推遲了時間)
2、預留的字段只能定義為varchar型別的可辯字串,無法支援其他型別字段,如果需要檢索,varchar型別建立索引非理想方案
3、預留字段,欄位名稱不具有語義化,例如在建立初期,可能叫ext1、ext2等,但是ext1、ext2不具有語義化,後期維護溝通成本高
方案三使用縱表儲存使用者資訊,例如之前使用者資料
uid
key
value
1name張三1
passport
1231
nick
null
2name李四2
passport
4312
nick
aaa
需要擴充套件age, ***時,資料儲存格式如下
uid
key
value
1name張三1
passport
1231
nick
null
2name李四2
passport
4312
nick
aaa3
name王五3
passport
1233
nick
null
3age113
***1
優勢:1、可以隨意新增字段,字段可以無限擴充套件
2、新舊資料可以同時存在
劣勢:1、同乙個使用者,單行資料變為多行儲存,資料量翻倍
2、在key列不能建立索引(建立索引無不能起到檢索作用),只能在uid列建立索引,檢索方式太單一
方案四、
版本號+通用列
最開始上線的時候,
版本為0
,此時只有
passwd
和nick
兩個屬性,那麼資料為
uidname
version
ext 1張三
02李四0
當需要擴充套件新字段時,將新資料版本公升級為1,新增加age, ***兩個字段,資料變為
uid
name
version
ext 1張三
02李四0
3王五1
優勢:2、新資料和老資料可以共存
3、遷移方便,可以線上寫個指令碼慢慢將老資料修改為新版本資料,並將version修改為1
劣勢:1、無法檢索(雖然mysql5.7開始支援json和json所以,目前本人未進行實際的效能測試)
2、ext列存在大量冗餘的key,雖然可以將key的值縮短,但是會降低key的語義
當然,也有一些將ext這種擴充套件資訊儲存在類似mongodb的nosql資料庫中。
方案五、
新錶+觸發器+遷移資料+rename
基本原理是:
(1)先建立乙個擴充欄位後的新錶user_new(uid, name, passwd, age, ***)
(2)在原表user上建立三個觸發器,對原表user進行的所有insert/delete/update操作,都會對新錶user_new進行相同的操作(這個操作有些公司也侵入到**層面來實現)
(3)分批將原表user中的資料insert到新錶user_new,直至資料遷移完成
(4)刪掉觸發器,把原表移走(預設是drop掉)
(5)把新錶user_new重新命名(rename)成原表user,擴充字段完成。
優勢:整個過程不需要鎖表,可以持續對外提供服務
劣勢:1、整個過程需要進行資料的遷移,如果資料量較大,可能週期較長
2、變更過程中,可能存在資料衝突
3、通過提供觸發器或者**來實現兩次insert/delete/update操作,如果是建立觸發器,會影響原表效能。
方案六、
增加1對1關聯的擴充套件表
例如原來user(uid, name, passwd, nick)
新建乙個user_ext表user(uid, age, ***)
通過uid進行一對一的關聯
優勢:1、在不對原表進行任何操作的情況下,實現字段擴充套件
2、可持續對外提供服務,user表中歷史資料,可以通過指令碼在user_ext慢慢補齊或者在**存在新增預設值,更新的時候做merge操作補齊
劣勢:1、兩張表需要做join操作,在大量資料情況下,存在效能瓶頸。(網際網路公司一般嚴格限制join的使用)
2、user_ext表未來也存在擴充套件欄位的問題。
目前,如果存在對online db進行ddl時,一般公司都會採用第五種方案,雖然操作步驟比較多,週期較長,但是其優勢也比較明顯,不會增長資料量、不會丟失關係型資料庫特性等等
如何做研究
來自 在研究生期間,一開始大家都很迷惑,都不知道自己要幹什麼 該幹什麼?即便知道自己要幹什麼,也不知道從哪幹起?上次兩位老師跟我們交流了一下,下面是他們的心得 給乙個專案 解決方案 問題分塊 任務明細 一開始並不是所有的問題都會想到,但是起碼要有乙個大體的框架在心中,然後細化模組,對每乙個功能進行細...
如何做專案
1,以業務規則為綱,而不是業務實體 2,在思考和設計業務規則的時候,以業務核心為綱,什麼是業務核心,定義為,當前你最關注的,當前最不確定的那一部分。所以我現在不喜歡領域驅動,我喜歡業務驅動 其實可能二者是一碼事 那麼我這裡所說的業務驅動要怎麼驅動法呢?就先以上面兩條為起頭,然後再來說,業務規則,以找...
如何做效能測試?
一提到效能測試,大家首先想到的就是測試工具,很多人認為效能測試就是使用測試工具,會使用測試工具就是會效能測試,我認為這種思想是不對的。什麼叫效能測試呢?效能測試是通過自動化的測試工具模擬多種正常 峰值以及異常負載條件來對系統的各項效能指標進行測試。測試工具只是用於模擬某些特定的情況的,模擬出某些情況...