Funktion in zentraler Datenbank erstellen oder in jeder Datenbank wiederholen?

8

Einer meiner Entwickler hat eine SQL-Funktion geschrieben, die wie die VB.Net-Funktion (LastIndexOf) funktioniert und diese veröffentlichen möchte. Meine Frage ist, was wäre der Grund, dies in eine zentrale Datenbank zu stellen, anstatt es in jede Benutzerdatenbank zu stellen?

Der Entwickler hat versucht, es in das Systemschema seiner Master-Datenbank einzufügen, damit er keine Anrufe aus Benutzerdatenbanken qualifizieren muss ... seufz

Aber ich war mir nicht sicher, was die gültige Entschuldigung wäre, um es (offensichtlich nicht Master-Datenbank) gegenüber jeder Benutzerdatenbank zu zentralisieren?

David George
quelle
1
Ich denke, die Idee dahinter kann so etwas wie "Was würden Sie im Falle eines hypothetischen Bugfixes tun?" Zu jeder einzelnen Datenbank gehen und jede einzelne Kopie separat reparieren? '
Dekso
1
Der Verwaltungsaufwand ist hier irrelevant, da ich alle Datenbanken genauso einfach aktualisieren kann wie eine einzelne Datenbank
David George
Und weiß Ihr Entwickler davon? :) Und wahrscheinlich hat er / sie das Gefühl, dass es eine so grundlegende Funktionalität implementiert, dass es im Kern sein muss.
Dekso
Ja. Das ist meine Frage, sollte etwas, das als Kern betrachtet werden könnte, Teil der Benutzerdatenbank sein oder von allen Datenbanken einer einzigen gemeinsamen Datenbank gemeinsam genutzt werden?
David George
Ja, ich habe versucht, zwei mehr oder weniger gültige Argumente für eine Zentralisierung vorzulegen. Ich denke, es kann eher eine Frage der Politik oder Ihres persönlichen Geschmacks sein - aus dem Wortlaut geht hervor, dass Sie die Idee nicht mögen.
Dekso

Antworten:

12

Die Art und Weise, wie ich dies bevorzuge: Legen Sie die Funktion in eine Dienstprogrammdatenbank und erstellen Sie in jeder regulären Datenbank ein Synonym dafür. Auf diese Weise erhalten Sie das Beste aus beiden Welten:

  1. Es muss nur eine Kopie des Objekts verwaltet werden
  2. Der Entwickler muss keine drei- oder vierteiligen Namen angeben

z.B

USE UtilityDB;
GO
CREATE FUNCTION dbo.LastIndexOf(...) ...
GO
USE otherDB;
GO
CREATE SYNONYM dbo.LastIndexOf FOR UtilityDB.dbo.LastIndexOf;
GO

Dies ist besonders leistungsfähig für CLR-Funktionen, da für das Ändern / Bereitstellen dieser Funktionen zusätzlicher Verwaltungsaufwand anfällt.

Dies ist der Verwendung von Master (und der Markierung als Systemobjekt, von dem nicht garantiert wird, dass es vorwärts portierbar ist) vorzuziehen. Ich würde gerne wissen, wie Ihr Entwickler erwartet, seine Funktion im sysSchema zu erstellen .

Ich verstehe, dass das Verwalten mehrerer Kopien einer Funktion in 500 Datenbanken nicht schwieriger ist als das Verwalten einer einzelnen Kopie, aber das Vorhandensein mehrerer Kopien ist nur dann von Vorteil, wenn Sie Ausnahmen haben (z. B. möchte Client A, dass seine Funktion NULL-Werte unterschiedlich behandelt). oder so). In diesem Fall würde ich das Synonym in allen anderen Datenbanken belassen und eine spezielle Version der Funktion nur in dieser Datenbank einführen.

(Dies setzt natürlich voraus, dass die Funktion nicht auf Datenzugriff in der Datenbank eines Kunden angewiesen ist - was die Sache sicherlich komplizieren kann.)

Aaron Bertrand
quelle
5

Ich werde Aaron (und der akzeptierten Antwort) nicht zustimmen müssen.

Aarons Ansatz ist die Art und Weise, wie ich mit "DBA-Sachen" umgehe, z. B. Wartungsskripten. Ich würde dies niemals mit einer Bibliotheksfunktion tun wollen, die von einer Benutzerdatenbank aufgerufen würde.

Warum? Sie werden auf das Datenbankäquivalent von DLL Hell zusteuern .

Inkompatible Versionen

... Vor Windows 2000 war Windows dafür anfällig, da die COM-Klassentabelle von allen Benutzern und Prozessen gemeinsam genutzt wurde. Es kann nur ein COM-Objekt in einer DLL / EXE mit einer bestimmten globalen COM-Klassen-ID auf einem System deklariert werden. Wenn ein Programm eine Instanz dieser Klasse erstellen musste, erhielt es die aktuell zentral registrierte Implementierung. Infolgedessen kann eine Installation eines Programms, das eine neue Version eines gemeinsamen Objekts installiert, versehentlich andere Programme beschädigen, die zuvor installiert wurden.

Installieren Sie .net 4.5 auf einem Server, auf dem eine .net 2.0-Anwendung ausgeführt wird, und was passiert? Nichts, Ihre Anwendung verwendet weiterhin das 2.0-Framework. Aktualisieren Sie Ihre LastIndexOf-Funktion auf einem Server, auf dem 3 Anwendungsdatenbanken gehostet werden (im Rahmen eines Upgrades auf eine davon). Was passiert? Alle drei verwenden jetzt die neueste Version.

Die Alternative ist der Ansatz von SQL # . Dies wird in einem Schema in jeder Benutzerdatenbank installiert, sodass Sie die Datenbank für Application-X sicher aktualisieren können, ohne die Stabilität von Application-Y zu gefährden.

Wenn Sie in einer streng kontrollierten Änderungsverwaltungsumgebung arbeiten, haben Sie keine andere Wahl. Sie können eine freigegebene Komponente nicht aktualisieren, ohne alle Benutzer der Komponente zu testen. Wenn Sie an einem Ort arbeiten, der etwas "schneller und lockerer" ist, können Sie Ihr Risiko eingehen, indem Sie mit einem Patch / Upgrade ungewollt etwas kaputt machen.

Mark Storey-Smith
quelle
Lassen Sie mich eine Gegenargumentation vorlegen, da Sie anscheinend eine wollten, und jetzt habe ich ein paar Momente Zeit, die ich vorher nicht hatte. :-) (1) Ich nahm an, dass die fraglichen Datenbanken alle miteinander verwandt sind und nicht Teil völlig unterschiedlicher Anwendungen sind. (2) In diesem Fall besteht meines Erachtens keine große Gefahr, dass eine aufgerufene Funktion LastIndexOfgeändert wird, geschweige denn , dass nur einige der Apps / Datenbanken beschädigt werden. Ich würde sagen, es ist ein größeres Problem für CLR oder wirklich zentrale / komplexe Funktionen, die mehrere Apps bedienen. (3) Meine eigentliche Präferenz wäre es, für einfache Aufgaben überhaupt keine Funktion zu verwenden.
Aaron Bertrand
1
Begrüßen Sie natürlich immer Ihre Gedanken :)
Mark Storey-Smith
Sie da. Als Schöpfer von SQL # schätze ich die positive Erwähnung :-). Ich sollte jedoch klarstellen, dass der Hauptentscheidungspunkt für die Verwendung eines separaten Schemas für alle SQL # -Objekte darin bestand, einen Namensraum zu erstellen, damit es nicht zu Namenskonflikten kommt, unabhängig davon, wo SQL # installiert wurde. Sie sprechen jedoch einen Punkt an, der in Bezug auf die Versionierung berücksichtigt werden muss, je nachdem, wie die App strukturiert ist. Persönlich mag ich eine UtilityDatenbank für häufig als Bibliothek bezeichnete Inhalte, aber dies erhöht das Risiko ein wenig und erfordert gründliche Tests.
Solomon Rutzky
0

Die Antwort auf diese Frage hängt davon ab, ob es sich um T-SQL-Objekte oder SQLCLR-Objekte handelt. Beim Umgang mit SQLCLR-Objekten sind verschiedene (und weitere) Faktoren zu berücksichtigen.

In Bezug auf T-SQL-Objekte bringen beide Antworten hier gültige Punkte hervor. Wie in der Antwort von @ Aaron beschrieben , kann die zentrale Datenbank sehr praktisch sein, und Synonyme können verwendet werden, um es einfach zu machen, dass einige Datenbanken auf die gemeinsam genutzte Ressource verweisen und andere eine lokale Ressource verwenden. Der in Marks Antwort angesprochene Punkt bezüglich des erhöhten Risikos aufgrund der stärkeren Abhängigkeit kann jedoch nicht ignoriert werden.

Wenn Sie sich jedoch mit SQLCLR-Objekten befassen, müssen Sie zuerst alle Punkte berücksichtigen, die ich in der folgenden Antwort angesprochen habe:

Wie kann man die CLR-Funktion aus Sicht der Leistung besser nutzen (in jeder Datenbank wiederholen oder allgemeine Funktion haben)?

Solomon Rutzky
quelle