2011-06-18 9 views
0

そこには次の2つの表は以下のとおりです。MySQL INSERT .. UPDATEはAUTO_INCREMENTを壊しますか?

create table lol(id int auto_increment, data int, primary key id(id)); 
create table lol2(id int auto_increment, data int, primary key id(id)); 

は、いくつかの値を挿入します。

insert into lol2 (data) values (1),(2),(3),(4); 

今selectを使用して挿入します。

insert into lol (data) select data from lol2; 

は再びそれを実行します。

insert into lol (data) select data from lol2; 

を今表を見て:

select * from lol; 

私が受け取る:

+----+------+ 
| id | data | 
+----+------+ 
| 1 | 1 | 
| 2 | 2 | 
| 3 | 3 | 
| 4 | 4 | 
| 8 | 1 | 
| 9 | 2 | 
| 10 | 3 | 
| 11 | 4 | 
+----+------+ 

私はこれを引き起こした何... 4と8の間のギャップによって困惑だとどのように「がそこにISNように私はそれを行うことができますギャップ?どうもありがとう!

+0

「innodb_autoinc_lock_mode」の値は何ですか? – extraneon

+2

テーブルを削除して再度クエリを実行してみてください。これは実行しないでください。私はそれを試してみると、私は1から8のIDを持っています。 1つのクエリが一度失敗し、IDが増分された可能性があります。自動増分は、最大数をとり、1を追加するようなものではなく、メタテーブルに格納されます。だから何かが失敗した場合、自動インクリメントは増分されますが、あなたはレコードを持っていません - あなたはギャップに終わるでしょう。 –

+0

再現できません... –

答えて

0

auto_incrementは、ID列に1ずつ増分することを保証しません。そして、それはできません。なぜなら、並列トランザクションを処理するとすぐに破損するからです。

BEGIN         BEGIN 
    INSERT INTO lol VALUES(...)   INSERT INTO lol VALUES(..) 
    ...         ... 
COMMIT         ROLLBACK 

データベースではどのIDを割り当てる必要がありますか?どのトランザクションが成功するか、どのトランザクションがロールバックされるかは事前に分かりません。

レコードの連続番号が必要な場合は、それを返すクエリを使用します。例えば

SELECT COUNT(*) as position, lol.data FROM lol 
INNER JOIN lol2 ON lol.id < lol2.id 
GROUP BY lol.id 
関連する問題