Ich entwickle eine Anwendung, die eine Datenbank (PostgreSQL, MySQL, Oracle oder MSSQL) auf dem Kundensystem verwendet.Sql-Änderungen an Kundendatenbanken implementieren (geänderte Tabellen, Funktionen, ...)
Daher muss ich Datenbankaktualisierungen mit jeder neuen Version durchführen.
Ich bin gerade in der Konzeptphase und habe nichts in Produktion.
Alle DDL-Anweisungen sind in Skriptdateien.
Die Struktur sieht wie folgt aus:
tables\employees.sql
customers.sql
orders.sql
Diese Skripte sind auch in Versionskontrolle und verwendet werden können, um die Datenbank von Strecke zu bauen.
Natürlich wird es irgendwann in der Zukunft Änderungen an diesen Tabellen geben.
Zum Beispiel Tabelle Mitarbeiter wie folgt erstellt werden:
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName text,
PRIMARY KEY (EmployeeId)
);
Und in einer zukünftigen Version die Tabelle erweitert wird:
ALTER TABLE employees ADD COLUMN address varchar(30);
Auf meinen Recherchen fand ich dieses Beispiel: https://stackoverflow.com/posts/115422/revisions. Eine Versionsnummer wird verwendet, um bestimmte Änderungen durchzuführen.
Ich mag dieses Konzept und meine Idee ist, etwas ähnliches zu implementieren. Aber statt einer Systemversionsnummer habe ich darüber nachgedacht, für jede Tabelle eine Version einzuführen.
Wenn die Mitarbeiter zu schaffen Tabelle es die Versionsnummer 1. Bei jeder Änderung von 1 auf dieser Tabelle Nach dem Hinzufügen der Adresse der Versionsnummer Spalte (alte Aussage oben) von der Tabelle erhöht wird Version 2 sein würde, . gerollt würde die Transaktion zurück
BEGIN TRANSACTION;
UPDATE employees SET Version = 2;
ALTER TABLE employees
ALTER TABLE employees ADD COLUMN address varchar(30);
END TRANSACTION;
Wenn die Tabelle Version niedriger ist als die aktuelle Tabelle Version:
Jede Tabelle ändernin einer verschachtelten Transaktion wie dies geschehen würde. Die Implementierung dieser Logik ist noch nicht abgeschlossen.
Der Vorteil wäre, dass alle Änderungen an einer Tabelle innerhalb der Skriptdatei der Tabelle selbst sind und die ursprüngliche Anweisung immer aktuell ist.
Zum Beispiel, wenn zuerst die Mitarbeiter Tabelle erstellt es würde wie folgt aussehen:
Mitarbeiter.sql
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName text,
Version int default 1 not null,
PRIMARY KEY (EmployeeId)
);
Nach einigen Veränderungen, die sie wie folgt aussieht:
employees.sql
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName varchar(100),
address varchar(80),
Version int default 3 not null, -- notice the 3
PRIMARY KEY (EmployeeId)
);
-- First Change
BEGIN TRANSACTION;
UPDATE employees SET Version = 2;
ALTER TABLE employees
ALTER TABLE employees ADD COLUMN address varchar(30);
END TRANSACTION;
-- Second Change
BEGIN TRANSACTION;
UPDATE employees SET Version = 3;
ALTER TABLE employees
ALTER COLUMN address TYPE varchar(80),
ALTER COLUMN FirstName TYPE varchar(100);
END TRANSACTION;
Ist das Konzept akzeptabel oder bin ich das Rad neu zu erfinden hier?
In MySQL jeder DDL-Befehl bewirkt, dass ein implizites Commit DDL-Änderungen können daher nicht rückgängig gemacht werden. Ich weiß nicht, wie es bei anderen dbs aussieht. – Shadow
Sie haben recht, https://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis – Tommy
Sie sind auf dem richtigen Weg, aber Sie Es fehlen einige Dinge. (Zum einen die Möglichkeit, dass Änderungen in der falschen Reihenfolge angewendet werden.) Web-Frameworks wie Ruby auf Rails verwalten diese Art von Dingen durch * Migrationen *. Forschung darüber, wie sie das tun, würde Ihnen viel Zeit sparen. –