Wie erzwinge ich ein einmaliges Schreiben und schreibgeschützte Datenbanktabellen in SQL?

28

Ist es überhaupt möglich?

Mein Anwendungsfall ist eine Hauptbuch-Tabelle mit der Anforderung, dass ein einmal erstellter Datensatz schreibgeschützt sein muss, dh, dass niemand in der Lage sein darf, ihn zu bearbeiten oder zu löschen. Dies gilt nur für die Hauptbuch-Tabelle und die Tabellen mit direktem Bezug. Es gibt andere Tabellen im selben Schema, die wie gewohnt aktualisiert / gelöscht werden.

Ich verstehe, dass aus Gründen der Datenintegrität diese Art von Einschränkungen auf die Datenbankebene angewendet werden sollten, aber ich kann keine saubere, allgemein akzeptierte Methode dafür finden - ist dies ein Anwendungsfall, bei dem ich es einfach besser machen würde in der Anwendungsschicht?

Das Ideal wäre eine Möglichkeit, dies in einfachem SQL zu tun, um unabhängig davon zu sein, welche DB-Plattform verwendet wird, da dies möglicherweise geändert werden kann, aber mir ist klar, dass dies zu viel verlangt werden kann, wenn dies der Fall ist Um plattformabhängig zu sein, wird eine Variante von MySQL bevorzugt.

Vielen Dank!

altanqa
quelle

Antworten:

43

Ich sehe mindestens zwei Möglichkeiten, um dies zu erreichen. Der erste Ansatz ist nicht zu gewähren DELETEund UPDATEPrivilegien auf diesen write-once - Tabellen, oder, was das betrifft, werden alle Privilegien außer INSERTund SELECTsomit nur die Benutzer in einfügen oder aus ihnen auswählen.

Eine andere Möglichkeit besteht darin, in diesen Tabellen Auslöser zu definieren BEFORE UPDATEund auszulösen BEFORE DELETEund mit der SIGNALAnweisung eine Ausnahme im Auslöserhauptteil auszulösen, die Aktualisierungen bzw. Löschungen verhindert.

mustaccio
quelle
6
Ich würde beide Optionen empfehlen, da Sie Ihre Absicht klarstellen und mehrere vorsätzliche Maßnahmen ergreifen müssen, um sie zu verletzen
Adam Martin
3
Trigger sind eine bessere Wahl, da sie bei allen Transaktionen ausgelöst werden, auch bei Transaktionen, die von administrativen Benutzern ausgeführt werden, und eine spezifischere Fehlermeldung ausgeben können.
Blrfl
10

Berechtigungen scheinen die naheliegende Wahl zu sein - Sie können jedoch auch die ARCHIVE Storage Engine verwenden . Diese Tabellen-Engine zeichnet große Datenmengen auf, die sich nicht ändern:

Die ARCHIVE-Engine unterstützt INSERT, REPLACE und SELECT, jedoch nicht DELETE oder UPDATE. Es unterstützt ORDER BY-Operationen, BLOB-Spalten und grundsätzlich alle außer räumlichen Datentypen (siehe Abschnitt 11.5.1, „Geodatentypen“). Die ARCHIVE-Engine verwendet Sperren auf Zeilenebene.

Der Unterschied zu Berechtigungen besteht darin, dass ein Benutzer mit erweiterten Berechtigungen weiterhin Daten für die meisten anderen Tabellentypen ändern kann, während ARCHIVE es niemandem erlaubt, Daten zu ändern, die sich bereits in der Tabelle befinden.

Ich habe einen Computer
quelle
1
Ab hier scheint das REPLACEeine Art zu sein UPDATE! "REPLACE funktioniert genauso wie INSERT, außer dass, wenn eine alte Zeile in der Tabelle den gleichen Wert wie eine neue Zeile für einen PRIMARY KEY oder einen UNIQUE - Index hat, die alte Zeile gelöscht wird, bevor die neue Zeile eingefügt wird. Siehe Abschnitt 13.2.5 , "INSERT Syntax". "
Vérace
7

Sehen Sie sich " Point in Time Architecture " oder " Temporal Database Architecture " an.

Datenbankdesign: Ein Zeitpunkt in der Architektur

In den meisten relationalen Datenbankimplementierungen. Aktualisierungs- und Löschbefehle zerstören die Daten, die vor der Ausgabe vorhanden waren. Bei einigen Systemen ist es jedoch erforderlich, dass keine Informationen physisch aus der Datenbank gelöscht oder in der Datenbank aktualisiert werden. In diesem Artikel stellt Arthur Fuller eine Lösung für diese Anforderung in Form einer Point-in-Time-Architektur vor: ein Datenbankdesign, mit dem ein Benutzer ein Abbild der Datenbank, wie es zu einem früheren Zeitpunkt vorhanden war, ohne Zerstörung neu erstellen kann das aktuelle Bild.

Zeitliche Datenbank

In der freien Enzyklopädie
Temporal von Wikipedia werden Daten zu Zeitinstanzen gespeichert. Es bietet zeitliche Datentypen und speichert Informationen zur Vergangenheit, Gegenwart und Zukunft.

Die Grundidee von beiden ist, dass Sie entweder Daten hinzufügen müssen, ohne sie zu löschen, oder Daten so speichern müssen, dass Sie die Daten abrufen können, wie sie aktuell existieren ... oder zu einem früheren Zeitpunkt existierten.

damit verbundene Frage hier: How-to-create-a-Point-in-Time-Architektur-in-mysql ,

WernerCD
quelle