Änderungen an der Datenbank
als Präsentation ▻Der erste Entwurf der Datenbank ist wahrscheinlich nicht der letzte. Während der Entwicklung werden neue Anforderungen an die Datenbank klar, und die Datenbank soll verändert werden.
Ein Beispiel: Zwischen Tabelle zimmerbuchung und zimmer besteht ein foreign key constraint:
Sql Code ein foreign key constraint
\d zimmerbuchung Table "public.zimmerbuchung" Column | Type | Collation | Nullable | Default ------------+---------+-----------+----------+--------- zinr | integer | | | buchungsnr | integer | | | Foreign-key constraints: "zimmerbuchung_buchungsnr_fkey" FOREIGN KEY (buchungsnr) REFERENCES buchung(buchungsnr) "zimmerbuchung_zinr_fkey" FOREIGN KEY (zinr) REFERENCES zimmer(zinr)
Diesem Constraint fehlt das Attribut on delete cascade
. Wie kann man
das im Nachhinein ändern?
Wir könnten die betroffenen Tabellen mit DROP TABLE
löschen
und neu anlegen. Das funktioniert, solange noch keine wichtigen
Daten in den Tabellen sind.
Ist das Projekt aber einmal in Betrieb, dann ist diese Methode nicht mehr möglich. Unsere ersten Kunden finden es sicher nicht gut wenn ihre Daten gelöscht werden.
Wir können die Datenbank also nicht löschen und neu aufbauen, sondern müssen sie ändern.
▻Zum Ändern des Datenbank-Schemas gibt es verschieden Befehle die meist mit ALTER
beginnen, z.B: ALTER TABLE
oder
ALTER TABLE distributors ADD COLUMN address varchar(30); ALTER TABLE distributors DROP COLUMN address RESTRICT; ALTER TABLE distributors ALTER COLUMN address TYPE varchar(80), ALTER COLUMN name TYPE varchar(100); ALTER TABLE distributors RENAME COLUMN address TO city; ...
Constraint entfernen und neu setzen
Mit diesen Befehlen können wir das alte Constraint entfernen, und dann neu setzen:
ALTER TABLE zimmerbuchung DROP CONSTRAINT zimmerbuchung_zinr_fkey; ALTER TABLE zimmerbuchung add CONSTRAINT zimmerbuchung_zinr_fkey FOREIGN KEY (zinr) REFERENCES zimmer(zinr) ON DELETE CASCADE;
Leider gibt es nicht für Alles ein einfaches ALTER
statement.
Wenn man eine Tabelle mit einem PRIMARY KEY
als INTEGER
angelegt hat
und im Nachhinein ein SERIAL
daraus machen will ist das sehr viel Arbeit:
-- CREATE TABLE gast (kunr INTEGER PRIMARY KEY, CREATE SEQUENCE gast_kunr_seq OWNED BY gast.kunr; SELECT setval('gast_kunr_seq', coalesce(max(kunr), 1)) FROM gast; ALTER TABLE gast ALTER COLUMN kunr SET DEFAULT nextval('gast_kunr_seq');
Migrations
So ein kleiner Änderungs-Schritt in der Datenbank wird auch Migration genannt. Wir müssen sicherstellen, dass die Migration sowohl auf dem Entwicklungsrechner als auch auf dem Production-Server durchgeführt wird. Migrations sind genau so wichtig wie der Programmcode, und sollten auch im Versionskontrollsystem erfasst werden.
Bei Migrations ist die Reihenfolge wichtig. Wir könnten sie also der Reihe nach in einer Daten speichern, oder einzelne Dateien anlegen deren Reihenfolge aus dem Dateinamen erkennbar ist, z.B:
migration-1-add-description.sql migration-2-foreigen-key-zimmerbuchung.sql migration-3....