InnoDBテーブルの複数列インデックスのAUTO_INCREMENT列のサポートがないことは、広く知られている制限であり、必要な場合のトリガーの回避策と同様です(例 this post を参照)。昨日、しかし、私は this thread に出くわし、この機能のサポートが5.1から追加されたと主張しました。私の5.7インストール(mysql-community-server-5.7.19-1.el7.x86_64)で次のステートメントを試したところ、問題なく動作するようです。
CREATE TABLE `tbl1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`data` datetime NOT NULL,
PRIMARY KEY (`id`,`data`)
) ENGINE=InnoDB;
私の問題は、私の人生において、MySQLのドキュメントサイトやその他の場所で、この機能のサポートについて肯定的な声明を見つけることができないことです。私は発表されていない何か(実験的に存在する可能性があります)を本番環境にデプロイすることに少し警戒しているので、誰かが私にこれの公式ステータスを指摘してくれることを願っています。
編集:マニュアルには、無関係な部分が含まれていることがわかります これはやや斜めのステートメント :
「…AUTO_INCREMENTカラムを持つInnoDBテーブルには、自動インクリメントカラムが唯一の、または左端のカラムである場合、少なくとも1つのキーが必要です。」
これはサポートを示唆していますが、述べていません。
編集2:以下の@rolandoMYSQLDBAからの情報を使用して、 this additional snippet : "も検索しました" AUTO_INCREMENTカラムは、InnoDBテーブルのインデックスの最初のカラムとして表示される必要があります。 "。したがって、私は彼の答えを受け入れています。
そして、誰かが不思議に思っている場合、複数の列のインデックスがテーブルのパーティション分割に必要です-顧客はすべてのテーブルにauto_increment PKを持っており、日付列でパーティション分割したいと考えています。
通常の状況では、この質問は重複して閉じていました。すでに近い投票があります。この特定の例では、あなたがこの質問に賞金を投じたので、私はできる限りそれに答えようとします。
あなたが言及した最初の投稿 を見てください。テーブルの定義に注意してください
CREATE TABLE `issue_log` (
`sr_no` INT NOT NULL AUTO_INCREMENT ,
`app_id` INT NOT NULL ,
`test_id` INT NOT NULL ,
`issue_name` VARCHAR(255) NOT NULL ,
primary key (app_id, test_id,sr_no)
);
Auto_increment列はsr_no
です。これは、主キー定義の唯一の列でも左端の列でもありません。今、主キーが書き込まれた場合
primary key (sr_no, app_id, test_id)
その場合、sr_no
が左端になります。 InnoDBでエラーは発生しませんでした。
コマンドを実行したとき
CREATE TABLE `tbl1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`data` datetime NOT NULL,
PRIMARY KEY (`id`,`data`)
) ENGINE=InnoDB;
auto_increment列id
が左端にありました。
2番目の投稿への参照 を作成しました。 2番目の投稿への回答では、MyISAMおよびBDBストレージエンジンがauto_increment IDをサポートしていることを明確に示していることに注意してください。 MyISAMに関しては、auto_incrementの動作により、auto_incrementの数値を1つ以上のキーと組み合わせて、数値1が複数回出現しても、列に一意に関連付けられるようにすることができます。私は長年にわたってこれを数回議論しました:
Apr 21, 2012
: 1つのテーブルに2つの自動インクリメント列を含めるにはどうすればよいですか?Jun 10, 2012
: MySQLは自動インクリメントなしで次の一意の値を取得するFeb 26, 2013
: MySQL phpmyadminで2つの自動インクリメント列を使用する方法Aug 28, 2013
: 関係の主要なオブジェクトをモデル化する方法?InnoDBによるPRIMARY KEY
のauto_incrementカラムのサポートは存在しますが、MyISAMと同じauto_incrementの動作はありません。 MyISAMは他の列とバインドして、数値を複数回存在させることができますが、InnoDBはそれを行いません。 auto_increment値を使用すると、テーブル全体で一意になります。
あなたが見つけた抜粋
aUTO_INCREMENTカラムを持つInnoDBテーブルには、自動インクリメントカラムが唯一の、または左端のカラムである場合、少なくとも1つのキーが必要です。
レプリケーションがauto_increment値をどのように認識して処理するかに関係するMySQLドキュメントのページ から来ています。マスターに書き込まれた注文データがスレーブで異なる順序でシリアル化される可能性があるため、これは重要な問題です。
ちょうど最近(Jun 16, 2017
に戻って)私は答えました 主キーの後に追加の列を含むインデックスを作成することは理にかなっていますか? 、MySQLドキュメントから、パーティション分割テーブルのauto_increment列。列がテーブル行のシャーディングを定義する列とともにPRIMARY KEY
に含まれていることが必須です。
結論を言えば、InnoDBのPRIMARY KEY
でのauto_incrementカラムのサポートには、MyISAMの場合のような付加的な利点や追加機能はありません。そのため、MySQLのドキュメントには多くの記述がありません。
これのサポートはずっと前に述べられました。 MySQL 5.1 Documentation on InnoDB Restrictions
を見ると、箇条書き#15が表示されます
AUTO_INCREMENTカラムの場合、常にテーブルのインデックスを定義する必要があり、そのインデックスにはAUTO_INCREMENTカラムのみが含まれている必要があります。 MyISAMテーブルでは、AUTO_INCREMENT列は複数列インデックスの一部である可能性があります。
MySQL 5.1ドキュメンテーション AUTO_INCREMENT InnoDBでの処理 には、より広範なものが含まれています。 MySQL 5.5ドキュメントで利用可能 でもあります。残念ながら、これらは古いドキュメント形式です。これがおそらく今何も見つからない理由です。サポートがあることを確認してください。
InnoDBへの変換 は問題をカバーします:
MyISAMの「機能」をシミュレートする方法は次のようになります。必要なのはこれですが、テーブルを2回参照しているため機能しません。
INSERT INTO foo
(other, id, ...)
VALUES
(123, (SELECT MAX(id)+1 FROM foo WHERE other = 123), ...);
代わりに、これにいくつかのバリアントが必要です。 (すでにBEGIN ... COMMITがあるかもしれません。)
BEGIN;
SELECT @id := IFNULL(MAX(id),0) + 1 FROM foo WHERE other = 123 FOR UPDATE;
INSERT INTO foo
(other, id, ...)
VALUES
(123, @id, ...);
COMMIT;
別のスレッドが同じIDを取得するのを防ぐために、トランザクションを持つことは必須です。