Constraints: Regeln für die Daten
Kurz gesagt: Constraints (NOT NULL, DEFAULT, UNIQUE, CHECK, PRIMARY KEY) sind Regeln im CREATE TABLE, mit denen die Datenbank selbst falsche Zeilen ablehnt.
Problem
Eine Tabelle, die alles nimmt
Hier ist eine Tabelle für die Lieferanten ganz ohne Regeln. Führ die Abfrage aus:
Ein Lieferant ohne Namen ist hineingekommen. Dieselbe Umsatzsteuernummer kam zweimal hinein. Eine Bewertung von 7 auf einer Skala von 1 bis 5 kam hinein. Niemand hat geprüft.
Im Modul über das Ändern von Daten hat der Shop solche Zeilen mit Fehlern abgewiesen. Diese Fehler kommen von Regeln, die in CREATE TABLE stehen. Jetzt schreibst du sie.
Die Idee
NOT NULL und DEFAULT
Die Regeln stehen hinter dem Typ der Spalte. Sie heißen Constraints (Einschränkungen).
NOT NULL: Die Spalte darf nicht leer sein.DEFAULT Wert: Was gespeichert wird, wenn derINSERTkeinen Wert angibt.
Die Molkerei hat „Sofia“ bekommen, weil ihre Stadt nicht angegeben war. Ein Lieferant ohne Namen kommt nicht hinein:
DEFAULT CURRENT_DATE speichert das heutige Datum. Das ist praktisch für „wann es hinzugefügt wurde“:
1 heißt „ja, es ist das heutige Datum“. Ersetze added_at = CURRENT_DATE durch added_at allein, und du siehst das Datum selbst.
Genauer, für Neugierige
CURRENT_DATE ist in SQLite das Datum in UTC, nicht in Ortszeit. In Bulgarien ist zwischen Mitternacht und 2 oder 3 Uhr morgens das Ortsdatum schon das neue, während UTC noch das alte hat. CURRENT_TIMESTAMP liefert Datum und Uhrzeit, ebenfalls in UTC.
Probier es aus
Die Pflichtfelder
Die Tabelle deliveries hat id, supplier_id, amount und status. Mach den Lieferanten und den Betrag zu Pflichtfeldern, und den Status zum Pflichtfeld mit dem Standardwert 'expected'.
Lösung
CREATE TABLE deliveries (
id INTEGER PRIMARY KEY,
supplier_id INTEGER NOT NULL,
amount REAL NOT NULL,
status TEXT NOT NULL DEFAULT 'expected'
);supplier_id INTEGER NOT NULL, amount REAL NOT NULL, status TEXT NOT NULL DEFAULT 'expected'. Eine neue Lieferung lässt sich ohne Status speichern: Sie ist „expected“, bis sie ankommt.
Die Idee
UNIQUE
UNIQUE verbietet zwei gleiche Werte in der Spalte. Eine Firma hat eine Umsatzsteuernummer:
Manchmal ist es das Paar, das eindeutig ist. Jeder Lieferant nennt einen Preis für ein Produkt. Zwei Lieferanten dürfen dasselbe Produkt anbieten, und ein Lieferant bietet viele Produkte an. Die Regel wird getrennt nach den Spalten geschrieben, mit beiden Spalten in Klammern:
Die ersten drei Zeilen gehen hinein. Die vierte ist ein zweiter Preis von Lieferant 1 für Produkt 1.
Genauer, für Neugierige
UNIQUE erlaubt viele NULL: Zwei Lieferanten ohne Umsatzsteuernummer zählen nicht als gleich, weil NULL nicht gleich NULL ist. Wenn die Umsatzsteuernummer Pflicht ist, schreib vat TEXT NOT NULL UNIQUE. PostgreSQL arbeitet genauso. SQL Server lässt in eine UNIQUE-Spalte standardmäßig nur ein NULL.
Die Idee
CHECK
CHECK (Bedingung) lässt die Zeile nur hinein, wenn die Bedingung wahr ist. Die Bedingung ist wie die in WHERE:
Wenn die Bedingung mehrere Spalten betrifft, steht CHECK nach den Spalten. Eine Aktion darf nicht enden, bevor sie beginnt:
Die Meldung von SQLite sagt, welche Bedingung verletzt wurde. Halte die Bedingungen also kurz und klar.
Sieh es dir an
CHECK lässt NULL durch
Die Bewertung geht von 1 bis 5. Und wenn sie nicht angegeben ist?
Sie ist hineingekommen. CHECK weist die Zeile nur ab, wenn die Bedingung falsch ist. NULL BETWEEN 1 AND 5 ist „unbekannt“, wie jeder Vergleich mit NULL. Das ist das Gegenteil von WHERE, das nur behält, was wahr ist.
Hier ist das richtig: Ein neuer Lieferant hat noch keine Bewertung. Aber wenn der Wert Pflicht ist, reicht CHECK nicht. Du brauchst zusätzlich NOT NULL.
Probier es aus
Die Preise der Lieferanten
Die Tabelle supplier_prices hat supplier_id, product_id und price. Der Preis ist Pflicht und größer als 0, und jeder Lieferant hat für ein bestimmtes Produkt nur einen Preis. Ergänze die Regeln.
Lösung
CREATE TABLE supplier_prices (
supplier_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
price REAL NOT NULL CHECK (price > 0),
UNIQUE (supplier_id, product_id)
);price REAL NOT NULL CHECK (price > 0) und in einer eigenen Zeile UNIQUE (supplier_id, product_id). Ohne NOT NULL käme ein Preis NULL an CHECK vorbei.
Die Idee
PRIMARY KEY
Den Primärschlüssel kennst du schon: die Spalte, an der man eine Zeile erkennt. In CREATE TABLE ist er ein Constraint wie die anderen. Er lässt keine zwei Zeilen mit demselben Schlüssel hinein:
Hat der Schlüssel zwei Spalten, wird er getrennt geschrieben, wie UNIQUE. So ist es in order_items: Ein Produkt steht einmal in einer Bestellung, und die Menge steht in quantity.
order_items
- PK
order_idinteger→ orders - PK
product_idinteger→ products quantityinteger *unit_pricereal *
Genauer, für Neugierige
SQLite hat eine alte Eigenheit: Ein Primärschlüssel, der nicht INTEGER PRIMARY KEY ist, akzeptiert NULL. Führ es aus:
Zwei Gutscheine ohne Code. Das ist ein Fehler aus den frühen Versionen, der geblieben ist, damit alte Programme nicht kaputtgehen. In einer STRICT-Tabelle nimmt der Primärschlüssel kein NULL. Überall sonst schreib code TEXT NOT NULL PRIMARY KEY. In PostgreSQL und MySQL ist der Primärschlüssel immer NOT NULL.
Übung
Die Lieferanten, richtig gemacht
Lege die endgültige Tabelle suppliers an: id (Primärschlüssel), name (Pflicht), vat (Umsatzsteuernummer, Pflicht und ohne Wiederholungen), city (Pflicht, mit dem Standardwert 'Sofia') und rating (eine ganze Zahl von 1 bis 5, darf fehlen). Die Prüfung versucht auch, schlechte Lieferanten hinzuzufügen.
Lösung
CREATE TABLE suppliers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
vat TEXT NOT NULL UNIQUE,
city TEXT NOT NULL DEFAULT 'Sofia',
rating INTEGER CHECK (rating BETWEEN 1 AND 5)
);name TEXT NOT NULL, vat TEXT NOT NULL UNIQUE, city TEXT NOT NULL DEFAULT 'Sofia' und rating INTEGER CHECK (rating BETWEEN 1 AND 5).
Die Prüfung versucht, sieben Lieferanten hinzuzufügen. Nur die zwei richtigen dürfen hineinkommen. Die wiederholte Umsatzsteuernummer, der Lieferant ohne Namen, der ohne Umsatzsteuernummer, der ohne Stadt und die Bewertung von 7 bleiben draußen.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Datumsfunktionen · Primärschlüssel und Fremdschlüssel · INSERT: Zeilen einfügen · CREATE TABLE: eine Tabelle anlegen
- Geht weiter in: Fremdschlüssel: Verbindungen zwischen Tabellen · ALTER TABLE: eine Tabelle ändern · Beziehungstypen: 1:1, 1:N, M:N · ER-Diagramm: von der Beschreibung zum Schema
- Aufgaben zum Thema: Tabellen und Regeln