事情變得有意思了,上一篇花1小時撰寫的“一分鐘”文章,又引起了廣泛的讨論,說明相關的技術大家感興趣,挺好。第一次一篇技術文章的評論量過100,才知道原來“評論精選”還有100上限,甚為欣慰(雖然是以一種自己不願看到的方式)。
《啥,又要為表增加一列屬性?》的方案頗有争議:
(1)版本号version + 擴充字段ext
(2)用增加列的key+value方式擴充屬性
有些評論,隻能說“所謂夏蟲,何以語冰”(作者要謙和,請删除)。因自己時間倉促,有些地方沒有交代清楚,對不起大夥,實在抱歉。大部分評論還是在進行技術讨論,故今天再熬夜補充說明一下。
零、緣起
讨論問題域:
(1)資料量大、并發量高場景,線上資料庫屬性擴充
(2)資料庫表結構擴充性設計
一、哪些方案一定是不行的
(1)alter table add column
要堅持這個方案的,也不多解釋了,大資料高并發情況下,一定不可行
(2)通過增加表的方式擴充,通過外鍵join來查詢
大資料高并發情況下,join性能較差,一定不可行
(3)通過增加表的方式擴充,通過視圖來對外
一定不可行。大資料高并發情況下,網際網路不怎麼使用視圖,至少58禁止使用視圖
(4)必須遵循“第x範式”的方案
一定不可行。網際網路的主要沖突之一是吞吐量,為了保證吞吐量甚至可能犧牲一些事務性和一緻性,通過反範式的方式來確定吞吐量的設計是很常見的,例如:備援資料。網際網路的主要沖突之二是可用性,為了保證可用性,常見的技術方案也是資料備援。在網際網路資料庫架構設計中,第x範式真的沒有這麼重要
(5)打産品經理
朋友,這是段子麼,這一定不可行
二、哪些方案可行,但文章未提及
(1)提前預留一些reserved字段
這個是可以的。但如果預留過多,會造成空間浪費,預留過少,不一定達得到擴充效果。
(2)通過增加表的方式擴充列,上遊通過service來屏蔽底層的細節
這個也是可以的。Jeff同學提到的UserExt(uid, newCol1, newCol2)就是這樣的方案(但join連表和視圖是不行的)
三、哪些讀者沒有仔細看文章
(1)version+ext太弱了,ext不支援索引
回複:屬于沒有仔細看文章,文章也提了如果有強需求索引可以使用MongoDB,它就是使用的json存儲(評論中有不少朋友提到,還有其他資料庫支援json檢索)
(2)第二種key+value方案不支援索引
回複:uid可以索引
四、key+value方式使用場景
服務端,wordpress,EAV,配置,統計項等都經常使用這個方案。
用戶端(APP或者PC),儲存個人資訊也經常使用這個方案。
今天的重點
以樓主性格,本不會進行“解釋”,上文解釋這般,說明這一次,樓主真的認真了。對于技術,認真是好事,認真的男人最可愛(打住,我要吐了)。好了,下面的内容才是今天的重點。
五、線上表結構變更
在《啥,又要為表增加一列屬性?》文章的開頭,已經說明常見“新表+觸發器+遷移資料+rename”方案(pt-online-schema-change),這是業内非常成熟的擴充列的方案(以為大夥都熟悉,沒有展開講,隻重點講了兩種新方案,這可能是導緻被噴得厲害的源頭),今天補充說一下。
以user(uid, name, passwd)
擴充到user(uid, name, passwd, age, sex)為例
基本原理是:
(1)先建立一個擴充字段後的新表user_new(uid, name, passwd, age, sex)
(2)在原表user上建立三個觸發器,對原表user進行的所有insert/delete/update操作,都會對新表user_new進行相同的操作
(3)分批将原表user中的資料insert到新表user_new,直至資料遷移完成
(4)删掉觸發器,把原表移走(預設是drop掉)
(5)把新表user_new重命名(rename)成原表user
擴充字段完成。
優點:整個過程不需要鎖表,可以持續對外提供服務
操作過程中需要注意:
(1)變更過程中,最重要的是沖突的處理,一條原則,以觸發器的新資料為準,這就要求被遷移的表必須有主鍵(這個要求基本都滿足)
(2)變更過程中,寫操作需要建立觸發器,是以如果原表已經有很多觸發器,方案就不行(網際網路大資料高并發的線上業務,一般都禁止使用觸發器)
(3)觸發器的建立,會影響原表的性能,是以這個操作建議在流量低峰期進行
pt-online-schema-change是DBA必備的利器,比較成熟,在網際網路公司使用廣泛。
樓主非專業的dba,上面的過程有說的不對的地方,歡迎指出。要了解更詳細的細節,可以百度一下。有更好的方法,也歡迎讨論,後續會梳理彙總share給更多的朋友。
六、結束
歡迎用批判的眼光看問題,歡迎任何友善的技術讨論,不太歡迎“純屬誤導”“非常蠢的方案”這樣的評論(但我還是會加精選,任何人都有發聲的權利)。
借評論中@張九雲 朋友的一句話“不要以為自己見過的就是全世界,任何方案都有使用場景,一切都是tradeoff”作為今天的結尾,謝謝大家的支援,感謝大家。
==【完】==