Ok, lass es uns zusammenfassen:
- Wie werden Joins zwischen zwei Tabellen in mehreren Datenbanken erstellt? (Ein Codebeispiel hier wäre hilfreich).
Das ist ziemlich einfach. SQL-Objekte haben eine ein- bis vierteilige Namenskonvention:
Servername.datendatenname.schemaname.tabellenname
Wenn sich alle Ihre Tabellen auf demselben Server in derselben Datenbank mit demselben Eigentümer / Schema befinden, können Sie die ersten drei Teile einfach ignorieren und das verwenden, was Sie am häufigsten gewohnt sind:
Select a.*,b.* from
tableA a inner join
tableB b on a.col1=b.col1
Wenn sich eine Ihrer Tabellen in einer anderen Datenbank befindet und beide das Standardschema für ihre Datenbanken verwenden, fügen Sie die Datenbank einfach der zweiten Tabelle hinzu:
Select a.*,b.* from
tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Wenn Sie sich in einer dritten Datenbank befinden, die sich von der abgefragten unterscheidet, verwenden Sie beide Datenbanknamen explizit:
Select a.*,b.* from
databaseD..tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Wenn Sie unterschiedliche Schemata und / oder Eigentümer verwenden, können Sie diese hinzufügen in:
Select a.*,b.* from
databaseD.john.tableA a inner join
databaseC.accounting.tableB b on a.col1 = b.col1
Und zu guter Letzt können Sie, wenn Sie sehr vorsichtig sind und einen guten Grund haben, einer (normalerweise kleinen) Tabelle auf einem anderen Server beitreten:
Select a.* from
databaseD.john.TableA a inner join
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
- Wann ist es an der Zeit, über ein 1-Datenbank / 1-Server-Setup hinauszugehen? Wie häufig muss das gemacht werden? Gibt es spezielle Strategien, um zu verfolgen, welche Tabellen sich in welcher Datenbank befinden?
Ich werde diese beiden kombinieren, weil sie zusammenpassen. Es ist fast immer in Ordnung, mit der Annahme zu beginnen, dass eine Datenbank und ein Server ausreichen, bis Sie aufgrund Ihrer gestalterischen, geschäftlichen und technischen Einschränkungen gezwungen sind, mehr zu verwenden.
Zur Beantwortung Ihrer zweiten Frage sollten Sie also zunächst wissen, wo sich etwas befindet, da Sie im Allgemeinen einen Grund dafür haben, separate Datenbanken zu haben.
Wann und warum es notwendig ist, über eine einzelne Datenbank hinauszugehen. Normalerweise ist es eine Mischung aus Geschäftsregeln, politischen und / oder technischen Gründen.
Zum Beispiel, wo ich arbeite, haben wir 16 Datenbanken, die auf 4 Server verteilt sind. Wir haben eine MainDB, eine ImageDB, eine referencetableDB, eine HighvolumeTransactionDB, eine ReportingDB, eine StagingDB, eine ProcessingDB, eine ArchiveDB, eine FinancialDB. Um einige Beispiele zu nennen, warum sie unterschiedlich sind:
- FinancialDB, sensible Informationen
- Image-DB, spezifische unterschiedliche Speicher- und Wiederherstellungsanforderungen
- ReferenceDB, niedrige Transaktion, hohes Lesevermögen
- ReportingDB, sehr häufig gelesen, muss im Gegensatz zu vielen anderen Daten in verschiedenen anderen Umgebungen wiederhergestellt / repliziert werden
- StagingDB, nichts Dauerhaftes, nur eine aufgepeppte Tempdb, über die wir mehr Kontrolle haben
- MainDB, ist mit allen anderen DBs kompatibel, benötigt jedoch differenzielle Sicherungen, sodass ... wir die Datenbank aufteilen
- HighVolumeTransaction-Tabellen (die relativ kurzlebig sind) in ihre eigene Datenbank, um die Sicherungsgröße angemessen zu halten.
- Archivieren, Viele der gleichen Daten aus Haupt- und Berichterstellung, jedoch mit längeren Aufbewahrungsfristen und schwierigeren Abfragen, die tief in den Daten verankert sind. Wäre dies noch mit Main / Reporting kombiniert, würde dies unser System zum Erliegen bringen.
• Muss der Anwendungscode wissen, dass eine oder mehrere Datenbanken auf mehrere Server verteilt sind? Wenn nicht, auf welcher Ebene werden die Anforderungen gefiltert?
Im weitesten Sinne tun sie es wahrscheinlich. Sie müssen mindestens wissen, auf welchen Server sie in der Datenbankverbindungszeichenfolge verweisen. Verarbeitung, Berichterstattung, Main, etc.
Von dort aus benötigen sie einen Datenbankkontext, unter dem sie ausgeführt werden können. Im Allgemeinen ist dies die am häufigsten verwendete Version für die Anwendung, möglicherweise sogar die ursprüngliche Version aus einer Datenbank / einem Servertag der Anwendung. Sie können festlegen, dass die Anwendung den Datenbankkontext bei jedem Aufruf explizit wechselt. Dies macht es jedoch sehr schwierig, die Datenbank anzupassen, ohne die App zu ändern.
Der übliche (oder zumindest MEINE übliche) Ansatz besteht darin, immer über eine oder vielleicht zwei Hauptdatenbanken zuzugreifen.
Erstellen Sie dann nach Bedarf Ansichten in anderen Datenbanken und stellen Sie eine Verbindung mit der Datenbank über gespeicherte Prozeduren her.
Um dies zu veranschaulichen:
Angenommen, Sie möchten die demografischen Informationen, Verkaufsdaten und das Guthaben eines Kunden abrufen, die ursprünglich alle in der MainDB auf drei Tabellen verteilt waren.
So schreiben Sie einen Anruf von Ihrer App aus:
Select c.ClientName, c.ClientAddress, s.totalSales,f.CreditBlance from
Clients c join Sales s on c.clientid = s.clientid inner join AccountReceivable f on
c.clientid=f.clientid where c.clientid = @clientid
Genial. Jetzt müssen Sie den App-Code jedoch jedes Mal aktualisieren, wenn wir einen Spaltennamen ändern oder eine Tabelle umbenennen / verschieben. Also machen wir stattdessen zwei Dinge:
Kunden erstellen, Verkauf, AccountReceivables Views (Sie würden nicht Select * verwenden, aber ich probiere es hier aus)
Use MainDB
GO
Create view v_Clients as select * from Clients
Create view v_Sales as select * from Sales
Create view v_AccountReceivable as select * from AccountReceivable
Go
Dann würden wir auch eine gespeicherte Prozedur, spGetClientSalesAR, erstellen
Create proc spGetClientSalesAR @clientID int
as
Select c.ClientName as ClientName,
c.ClientAddress as ClientAddress,
s.totalSales as TotalSales,
f.CreditBlance as CreditBalance
from
v_Clients c join v_Sales s
on c.clientid = s.clientid
inner join v_AccountReceivable f
on c.clientid=f.clientid
where c.clientid = @clientid
Und lassen Sie Ihre App das nennen.
Solange ich die Oberfläche dieses gespeicherten Prozesses nicht ändere, kann ich so ziemlich alles tun, was ich tun muss, um die Back-End-Datenbank zu vergrößern oder zu verkleinern.
Im Extremfall könnte ich meine alte MainDB sogar zu einer Reihe von gespeicherten Prozeduren und Ansichten mit Shell machen, so dass unter den von uns erstellten Ansichten Folgendes aussieht:
Create view v_Clients as select * from ServerX.DatabaseY.dbo.Clients
Create view v_Sales as select * from ServerQ.DatabaseP.dbo.Sales
Create view v_AccountReceivable as select * from ServerJ.DatabaseK.dbo.AccountReceivable
Und Ihre App würde niemals den Unterschied erkennen (unter der Voraussetzung, dass schnelle Pipes und gut bereitgestellte Daten vorhanden sind).
Das ist natürlich extrem und ich würde lügen, wenn ich sagen würde, dass alles so geplant ist. Die Verwendung gespeicherter Prozeduren / Ansichten, auch wenn Sie dies während des Refactorings tun, ermöglicht Ihnen viel Flexibilität, da Ihre App von einer einfachen Datenbank auf einen Server erweitert wird Anfang.