12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[MySQL]シャーディングしているDBでidを一意に振る

Last updated at Posted at 2016-04-22

データベースを分割(シャーディング)する際に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

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?