Normalerweise entwerfe ich meine Datenbanken nach den folgenden Regeln:
- Niemand anderes als db_owner und sysadmin hat Zugriff auf die Datenbanktabellen.
- Benutzerrollen werden auf Anwendungsebene gesteuert. Normalerweise verwende ich eine Datenbankrolle, um Zugriff auf die Ansichten, gespeicherten Prozeduren und Funktionen zu gewähren, aber in einigen Fällen füge ich eine zweite Regel hinzu, um einige gespeicherte Prozeduren zu schützen.
- Ich benutze TRIGGERS, um wichtige Informationen zunächst zu validieren.
CREATE TRIGGER <TriggerName>
ON <MyTable>
[BEFORE | AFTER] INSERT
AS
IF EXISTS (SELECT 1
FROM inserted
WHERE Field1 <> <some_initial_value>
OR Field2 <> <other_initial_value>)
BEGIN
UPDATE MyTable
SET Field1 = <some_initial_value>,
Field2 = <other_initial_value>
...
END
- DML wird mit gespeicherten Prozeduren ausgeführt:
sp_MyTable_Insert(@Field1, @Field2, @Field3, ...);
sp_MyTable_Delete(@Key1, @Key2, ...);
sp_MyTable_Update(@Key1, @Key2, @Field3, ...);
Denken Sie, dass es sich in diesem Szenario lohnt, DEFAULT CONSTRAINTs zu verwenden, oder füge ich dem DB-Server einen zusätzlichen und unnötigen Job hinzu?
Aktualisieren
Ich verstehe, dass ich durch die Verwendung der DEFAULT-Einschränkung einer anderen Person, die die Datenbank verwalten muss, mehr Informationen übergebe. Aber ich interessiere mich hauptsächlich für Leistung.
Ich gehe davon aus, dass die Datenbank immer Standardwerte überprüft, auch wenn ich den korrekten Wert eingebe. Daher mache ich den gleichen Job zweimal.
Gibt es beispielsweise eine Möglichkeit, die Einschränkung DEFAULT innerhalb einer Triggerausführung zu vermeiden?
sql-server
undtsql
da der Code in Ihrer Frage sehr spezifisch für dieses DBMS istAntworten:
Warum würden Sie das annehmen? ;-). Da Standardwerte vorhanden sind, um einen Wert bereitzustellen, wenn die Spalte, an die sie angehängt sind, nicht in der
INSERT
Anweisung vorhanden ist, würde ich das genaue Gegenteil annehmen: Sie werden vollständig ignoriert, wenn die zugehörige Spalte in derINSERT
Anweisung vorhanden ist.Glücklicherweise muss keiner von uns aufgrund dieser Aussage in der Frage etwas annehmen:
Fragen zur Leistung sind fast immer überprüfbar. Wir müssen also nur einen Test ausarbeiten, damit SQL Server (die wahre Autorität hier) diese Frage beantworten kann.
INSTALLIEREN
Führen Sie einmal Folgendes aus:
Führen Sie die Tests 1A und 1B einzeln aus, nicht zusammen, da dies das Timing verzerrt. Führen Sie die einzelnen Schritte mehrmals aus, um einen Überblick über das durchschnittliche Timing der einzelnen Schritte zu erhalten.
Test 1A
Test 1B
Führen Sie die Tests 2A und 2B einzeln aus, nicht zusammen, da dies das Timing verzerrt. Führen Sie die einzelnen Schritte mehrmals aus, um einen Überblick über das durchschnittliche Timing der einzelnen Schritte zu erhalten.
Test 2A
Test 2B
Sie sollten feststellen, dass zwischen den Tests 1A und 1B oder zwischen den Tests 2A und 2B kein wirklicher Zeitunterschied besteht. Also, nein, es gibt keine Leistungseinbußen, die
DEFAULT
definiert, aber nicht verwendet werden.Neben der bloßen Dokumentation des beabsichtigten Verhaltens müssen Sie auch berücksichtigen, dass es hauptsächlich Sie selbst ist, der sich darum kümmert, dass die DML-Anweisungen vollständig in Ihren gespeicherten Prozeduren enthalten sind. Support-Leute interessieren sich nicht. Zukünftige Entwickler sind sich möglicherweise nicht bewusst, dass Sie den Wunsch haben, alle DML-Dateien in diese gespeicherten Prozeduren einzuschließen, oder kümmern sich selbst dann darum, wenn sie es wissen. Und wer diese Datenbank verwaltet, nachdem Sie gegangen sind (entweder ein anderes Projekt oder eine andere Stelle), ist möglicherweise egal oder kann die Verwendung eines ORM nicht verhindern, egal wie sehr sie protestieren. Defaults können also dabei helfen, dass die Leute ein "out" bekommen, wenn sie eine
INSERT
, insbesondere eine Ad-hoc-INSERT
Aktion eines Support-Mitarbeiters durchführen, da dies eine Spalte ist, die sie nicht einschließen müssen (weshalb ich beim Audit immer Defaults verwende Datumsspalten).UND, mir ist gerade eingefallen, dass ziemlich objektiv gezeigt werden kann, ob ein
DEFAULT
Häkchen gesetzt ist oder nicht , wenn die zugehörige Spalte in derINSERT
Anweisung vorhanden ist: Geben Sie einfach einen ungültigen Wert an. Der folgende Test macht genau das:Wie Sie sehen,
DEFAULT
wird der Standardwert zu 100% ignoriert , wenn eine Spalte (und kein Schlüsselwort ) angegeben wird. Wir wissen das, weil dasINSERT
gelingt. Wenn jedoch die Standardeinstellung verwendet wird, liegt ein Fehler vor, während diese endgültig ausgeführt wird.Während das Vermeiden von Standardeinschränkungen (zumindest in diesem Zusammenhang) völlig unnötig ist, kann der Vollständigkeit halber angemerkt werden, dass es nur möglich wäre, eine Standardeinschränkung innerhalb eines
INSTEAD OF
Auslösers, jedoch nicht innerhalb einesAFTER
Auslösers, zu "vermeiden" . In der Dokumentation zu CREATE TRIGGER heißt es :Natürlich
INSTEAD OF
würde die Verwendung eines Triggers Folgendes erfordern:AFTER
Triggers, der die Einschränkung aktiviertDies würde ich jedoch nicht unbedingt empfehlen.
quelle
CURRENT_TIMESTAMP
von datetime-Spalten. Daher funktioniert der "einfache" Test der Verwendung eines ungültigen Ausdrucks dort nicht (und ein ungültiger Wert kann nicht verwendet werden,CREATE TABLE
da er validiert wurde), und ich habe keine Zeit, den Leistungstest zu erstellen. Ich vermute jedoch, dass die meisten RDBMS sie auf die gleiche Weise behandeln würden.Ich sehe keinen nennenswerten Schaden, wenn ich Standardbedingungen habe. In der Tat sehe ich einen besonderen Vorteil: Sie haben den Standard auf derselben Logikebene wie die Tabellendefinition selbst definiert. Wenn Sie in Ihrer gespeicherten Prozedur einen Standardwert angeben, muss jemand dorthin gehen, um herauszufinden, wie hoch der Standardwert ist. und das ist nicht unbedingt etwas, das für jemanden, der neu im System ist, offensichtlich ist (wenn Sie zum Beispiel morgen eine Milliarde Dollar erben, Ihre eigene tropische Insel kaufen und dort aufhören und umziehen und einen anderen armen Saft zurücklassen, um die Dinge herauszufinden) auf eigene Faust).
quelle