9

ich ein CMS-System, das Datum über Tabellen wie folgt speichert:Beibehalten der Seitenänderungshistorie. Ein bisschen wie SO tut für Revisionen

Entries Table 
+----+-------+------+--------+--------+ 
| id | title | text | index1 | index2 | 
+----+-------+------+--------+--------+ 

Entries META Table 
+----+----------+-------+-------+ 
| id | entry_id | value | param | 
+----+----------+-------+-------+ 

Files Table 
+----+----------+----------+ 
| id | entry_id | filename | 
+----+----------+----------+ 

Entries-to-Tags Table 
+----+----------+--------+ 
| id | entry_id | tag_id | 
+----+----------+--------+ 

Tags Table 
+----+-----+ 
| id | tag | 
+----+-----+ 

Ich bin bei dem Versuch, ein Revisionssystem zu implementieren, wie ein bisschen SO hat. Wenn ich es nur für die Entries Table tat, plante ich, nur eine Kopie aller Änderungen an dieser Tabelle in einer separaten Tabelle zu behalten. Da ich es für mindestens 4 Tabellen tun muss (die TAGS-Tabelle muss keine Revisionen haben), scheint dies überhaupt keine elegante Lösung zu sein.

Wie würdest du es tun?

Bitte beachten Sie, dass die Meta Tabellen in EAV (entity-attribute-value) modelliert.

Vielen Dank im Voraus.

Antwort

8

Hallo arbeite derzeit an der Lösung zu ähnlichen Problem, ich lösen es durch Aufspalten meiner Tabellen in zwei, eine Steuertabelle und eine Datentabelle. Die Steuertabelle enthält einen Primärschlüssel und eine Referenz in die Datentabelle. Die Datentabelle enthält den Revisionsschlüssel für die automatische Erhöhung und den Primärschlüssel der Steuertabelle als Fremdschlüssel.

Ihre Eingaben Tabelle als Beispiel

Entries Table 
+----+-------+------+--------+--------+ 
| id | title | text | index1 | index2 | 
+----+-------+------+--------+--------+ 

wird

entries    entries_data 
+----+----------+ +----------+----+--------+------+--------+--------+ 
| id | revision | | revision | id | title | text | index1 | index2 | 
+----+----------+ +----------+----+--------+------+--------+--------+ 

select * from entries join entries_data on entries.revision = entries_data.revision; 

anstelle der Aktualisierung der entries_data Tabelle liefert eine Insert-Anweisung zum Abfragen und aktualisieren Sie dann die Tabelle der Eintragstabelle mit der neuen Revision der Eintragstabelle.

Der Vorteil dieses Systems besteht darin, dass Sie zu verschiedenen Revisionen wechseln können, indem Sie einfach die Revisionseigenschaft in der Tabelle der Einträge ändern. Der Nachteil ist, dass Sie Ihre Abfragen aktualisieren müssen. Ich bin derzeit dabei, dies in eine ORM-Ebene zu integrieren, so dass die Entwickler sich keine Sorgen darüber machen müssen, SQL trotzdem zu schreiben. Eine andere Idee, mit der ich mich beschäftige, ist, dass es eine zentralisierte Revisionstabelle gibt, die alle Datentabellen verwenden. Dies würde es Ihnen ermöglichen, den Status der Datenbank mit einer einzelnen Revisionsnummer zu beschreiben, ähnlich wie die Subversion-Revisionsnummern funktionieren.

+0

Warum hat jemand ejrowleys Antwort abgelehnt? Ich suche immer noch nach der bestmöglichen Lösung und werde Kredit geben, wo Kredit fällig ist. Aber das scheint wie eine brauchbare Lösung, oder? – Frankie

+0

obwohl Ihr System nicht genau das ist, wofür ich hingehe; Ich glaube, dass das 'Media Wiki'-Tabellenschema in Edward Williams eine engere Antwort in Bezug auf Leistung und Verfügbarkeit ist; Ich glaube, du bist Antwort in der Zeile von Edwards Antwort mit besseren Schaltpläne, also akzeptiere ich es. Vielen Dank! – Frankie

6

Haben Sie einen Blick auf diese Frage: How to version control a record in a database

Warum nicht einen separaten history_table für jede Tabelle haben (gemäß der akzeptierte Antwort auf die Frage verbunden sind)? Das hat einfach einen zusammengesetzten Primärschlüssel der PK der ursprünglichen Tabellen und der Revisionsnummer. Sie müssen die Daten trotzdem irgendwo speichern.

+0

Ihre Antwort ist sehr interessant. Speziell 'Media Wiki' Datenbankschema. Es erzeugt eine zusätzliche Ebene 'Tabelle -> Revisionsschlüssel -> Revisionsdaten', wobei die' Datentabelle' so klein wie möglich gehalten wird, während ein Revisionsverlauf bereitgestellt wird und in der Lage ist, zwischen Revisionen hin und her zu navigieren, wie SO. Ich frage mich immer noch, ob es eine * elegante * Möglichkeit gibt, es zu speichern. – Frankie

1

Für einen unserer Projekte gingen wir die folgende Art und Weise:

Entries Table 
+----+-----------+---------+ 
| id | date_from | date_to | 
+----+--------_--+---------+ 

EntryProperties Table 
+----------+-----------+-------+------+--------+--------+ 
| entry_id | date_from | title | text | index1 | index2 | 
+----------+-----------+-------+------+--------+--------+ 

ziemlich kompliziert, noch den Überblick über vollständigen Objektlebenszyklus zu halten erlaubt. Also für aktive Einheiten abfragt wir wollten:

SELECT 
entry_id, title, text, index1, index2 
FROM 
Entities INNER JOIN EntityProperties 
ON Entities.id = EntityProperties.entity_id 
AND Entities.date_to IS NULL 
AND EntityProperties.date_to IS NULL 

Die einzige Sorge für eine Situation war mit Einheit entfernt werden (so setzen wir eine DATE_TO dort) und dann von admin wiederhergestellt.Mit dem gegebenen Schema gibt es keine Möglichkeit solche Tricks zu verfolgen.

Insgesamt ist der Nachteil eines solchen Versuches offensichtlich - Sie müssen Tonnen von TSQL schreiben, wo nicht-versionierte DBs für etwas wie gehen, wählen Sie A beitreten B.