架構(gòu)師必備:業(yè)務(wù)擴(kuò)展模式選型

業(yè)務(wù)發(fā)展過(guò)程中,增加字段是很常見(jiàn)、頻繁的,因此怎么存儲(chǔ)新增的字段是要重點(diǎn)考慮的因素。下面結(jié)合筆者的經(jīng)驗(yàn),總結(jié)一下各種業(yè)務(wù)擴(kuò)展模式選型的優(yōu)缺點(diǎn)、適用場(chǎng)景,如何讓系統(tǒng)保持良好的業(yè)務(wù)擴(kuò)展性。

方案選項(xiàng)

1. 最樸素方案:MySQL表直接加字段

  • 實(shí)現(xiàn):
    在表中新增字段(ALTER TABLE ... ADD COLUMN ...)。

  • 優(yōu)點(diǎn):

    • 簡(jiǎn)單直接,快速迭代
  • 缺點(diǎn):

    • 需要頻繁修改表結(jié)構(gòu)
    • 字段膨脹導(dǎo)致表臃腫,索引效率下降(mysql單行記錄有大小上限,65535字節(jié);特別地,TEXT、BLOB另外分開(kāi)存儲(chǔ),占9到12字節(jié))
  • 適用場(chǎng)景:

    • 業(yè)務(wù)初期頻繁加字段
    • 或該字段為通用字段,適用于所有記錄

2. 按業(yè)務(wù)領(lǐng)域聚合字段(增量更新)

  • 實(shí)現(xiàn):
    將新增字段按業(yè)務(wù)域劃分,比如業(yè)務(wù)一的信息都放到field_1,業(yè)務(wù)二的信息都放到field_2,每個(gè)字段是json格式、方便后續(xù)擴(kuò)展。

  • 優(yōu)點(diǎn):

    • 業(yè)務(wù)聚合:相同業(yè)務(wù)領(lǐng)域信息存在一個(gè)字段內(nèi),無(wú)需每次DDL新增字段
  • 缺點(diǎn):

    • 每次更新都要先查DB的值,merge本次變更后再寫(xiě)入DB
    • 需做好并發(fā)控制,否則可能丟失變更內(nèi)容(可通過(guò)樂(lè)觀鎖、或悲觀鎖控制,取決于并發(fā)程度)
    • 仍然存在mysql單行大小限制
  • 適用場(chǎng)景:

    • 小型項(xiàng)目,不做推薦

3. 按業(yè)務(wù)領(lǐng)域垂直拆表

  • 實(shí)現(xiàn):
    相近業(yè)務(wù)領(lǐng)域的字段,做垂直分表(如拆為訂單信息表order_info、訂單支付表order_payment、訂單物流表order_logistics)。


    image.png
  • 優(yōu)點(diǎn):

    • 徹底解耦業(yè)務(wù)域,各表獨(dú)立演進(jìn)
    • 按需查表,提升查詢性能
  • 缺點(diǎn):

    • 每個(gè)垂直分表仍是在表內(nèi)新增字段
    • 業(yè)務(wù)擴(kuò)展的難易程度,取決于垂直拆分得是否合理
  • 適用場(chǎng)景:

    • 業(yè)務(wù)模式已經(jīng)穩(wěn)定
    • 或業(yè)務(wù)邊界清晰的項(xiàng)目

4. 主表 + 動(dòng)態(tài)擴(kuò)展表(通過(guò)業(yè)務(wù)ID關(guān)聯(lián))

  • 實(shí)現(xiàn):
    主表:存儲(chǔ)核心字段(如業(yè)務(wù)ID、其它通用關(guān)鍵字段)
    動(dòng)態(tài)擴(kuò)展表:存儲(chǔ)動(dòng)態(tài)擴(kuò)展字段,與主表通過(guò)業(yè)務(wù)id關(guān)聯(lián)。包括擴(kuò)展key、擴(kuò)展value(可以是json格式,方便后續(xù)擴(kuò)展)
    每次新增字段:(1)新增一個(gè)擴(kuò)展key,在擴(kuò)展value里存儲(chǔ)內(nèi)容;(2)或在已有擴(kuò)展key的value中新增字段。


    image.png

之所以通過(guò)動(dòng)態(tài)擴(kuò)展表來(lái)實(shí)現(xiàn),是因?yàn)楹芏嘧侄尾⒎峭ㄓ玫?,而僅針對(duì)部分記錄。

以電子產(chǎn)品為例:
可以有擴(kuò)展字段1(認(rèn)證證書(shū):3C),則擴(kuò)展key為"certification",value是["3C"]
也可以有擴(kuò)展字段2(保修信息:保修期12個(gè)月、可延保、最長(zhǎng)可延保24個(gè)月),則擴(kuò)展key為"warranty",value是{"warrantyMonths": 12, "canExtend": true, "maxWarrantyMonths": 24}
以食品為例:
可以有擴(kuò)展字段1(保質(zhì)期截止時(shí)間:2026-07-07),則擴(kuò)展key為"bestBefore",value是對(duì)應(yīng)時(shí)間戳
也可以有擴(kuò)展字段2(生產(chǎn)地:中國(guó)上海),則擴(kuò)展key為"productionPlace",value是{"country": "CN", "province": "Shanghai"}

表結(jié)構(gòu)設(shè)計(jì):

-- 主表
CREATE TABLE biz_info (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  biz_id BIGINT UNIQUE KEY,  -- 業(yè)務(wù)ID
  ...  -- 其它通用關(guān)鍵字段
);

-- 通用擴(kuò)展表
CREATE TABLE biz_extension (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  biz_id BIGINT,        -- 關(guān)聯(lián)主表的業(yè)務(wù)ID
  extension_key VARCHAR(64), -- 擴(kuò)展key名
  extension_value TEXT,      -- 擴(kuò)展value值
  UNIQUE KEY (biz_id, extension_key) -- 唯一鍵
);
  • 優(yōu)點(diǎn):

    • 動(dòng)態(tài)擴(kuò)展字段,無(wú)需DDL變更
    • 按需查擴(kuò)展key對(duì)應(yīng)的記錄,提升查詢性能
  • 缺點(diǎn):

    • 擴(kuò)展數(shù)據(jù)為字符串存儲(chǔ),需要按業(yè)務(wù)自定義格式解析,無(wú)法直接按條件篩選查詢
  • 適用場(chǎng)景:

    • 應(yīng)當(dāng)優(yōu)先考慮的長(zhǎng)期方案

5. MySQL主表 + HBase業(yè)務(wù)擴(kuò)展表

  • 實(shí)現(xiàn):
    MySQL:存儲(chǔ)核心結(jié)構(gòu)化數(shù)據(jù)(強(qiáng)事務(wù)需求、可指定條件篩選查詢)
    HBase:存儲(chǔ)動(dòng)態(tài)擴(kuò)展字段(稀疏、多列),可以按業(yè)務(wù)領(lǐng)域垂直拆表,因?yàn)樵贖Base表中新增字段的成本很低
    關(guān)聯(lián)方式:用mysql主表業(yè)務(wù)ID,作為HBase rowKey的一部分,通過(guò)業(yè)務(wù)id即可查到HBase中的其它擴(kuò)展信息。
    如果想按條件查詢擴(kuò)展信息,需要把數(shù)據(jù)導(dǎo)入到ES里,通過(guò)ES查詢。


    image.png

HBase表設(shè)計(jì):
如果業(yè)務(wù)id是123456789,則rowKey可設(shè)計(jì)成:{業(yè)務(wù)id后綴}_{業(yè)務(wù)id},如789_123456789;方便將hbase數(shù)據(jù)打散到不同的region,提高存儲(chǔ)和查詢性能。

HBase業(yè)務(wù)擴(kuò)展表1

rowKey 字段1 字段2 字段3
rowKey100 cf1:cert=xxx cf1:warranty=yyy ...

HBase業(yè)務(wù)擴(kuò)展表2

rowKey 字段1 字段2 字段3
rowKey200 cf2:best_before=aaa cf2:prod=bbb ...
  • 優(yōu)點(diǎn):

    • 支持大量列字段,稀疏存儲(chǔ)高效
    • 是“主表 + 擴(kuò)展表”的進(jìn)階版
  • 缺點(diǎn):

    • 擴(kuò)展信息不能方便地按條件查詢,導(dǎo)出至ES后才行
    • 事務(wù)支持弱(跨 MySQL/HBase 無(wú)法保證事務(wù)性,只能做到最終一致性)
    • 復(fù)雜度變高:開(kāi)發(fā)成本、運(yùn)維成本都變高了
  • 適用場(chǎng)景:

    • 數(shù)據(jù)量較大,需拆分一部分?jǐn)U展信息至HBase
    • 或動(dòng)態(tài)擴(kuò)展字段變多,達(dá)到千級(jí)/萬(wàn)級(jí)時(shí)

結(jié)論

  • 適用于所有記錄的字段,在MySQL表中直接新增
  • 初期優(yōu)先選擇“主表 + 動(dòng)態(tài)擴(kuò)展表”模式,平衡靈活性與復(fù)雜度
  • 當(dāng)擴(kuò)展信息數(shù)據(jù)量較大,或動(dòng)態(tài)擴(kuò)展字段達(dá)到千級(jí)/萬(wàn)級(jí)時(shí),考慮升級(jí)到“MySQL主表 + HBase業(yè)務(wù)擴(kuò)展表”模式
  • 若需復(fù)雜查詢,可補(bǔ)充 Elasticsearch 構(gòu)建二級(jí)索引
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容