web-dev-qa-db-ja.com

MySQL 5の複数列の主キー

キーの使用方法を学び、すべてのテーブルのすべての行にSERIALタイプのIDを必ず持つ習慣を破ろうとしています。同時に、多対多のリレーションシップも実行しているため、リレーションシップを調整するテーブルのいずれかの列に一意の値を要求すると、それが妨げられます。

すべての列にわたる値の組み合わせが正確に繰り返されない限り、任意の値を任意の列で繰り返すことができるように、テーブルに主キーを定義するにはどうすればよいですか?

24
Kaji

CREATE TABLE構文 ページから引用:

PRIMARY KEYは、複数列のインデックスにすることができます。ただし、列指定でPRIMARY KEYキー属性を使用して複数列のインデックスを作成することはできません。これにより、その単一の列のみがプライマリとしてマークされます。別のPRIMARY KEY(index_col_name、...)句を使用する必要があります。

このようなものは、複数列の主キーに使用できます。

CREATE TABLE
    product (
        category INT NOT NULL,
        id INT NOT NULL,
        price DECIMAL,
        PRIMARY KEY(category, id)
    );

From 13.1.20.6 FOREIGN KEY制約

51
Adriaan Stander

主キーは、類似のエンティティー間でエンティティーを一意に(必要かつ十分に)識別するドメインの概念です。複合(複数列)主キーは、キーの一部が別のドメインエンティティの特定のインスタンスを参照する場合にのみ意味があります。

あなたが本の個人的なコレクションを持っているとしましょう。あなたが一人でいる限り、それらを数え、それぞれに番号を割り当てることができます。番号は、ライブラリのドメインの主キーです。

次に、ライブラリを隣人のライブラリとマージし、それでも本が誰のものかを区別できるようにしたいとします。ドメインはより広くなり、主キーは(owner、book_id)になりました。

したがって、各主キーコンポジットを作成することは戦略ではなく、必要に応じて使用する必要があります。

MySQLに関するいくつかの事実。複合主キーを定義し、RDBSMにIDを自動インクリメントさせたい場合は、MyISAMとInnoDBの動作の違いについて知っておく必要があります。

Parent_id、child_idという2つのフィールドを持つテーブルが必要だとします。そして、child_idが自動インクリメントされるようにします。

MyISAMは、同じparent_idを持つレコード内で一意に自動インクリメントし、InnoDBはテーブル全体で一意に自動インクリメントします。

MyISAMでは、主キーを(parent_id、child_id)として定義し、InnoDBでは(child_id、parent_id)として定義する必要があります。これは、自動インクリメントフィールドがInnoDBの主キーの左端の構成要素であるためです。

22
newtover

主キーは、行の一意の値です。価格、変化する可能性のある値を含めることは意味がありません。広範囲の価格を変更する必要がある場合、それらのすべての主キー値が変更されることを想像してください。なんてめちゃくちゃなんだろう!

1
Perry