2009-04-09 15 views

Antwort

669

Nach dem documentation, es ist

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

Nun, das ist richtig, aber nach der Dokumentation CREATE TABLE etwas (Spalte1 PRIMARY KEY, column2 PRIMARY KEY); sollte auch möglich sein, aber es ist nicht möglich. – Yar

+4

@Yar Die Dokumente sagen "Wenn es mehr als eine PRIMARY KEY-Klausel in einer einzelnen CREATE TABLE-Anweisung gibt, handelt es sich um einen Fehler." Ja, die Eisenbahndiagramme zeigen möglicherweise an, dass das auch zutrifft, aber der folgende Text verdeutlicht, dass dies nicht der Fall ist. –

+3

Denken Sie daran, den Teil * PRIMARY KEY (column1, column2) * am Ende wie in dieser Antwort hinzuzufügen. Wenn Sie versuchen, es nach der column2-Definition hinzuzufügen, erhalten Sie einen Syntaxfehler **. – vovahost

36

Ja. Aber denken Sie daran, dass solche Primärschlüssel Werte in beiden Spalten mehrmals zulassen.

eine Tabelle als solche erstellen:

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

Jetzt funktioniert dies ohne Vorwarnung:

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

Gibt es einen Hinweis auf den Grund eines solchen Verhaltens? Was wäre eine gute Möglichkeit, mehrere Zeilen in der Datenbank abzulegen und trotzdem Duplikate zu entfernen, selbst wenn sie 'NULL' enthalten? – Pastafarianist

+1

@Pastafarianist http://www.sqlite.org/lang_createtable.html - "Nach dem SQL-Standard sollte PRIMARY KEY immer NOT NULL beinhalten.Leider ist dies in SQLite aufgrund eines Fehlers in einigen früheren Versionen nicht der Fall. [...] NULL-Werte werden von allen anderen Werten, einschließlich anderer NULL-Werte, unterschieden. " –

+0

Ja, in SQL-NULL-Werten wird immer false verglichen. Aus diesem Grund schließt die relationale Theorie NULL ausdrücklich als Wert einer Schlüsselkomponente aus Es scheint, dass die Autoren pragmatisch die mehrfache, aber nicht "gleiche" Schlüsseln zulassen. Es ist klar, dass NULLs nicht als Schlüsselwerte erlaubt sind. – holdenweb

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

Bedeutet Primärschlüssel keinen NOT NULL? – pratnala

+18

@pratnala In Standard-SQL Ja, in SQLite ist 'NULL' in Primärschlüsseln erlaubt Diese Antwort betont, dass, wenn Sie mehr Standardverhalten wollen, müssen Sie das' NOT NULL' selbst hinzufügen. Meine Antwort ist nur die sehr einfache Syntax für eine Mehrspalte Primärschlüssel. –

13

Primärschlüsselfelder als nicht für nichtig erklärt werden sollte (dies nicht Standard, wie das ist Definition eines Primärschlüssels ist, dass es eindeutig sein muss und nicht null). Aber unten ist eine gute Praxis für alle mehrspaltigen Primärschlüssel in jedem DBMS.

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

Seit Version 3.8.2 von SQLite, eine Alternative zu den expliziten NOT NULL-Spezifikationen ist die "OHNE ROWID" Spezifikation: [1]

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

"OHNE ROWID" Tabellen mögliche Effizienzvorteile haben, so eine weniger ausführliche alternative zu betrachten ist:

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

beispielsweise an der sqlite3 Prompt: 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) 
); 

Wenn Ihre Spalten Fremdschlüssel der anderen Tabellen (allgemeiner Fall) sind:

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 
);