複数列のSqlite主キー


回答:


805

ドキュメントによると、それは

CREATE TABLE something (
  column1, 
  column2, 
  column3, 
  PRIMARY KEY (column1, column2)
);

3
まあ、これは正しいですが、ドキュメントによると、CREATE TABLE何か(column1 PRIMARY KEY、column2 PRIMARY KEY); 同様に可能であるはずですが、それは不可能です。
Yar

6
@Yarドキュメントは、「単一のCREATE TABLEステートメントに複数のPRIMARY KEY句がある場合、それはエラーです。」と言います。はい、鉄道図はそれが有効であることを示している可能性がありますが、以下のテキストでは無効であることを明確にしています。
ブライアンキャンベル

10
この回答のように、最後にPRIMARY KEY(column1、column2)の部分を追加することを忘れないでください。column2の定義の後に追加しようとすると、構文エラーが発生します
vovahost 2015

159
CREATE TABLE something (
  column1 INTEGER NOT NULL,
  column2 INTEGER NOT NULL,
  value,
  PRIMARY KEY ( column1, column2)
);

主キーはNOT NULLを課しませんか?
プラトナラ2014年

23
@pratnala標準SQLでは、はい。SQLiteではNULL、主キーで使用できます。この回答は、より標準的な動作が必要な場合は、NOT NULL自分で追加する必要があることを強調しています。私の答えは、複数列の主キーの非常に基本的な構文です。
ブライアンキャンベル

42

はい。ただし、このような主キーではNULL、両方の列の値を複数回使用できることに注意してください。

そのようなテーブルを作成します。

    sqlite> CREATE TABLE something (
column1, column2, value, PRIMARY KEY (column1, column2));

これは警告なしで動作します:

sqlite> insert into something (value) VALUES ('bla-bla');
sqlite> insert into something (value) VALUES ('bla-bla');
sqlite> select * from something;
NULL|NULL|bla-bla
NULL|NULL|bla-bla

そのような行動の理由への言及はありますか?データベースに複数の行をダンプし、重複が含まれている場合でもそれらを削除するための良い方法は何でしょうNULLか?
パスタファリアニスト2015年

4
@Pastafarianist sqlite.org/lang_createtable.html-"SQL標準によると、PRIMARY KEYは常にNOT NULLを意味する必要があります。残念ながら、初期のバージョンのバグのため、SQLiteには当てはまりません。[...] NULL値は、他のNULLを含む他のすべての値とは異なると見なされます。」
驚くべきJan

はい、SQLではNULLは常にfalseと比較されます。このため、リレーショナル理論では、キーコンポーネントの値としてNULLを明確に除外しています。ただし、SQLiteはリレーショナルな手法です。作者は複数の「等しい」キーではなく実際的なキーを許可することを選択したようです。明らかに、キー値としてNULLを許可しないことが望ましいです。
holdenweb

31

基本:

CREATE TABLE table1 (
    columnA INTEGER NOT NULL,
    columnB INTEGER NOT NULL,
    PRIMARY KEY (columnA, columnB)
);

列が他のテーブルの外部キーである場合(一般的なケース):

CREATE TABLE table1 (
    table2_id INTEGER NOT NULL,
    table3_id INTEGER NOT NULL,
    FOREIGN KEY (table2_id) REFERENCES table2(id),
    FOREIGN KEY (table3_id) REFERENCES table3(id),
    PRIMARY KEY (table2_id, table3_id)
);

CREATE TABLE table2 (
    id INTEGER NOT NULL,
    PRIMARY KEY id
);

CREATE TABLE table3 (
    id INTEGER NOT NULL,
    PRIMARY KEY id
);

14

主キーフィールドはnull以外として宣言する必要があります(これは標準ではありません。主キーの定義は一意であり、nullでない必要があるためです)。ただし、以下は、DBMSのすべての複数列の主キーに適した方法です。

create table foo
(
  fooint integer not null
  ,foobar string not null
  ,fooval real
  ,primary key (fooint, foobar)
)
;

11

SQLiteのバージョン3.8.2以降、明示的なNOT NULL指定の代わりに "WITHOUT ROWID"指定があります:[ 1 ]

NOT NULL is enforced on every column of the PRIMARY KEY
in a WITHOUT ROWID table.

「WITHOUT ROWID」テーブルには潜在的な効率上の利点があるため、考慮すべき冗長度の低い代替案は次のとおりです。

CREATE TABLE t (
  c1, 
  c2, 
  c3, 
  PRIMARY KEY (c1, c2)
 ) WITHOUT ROWID;

たとえば、sqlite3プロンプトで: sqlite> insert into t values(1,null,3); Error: NOT NULL constraint failed: t.c2


今日これを読んでいる人にとっては:WITHOUT ROWID追加の影響があるNOT NULLため、主キーの横に書き込む代わりに使用しないでください。
シャドウトーカー


2

PRIMARY KEY (id, name)うまくいきませんでした。代わりに、制約を追加することで処理が行われました。

CREATE TABLE IF NOT EXISTS customer (id INTEGER, name TEXT, user INTEGER, CONSTRAINT PK_CUSTOMER PRIMARY KEY (user, id))


1

次のコードは、SQLiteの主キーとして2列のテーブルを作成します。

解決:

CREATE TABLE IF NOT EXISTS users (id TEXT NOT NULL, name TEXT NOT NULL, pet_name TEXT, PRIMARY KEY (id, name))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.