天天看點

知識點 | 分庫分表情況下全局唯一主鍵的一種簡單實作

【引言】

大家知道,關系型資料庫易成為系統瓶頸,單機存儲容量、連接配接數、處理能力都有限。當單表的資料量 >1000W行或 >100G後,由于查詢次元較多,即使添加從庫讀、優化索引,優化後性能仍下降嚴重。

此時就要考慮對其進行切分了,目的就在于減少資料庫的負擔,縮短查詢時間。

在分庫分表環境中,由于表中資料同時存在不同資料庫中,單庫主鍵值平時使用的自增長将不再适用,某分區資料庫下自生成的ID無法保證全局唯一。是以需要單獨設計全局主鍵,以避免跨庫主鍵重複問題。

常見的主鍵生成政策有:UUID、建立主鍵ID表、Snowflake分布式自增ID算法。

今天就來講一下最簡單的建立主鍵ID表方法,此方法實作最為簡單。

首先,在一台資料庫中建立 sequence 表:

CREATE TABLE

sequence

(

id

bigint(20) unsigned NOT NULL auto_increment,

stub

char(1) NOT NULL default ‘’,

PRIMARY KEY (

id

),

UNIQUE KEY

stub

(

stub

)

) ENGINE=MyISAM;

stub字段設定為唯一索引,同一stub值在sequence表中隻有一條記錄,可以同時為多張表生成全局ID。

使用 MyISAM 存儲引擎而非 InnoDB,目的是為了擷取更高性能。

MyISAM使用的是表級别的鎖,對表的讀寫是串行的,故不用擔心在并發時兩次讀取同一個ID值。

當需要全局唯一的64位ID時,執行:

mysql> REPLACE INTO sequence (stub) VALUES ('a');
mysql> select * from sequence;
+----+------+
| id | stub |
+----+------+
|  1| a    |
+----+------+
1 row in set (0.00 sec)

           

注意:select last_insert_id() 必須與replace into在同一資料庫連接配接下才能得到剛剛插入的新ID。

使用replace into代替insert into好處是避免了表行數過大,不需要另外定期清理。

此方案優點簡單易實作,缺點也明顯:存在單點問題,強依賴DB。

當DB異常時,整個分布式系統将因取不到最新的序号導緻庫不可用;配置主從可增加可用性,但當主庫挂了,主從切換時,資料一緻性在資料修改較為頻繁的場景下難以保證;且,整體分布式的性能瓶頸也将受限于此産生主鍵ID序列的伺服器讀寫性能上。

歡迎關注個人微信公衆号:

知識點 | 分庫分表情況下全局唯一主鍵的一種簡單實作

繼續閱讀