分庫主鍵設計-Mysql

常見的兩種方案,遍及網絡:

第一種:
replace方案,mysql解釋:REPLACE的運行與INSERT很相像。只有一點除外,若是表中的一箇舊記錄與一個用於PRIMARY KEY或一個UNIQUE索引的新記錄具備相同的值,則在新記錄被插入以前,舊記錄被刪除。html

CREATE TABLE `user_id_seq` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `stub` varchar(3) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `stub` (`stub`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

REPLACE INTO user_id_seq(stub) VALUES ('a');
select last_insert_id();


這種方案通常一個表對應一個類型的主鍵,簡單明瞭,一個表對應一個業務的seq。可是在高併發的狀況下很容易致使mysql死鎖。

第二種:java

CREATE TABLE `sequence` (
  `name` varchar(50) NOT NULL,
  `id` bigint(20) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

INSERT INTO `sequence` (`name`) VALUES('users');
update sequence set id=last_insert_id(id+1) where name = 'users'; 
select last_insert_id();


這種方案能夠一個表支持多個業務的seq需求,可是太多的業務對這一個表頻繁操做,若是某個業務出現鎖表,就會致使其餘業務沒法進行。mysql

 

第三種:spring

若是是java的項目,可使用spring框架的MySQLMaxValueIncrementer解決,在mysql上實現原理同第二種,只是在業務層加了一段本地緩存,對於seq請求很高的業務能夠較好的保障。

以上三種方案的都關係到mysql的last_insert_id()這個功能,其實關鍵點也就是這個last_insert_id()使咱們能夠經過mysql實現惟一seq的設計。
mysql中對它的解釋:【對於LAST_INSERT_ID(),最近生成的ID是在服務器上按鏈接維護的。它不會被另外一個客戶端改變。即便用non-magic值(即非Null非0值)更新了另外一個AUTO_INCREMENT列,也不會更改它。】

mysql如何得到上次插入行的惟一ID
http://dev.mysql.com/doc/refman/5.1/zh/apis.html#getting-unique-id

這樣無論咱們如何設計,只要保證select last_insert_id();以前的操做是一個鏈接完成的原子操做,咱們就能從返回值中獲得惟一的last_insert_id。sql

相關文章
相關標籤/搜索