SQL-Spaltendefinition: Standardwert und nicht null redundant?

88

Ich habe oft die folgende Syntax gesehen, die eine Spalte in einer DDL-Anweisung zum Erstellen / Ändern definiert:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"

Die Frage ist: Da ein Standardwert angegeben wird, muss auch angegeben werden, dass die Spalte keine NULL-Werte akzeptieren soll? Mit anderen Worten, macht DEFAULT NOT NULL nicht überflüssig?

Razvan
quelle

Antworten:

133

DEFAULTist der Wert, der eingefügt wird, wenn in einer Einfüge- / Aktualisierungsanweisung kein expliziter Wert vorhanden ist. Nehmen wir an, Ihre DDL hatte nicht die NOT NULLEinschränkung:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT 'MyDefault'

Dann könnten Sie diese Aussagen machen

-- 1. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B) VALUES (NULL, NULL);

-- 2. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, DEFAULT);

-- 3. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) DEFAULT VALUES;

-- 4. This will insert NULL into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, NULL);

Alternativ können Sie auch DEFAULTin UPDATEAussagen, nach dem SQL-1992 - Standard:

-- 5. This will update 'MyDefault' into tbl.col
UPDATE tbl SET col = DEFAULT;

-- 6. This will update NULL into tbl.col
UPDATE tbl SET col = NULL;

Beachten Sie, dass nicht alle Datenbanken alle diese SQL-Standardsyntaxen unterstützen. Das Hinzufügen der NOT NULLEinschränkung führt zu einem Fehler bei Anweisungen 4, 6, solange diese 1-3, 5noch gültig sind. Um Ihre Frage zu beantworten: Nein, sie sind nicht überflüssig.

Lukas Eder
quelle
Ich ging zu Ihrem Link (zu Ihrem Blog-Beitrag) und erwartete eine Erklärung (möglicherweise mit einigen Zahlen) der enormen Auswirkungen auf die Abfrageleistung, sah jedoch nur kurz, dass dies Auswirkungen hat. Nichts für ungut, aber der Link ist etwas irreführend.
Seth Flowers
@ SethFlowers: Danke für den Hinweis, Seth. Der verlinkte Artikel wurde inzwischen bearbeitet. Ich werde sehen, ob ich stattdessen etwas anderes verlinken oder den Link entfernen kann. So wie es jetzt ist, haben Sie absolut Recht, es fügt der Antwort hier keinen Wert hinzu.
Lukas Eder
Danke - ich hoffe ich klang nicht unhöflich. Ich habe gerade den Link gesehen und dachte: "Ja, das ist definitiv etwas, das ich lesen möchte" - dann war es ein wenig enttäuschend :).
Seth Flowers
@ SethFlowers: Keine Sorge. Ich stimme vollkommen zu. Zu meiner Rettung: Meine Blogging-Fähigkeiten haben sich in den letzten Jahren erheblich verbessert :)
Lukas Eder
19

Selbst mit einem Standardwert können Sie die Spaltendaten jederzeit mit überschreiben null.

Mit der NOT NULLEinschränkung können Sie diese Zeile nicht aktualisieren, nachdem sie mit nullWert erstellt wurde

Tamir
quelle
Ich denke, dies sollte umformuliert werden: "Mit der NOT NULL-Einschränkung können Sie diese Zeile nicht aktualisieren, nachdem sie mit dem Nullwert erstellt wurde." Natürlich können Zeilen mit NOT NULL-Spalten aktualisiert werden, sie können nur nicht mit null als aktualisiert werden Wert für diese Spalte. Außerdem: Ich gehe davon aus, dass das Erstellen einer Zeile das Einfügen einer Zeile bedeutet. INSERT-Anweisungen dürfen keine Nullwerte für Spalten haben, die ebenfalls mit NOT NULL angegeben sind.
Makrom
4

Mein SQL-Lehrer sagte, wenn Sie sowohl einen DEFAULTWert als auch NOT NULLoder angeben NULL, DEFAULTsollte dies immer vor NOT NULLoder ausgedrückt werden NULL.

So was:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NULL

Tanguy Labrador Ruiz
quelle
5
Hey, und danke für die Teilnahme. Damit wird die vorliegende Frage jedoch nicht beantwortet, und beide Bestellungen sind vollständig wirksam. Ich finde es einfacher, die Standardeinstellung am Ende zu setzen, wenn ich Tabellen manuell skripte, da dann die Werte NULL und NOT NULL besser ausgerichtet sind.
Emragins
Okay, ich denke du hast auch recht. Ich verstehe nicht, warum mein Kurs explizit sagt, was ich zu meiner Antwort geschrieben habe. Ich weiß, dass meine Antwort die Frage nicht wirklich anspricht, aber ich fand, dass ein Kommentar nicht sehr lesbar wäre.
Tanguy Labrador Ruiz
3
Es gibt einen Unterschied zwischen (subjektiven) Best Practices und Regeln. Es ist keine schlechte Idee, einen konsistenten Stil zu haben, aber in diesem speziellen Fall würde ich persönlich NICHT NULL vor STANDARD bevorzugen. Unabhängig davon können Sie auch Kommentare anstelle von Antworten schreiben, dies wäre angemessener gewesen.
Makrom
Das beantwortet die Frage wahrscheinlich nicht. Aber genau das habe ich gesucht. Vielen Dank.
Sasuke Uchiha
2

Ich würde nicht sagen.

Wenn die Spalte Nullwerte akzeptiert, hindert Sie nichts daran, einen Nullwert in das Feld einzufügen. Soweit mir bekannt ist, gilt der Standardwert nur beim Erstellen einer neuen Zeile.

Wenn nicht null festgelegt ist, können Sie keinen Nullwert in das Feld einfügen, da dies einen Fehler auslöst.

Stellen Sie sich das als einen ausfallsicheren Mechanismus vor, um Nullen zu verhindern.

Dunkles Nilpferd
quelle
2
Sie sagten "Schaffung einer neuen Regel". Wollten Sie "Erstellen einer neuen Zeile" sagen?
Bielawski
Ich denke, das ist eine praktischere Antwort auf diese Frage.
Noman_ibrahim
@bielawski Und fast 8 Jahre später kann ich diesen Tippfehler korrigieren :)
Dark Hippo
Dies sollte die akzeptierte Antwort sein. OP fragt nach einer einfachen Frage und die Antwort lautet einfach "Nein". Für die Dokumentation sind jedoch Erläuterungen und Beispiele erforderlich.
Nicolas Hevia
0

Mit anderen Worten, macht DEFAULT NOT NULL nicht überflüssig?

Nein, es ist nicht redundant. Zur erweiterten akzeptierten Antwort. Für eine Spalte, coldie nullbar ist, kann Ehrfurcht NULL einfügen, selbst wenn DEFAULT definiert ist:

CREATE TABLE t(id INT PRIMARY KEY, col INT DEFAULT 10);

-- we just inserted NULL into column with DEFAULT
INSERT INTO t(id, col) VALUES(1, NULL);

+-----+------+
| ID  | COL  |
+-----+------+
|   1 | null |
+-----+------+

Oracle hat eine zusätzliche Syntax für ein solches Szenario eingeführt, um explizites NULL standardmäßig zu überschreiben DEFAULT ON NULL:

CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10);
-- same as
--CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10 NOT NULL); 

INSERT INTO t2(id, col) VALUES(1, NULL);

+-----+-----+
| ID  | COL |
+-----+-----+
|  1  |  10 |
+-----+-----+

Hier haben wir versucht, NULL einzufügen, aber stattdessen den Standardwert zu erhalten.

db <> Geigen-Demo

ON NULL

Wenn Sie die ON NULL-Klausel angeben, weist Oracle Database den DEFAULT-Spaltenwert zu, wenn eine nachfolgende INSERT-Anweisung versucht, einen Wert zuzuweisen, der NULL ergibt.

Wenn Sie ON NULL angeben, werden die NOT NULL-Einschränkung und der NOT DEFERRABLE-Einschränkungsstatus implizit angegeben.

Lukasz Szozda
quelle