1. 程式人生 > >MySQL分庫分表面試知識總結

MySQL分庫分表面試知識總結

場景分析

  • Web開發工作,亦或是海量資料開發工作,學習分庫、分表、分割槽等知識都是很有必要的 。
  • 面試的時候,也有可能也會被問到。不過作為一個有經驗的Coder,不熟悉分庫、分表技術確實有些 low。

基礎概念

  • 分表,能夠解決單表資料量過大帶來的查詢效率下降的問題;
  • 分庫,面對高併發的讀寫訪問,當資料庫master伺服器無法承載寫操作壓力時,不管如何擴充套件slave伺服器,此時都沒有意義。此時,則需要通過資料分庫策略,提高資料庫併發訪問能力。
  • 優點,分庫、分表技術優化了資料儲存方式,有效減小資料庫伺服器的負擔、縮短查詢響應時間。

  • 資料分庫、分表儲存場景條件

    • 關係型資料庫
    • 主從架構(master-slave)
    • 單表資料量在百萬、千萬級別
    • 資料庫面臨極高的併發訪問
  • 分庫、分表實現策略

    • 關鍵字取模,實現對資料訪問進行路由。

分庫

  • 舉例
    • 按功能分
      • 使用者類庫、商品類庫、訂單類庫、日誌類庫等
    • 按地區分
      • 每個城市或省市一個同樣的庫,如: db_click_bj、db_click_sh 等

橫向/水平分表: 解決 表記錄太大問題

  • 主要解決問題

    • 單表過大造成的效能問題;
    • 單表過大造成的單伺服器空間問題。
  • 按某個欄位分

    • 如:將使用者資料附件表分成3個附件分表pre_forum_attachment_[0|1|2],和1個附件索引表(儲存tid和附件id關係),根據tid最後一位判斷附件儲存在哪個分表中。
  • 按日期分表
    • 日誌類、統計類資料表按年、月、日、周分表。如:點選量統計click_201801、click_201802
  • 通過MySQL的merge儲存引擎實現
    • 需要建立分表、總表,總表需要merge儲存引擎。
      • 示例程式碼
create table log_merge (
dt datetime not null,
info varchar (100) not null,
  index (dt)
) engine = merge
union= (log_2017,log_2018) insert_method = last;

縱向/垂直分表 : 解決 列過多問題

  • 縱向分表常見的方式有根據活躍度分表、根據重要性分表等。
  • 主要解決問題

    • 表與表之間資源爭用問題;
    • 鎖爭用機率小;
    • 實現核心與非核心的分級儲存,如UDB登陸庫拆分成一級二級三級庫;
    • 資料庫同步壓力問題。
  • 具體策略

    • 經常組合查詢的列放在一個表,常用欄位的表可考慮Memory引擎。
    • 不經常使用的欄位單獨成表。
    • 把text、blob等大欄位拆分放在附表。如:把使用者文章表分成主表news和從表news_data,主表存標題、關鍵字、瀏覽量等,從表存具體內容、模板等。

分庫、分表注意事項

  • 維度問題
    • 針對使用者購買記錄資料,如果按照使用者緯度分表,則每個使用者的交易記錄都儲存在同一表中,所以很快很方便的查詢到某使用者的購買情況,但是某商品被購買的情況則可能分佈在多張表中,查詢起來比較麻煩。
    • 若按照商品維度分表,方便查詢商品購買情況,但查找個人交易記錄比較麻煩。
    • 常見解決方案:
      • 通過掃表方式解決,效率太低,不可行。
      • 記錄兩份資料,一份按照使用者緯度分表,一份按照商品維度分表。
      • 通過搜尋引擎解決,但如果實時性要求很高,則牽涉到實時搜尋問題。
  • 避免分表join操作。關聯的表有可能不在同一資料庫中。
  • 避免跨庫事務
    • 避免在一個事務中修改db0、db1中的表,不僅操作複雜,而且影響效率。
  • 分表宜多不宜少;避免後期可能二次拆分。
  • 儘量同組資料統一DB伺服器。例如將賣家a的商品和交易資訊都放到db0中,當db1掛了的時候,賣家a相關的東西可以正常使用。即避免多個數據庫中的資料產生依賴。

References