データベースを分割(シャーディング)する際にauto_incrementするようにしているとidが重複する問題があります。
例えば、id = 120
まで振られたDBを'id= 60'を境に2つに分割した場合
A | B | |
---|---|---|
現状で一番大きなid | 60 | 120 |
auto_incrementによって付与される次のid | 61 | 121 |
のようにidが振られます。
ここでAがauto_incrementによって61を付与されようとしていますが、これはBが保有する61~120までのidと重複します。
このような場合、auto_incrementを使わずにid用のテーブルを用意する事で重複を回避することが出来ます。
create table seq_log (id bigint(20) unsigned not null)engine=MyISAM;
このようなテーブルを作り、同一のトランザクション内で
update seq_log set id=LAST_INSERT_ID(id+1);
select LAST_INSERT_ID();
を行えば、seq_logが必ず一意なidを返してくれるというわけです。
ここで得られたidを使ってシャーディングしたDBに更新をかければ重複は起こりません。
参考:http://engineer.dena.jp/2010/11/mysql-for-socialgame.html
追記
MyISAMではトランザクションが存在しないので、ロックを使って擬似的にトランザクションを作ってあげる必要がある
俗にこれを採番テーブルという
メリット・デメリットや採番方式、ロールバックに関する問題等下記の記事が詳しそう
参考:http://qiita.com/NAKANO_Akihito/items/44db44375a464c72606a