2016-04-06 25 views
-1

問題が発生しました。 InnoDBのMySql auto_incrementの値が正しくない

CREATE TABLE UserAccount ( 
    UserID INT NOT NULL AUTO_INCREMENT, 
    Email CHAR(32) NOT NULL UNIQUE, 
    Password CHAR(32) NOT NULL, 
    Status TINYINT DEFAULT 0, 

    PRIMARY KEY(UserID) 
); 

を使用して

は、挿入データを試してみてください。 [email protected]UserIDが1と test2gmail.comのUserIDが4である

INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 

、ない2

私は結果がソリューション何2. ありたいですか?

+0

UserAccount VALUES(4、 '[email protected]、3341234、0)に置き換えます。 – num8er

+0

特定の数値を使用する場合は、「NULL」を使用するのではなくSQL問合せに入力する必要があります。 –

+2

auto_incrementはそのようには機能しません。それは連続した数字を保証するものではありません。 – Argeman

答えて

0

挿入クエリでは、IGNOREを使用すると、重複レコードを挿入しないことを意味します。 あなたが同じユーザーID AUTO_INCREMENT数の増加を挿入し、別のユーザーIDが入って来たときに、それがインクリメントAUTO_INCREMENTの値を挿入するたびに(あなたのケースのように4)

INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected], 3341234, 0); -- auto_increment = 1 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected], 3341234, 0); -- auto_increment = 2 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected], 3341234, 0); -- auto_increment = 3 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected], 3341234, 0); -- auto_increment = 4 

Link

3

問題

デフォルトinnodb_autoinc_lock_modeは "1"です。つまり、InnoDBは、挿入する行の数を事前に決定できない場合(例えば、INSERT ... SELECTクエリの場合)、INSERT文の最後までテーブルの自動インクリメント列をロックするだけです。クエリのようなシンプルなINSERTの場合は、事前に自動インクリメントIDを割り当ててからすぐにテーブルに他の挿入を許可し、より速い書き込みを実現します。

一般的に、これはIDが連続していることを意味しますが、INSERT IGNOREを使用すると、これは単純な挿入であるため、IDが割り当てられ、その行が重複しているために実際には使用されません。

ロックモード

を変えるあなたは絶対に行ごとに、連続した識別子を持たなければならない場合は、あなたがあなたのmy.cnfに次の行を追加し、MySQLサーバを再起動することによって、InnoDBの自動インクリメントロックモードを変更することができます。

innodb_autoinc_lock_mode = 0 

さらに詳しい情報はmanualです。この変更後も、IDを生成するトランザクションがロールバックされた場合、または後で行が削除された場合にシーケンスにギャップが存在する可能性がありますが、生成されたIDは期待どおり "1"および "2"です。あなたはmy.cnfを編集することはできませんまたはロールバック後のギャップが問題である場合と同じ効果に

をシミュレートするためのトリガを使用し

、あなたの代わりに主キーを更新するためのトリガーを書くことができます。次のようなものはOKです。挿入ごとに警告( "Column 'UserID'はnullにはできません)が生成されますが、連続するIDで正常に挿入されます。残念ながら、最も高いIDを持つユーザーを削除すると、次のユーザーは同じIDを再度取得しますが、シーケンスの途中でユーザーを削除すると、自動インクリメントのようにギャップが生じます。

DROP TABLE UserAccount; 

CREATE TABLE UserAccount ( 
    UserID INT NOT NULL, 
    Email CHAR(32) NOT NULL UNIQUE, 
    Password CHAR(32) NOT NULL, 
    Status TINYINT DEFAULT 0, 
    PRIMARY KEY(UserID) 
); 

CREATE TRIGGER UserAccount_before_insert BEFORE INSERT ON UserAccount 
FOR EACH ROW SET NEW.UserId = (
    SELECT COALESCE(MAX(UserId), 0) + 1 FROM UserAccount); 

INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 
INSERT IGNORE INTO UserAccount VALUES (NULL, '[email protected]', 3341234, 0); 

複数の接続から同時に多くの挿入を行った場合、このトリガーがどのように機能するかは完全にはわかりません。それが問題であれば、さらに研究をする必要があるかもしれません。

関連する問題