【引言】
大家知道,關系型資料庫易成為系統瓶頸,單機存儲容量、連接配接數、處理能力都有限。當單表的資料量 >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序列的伺服器讀寫性能上。
歡迎關注個人微信公衆号: