MyISAMはこの動作をサポートしています。 2列の主キーを作成し、2番目にします 列の自動インクリメント。最初の列の個別の値ごとに最初からやり直します。
CREATE TABLE t (i INT, j INT AUTO_INCREMENT, PRIMARY KEY (i,j)) ENGINE=MyISAM;
INSERT INTO t (i) VALUES (1), (1), (2), (2), (1), (3);
SELECT * FROM t;
+---+---+
| i | j |
+---+---+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
+---+---+
しかし、考えてみれば、これはテーブルレベルのロックを行うストレージエンジンでのみスレッドセーフです。 INSERTステートメントの場合。 INSERTは、テーブル内の他の行を検索して、最大のj
を見つける必要があるためです。 同じi
あたりの値 価値。他の人が同時にINSERTを実行している場合、競合状態が発生します。
したがって、INSERTでテーブルレベルのロックを行うMyISAMへの依存。
マニュアルの次のリファレンスを参照してください: http:// dev.mysql.com/doc/refman/5.6/en/example-auto-increment.html セクションの下にあるMyISAMノート 。
MyISAMを使用しない理由はたくさんあります。私にとって決定的な要因は、MyISAMがデータを破壊する傾向があることです。
コメントを再確認してください:
InnoDBは、上記のグループごとの増分動作をサポートしていません。複数列の主キーを作成できますが、発生したエラーは、自動インクリメント列がテーブルのキーの最初の列である必要があるためです(厳密には主キーである必要はありません)
複数列キーの自動インクリメント列の位置に関係なく、InnoDBで使用した場合にのみインクリメントします。別の列の個別の値ごとにエントリに番号を付けることはありません。
InnoDBテーブルでこれを行うには、競合状態を回避するために、INSERTの間、テーブルを明示的にロックする必要があります。挿入先のグループの最大値に対して独自のSELECTクエリを実行します。次に、その値+1を挿入します。
基本的に、自動インクリメント機能をバイパスして、値を自動的に生成するのではなく指定する必要があります。