2009-04-09 7 views
522

Что такое синтаксис для указания первичного ключа на более чем 1 столбце в SQLITE?Первичный ключ Sqlite для нескольких столбцов

+9

Это также называется сложным ключом http://en.wikipedia.org/wiki/Compound_key – OneWorld

+1

@OneWorld или составной ключ, если какой-либо из столбцов не является самим ключом. – Michael

ответ

669

Согласно documentation, это

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

Ну, это правильно, но, согласно документации, CREATE TABLE что-то (column1 PRIMARY KEY, column2 PRIMARY KEY); также должно быть возможным, но это не так. – Yar

+4

@Yar В документах сказано: «Если в одном предложении CREATE TABLE есть более одного предложения PRIMARY KEY, это ошибка». Да, железнодорожные диаграммы могут указывать на то, что это действительно так, но текст ниже поясняет, что это не так. –

+3

Не забудьте добавить * ПЕРВИЧНЫЙ КЛЮЧ (column1, column2) * часть в конце, как в этом ответе. Если вы попытаетесь добавить его после определения столбца2, вы получите ** синтаксическую ошибку **. – vovahost

36

Да. Но помните, что такой первичный ключ допускает значения 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 
+0

Есть ли какая-либо ссылка на причину такого поведения? Что было бы хорошим способом сбросить несколько строк в базе данных и все равно удалить дубликаты, даже если они содержат «NULL»? – Pastafarianist

+1

@Pastafarianist http://www.sqlite.org/lang_createtable.html - «Согласно стандарту SQL, PRIMARY KEY всегда должен подразумевать NOT NULL.К сожалению, из-за ошибки в некоторых ранних версиях это не относится к SQLite. [...] Значения NULL считаются отличными от всех других значений, в том числе других NULL. » –

+0

Да, в SQL NULL всегда сравниваются false. Из-за этого реляционная теория специально исключает NULL в качестве значения любого ключевого компонента. Однако SQLite , является реляционной практикой. Кажется, авторы решили прагматически разрешить множественные, но не «равные» ключи. Очевидно, что предпочтительно не допускать NULL как ключевые значения. – holdenweb

144
CREATE TABLE something (
    column1 INTEGER NOT NULL, 
    column2 INTEGER NOT NULL, 
    value, 
    PRIMARY KEY (column1, column2) 
); 
+0

Не использует ли первичный ключ NOT NULL? – pratnala

+18

@pratnala В стандартном SQL , да. В SQLite в первичных ключах разрешен «NULL». В этом ответе подчеркивается, что если вы хотите более стандартного поведения, вам нужно добавить 'NOT NULL' себя. Мой ответ - это просто базовый синтаксис для нескольких столбцов основной ключ. –

13

Первичные ключевые поля должны быть объявлены не нулевой (это не стандарт, как определение первичного ключа заключается в том, что оно должно быть уникальным, а не null). Но ниже - хорошая практика для всех первичных ключей с несколькими столбцами в любой СУБД.

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

Начиная с версии 3.8.2 в SQLite, альтернатива явно не NULL спецификации является "БЕЗ ROWID" Спецификация: [1]

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

"БЕЗ 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

25

Basic:

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 
); 
Смежные вопросы