Ok, scomponiamo:
- Come vengono creati i join tra due tabelle su più database? (Un esempio di codice qui sarebbe utile).
Questo è piuttosto semplice. Gli oggetti SQL hanno ovunque una convenzione di denominazione da una a quattro parti:
Servername.databasename.schemaname.tablename
Se tutte le tue tabelle si trovano sullo stesso server sullo stesso database, con lo stesso proprietario / schema, puoi semplicemente ignorare le prime tre parti e utilizzare ciò a cui sei maggiormente abituato:
Select a.*,b.* from
tableA a inner join
tableB b on a.col1=b.col1
Se una delle tue tabelle si trova in un database diverso ed entrambi utilizzano lo schema predefinito per i loro database, aggiungi semplicemente il database alla seconda tabella:
Select a.*,b.* from
tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Se ti capita di trovarti in un terzo database diverso da uno di quelli che stai interrogando, usi esplicitamente entrambi i nomi di database:
Select a.*,b.* from
databaseD..tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Se finisci per usare schemi e / o proprietari diversi, puoi aggiungerli in:
Select a.*,b.* from
databaseD.john.tableA a inner join
databaseC.accounting.tableB b on a.col1 = b.col1
Infine, se fai molta attenzione e hai un'ottima ragione, puoi unirti a una tabella (di solito piccola) su un altro server:
Select a.* from
databaseD.john.TableA a inner join
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
- Quando è il momento di passare oltre una configurazione di 1 database / 1 server? Quanto è comune fare questo? Esistono strategie speciali per tenere traccia di quali tabelle si trovano in quale database?
Combinerò questi due perché vanno insieme. Stai quasi sempre bene iniziare partendo dal presupposto che un database e un server sono sufficienti fino a quando i tuoi vincoli di progettazione / business / tecnici ti costringono a usarne di più.
Quindi, per rispondere prima alla tua seconda domanda, dal momento che in genere hai un motivo per avere database separati, dovrebbe essere abbastanza ovvio dal conoscere il design del tuo sistema in cui si trova qualcosa.
Per quanto riguarda quando / perché è necessario spostarsi oltre un singolo database. Di solito è un mix di regole aziendali, politica e / o ragioni tecniche.
Ad esempio, dove lavoro, abbiamo 16 database distribuiti su 4 server. Abbiamo un MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB. Per fare alcuni esempi del perché sono diversi:
- FinancialDB, informazioni sensibili
- Image DB, requisiti specifici di archiviazione e ripristino diversi
- Riferimento DB, transazione bassa, lettura alta
- ReportingDB, lettura molto elevata, deve essere ripristinato / replicato in vari altri ambienti a differenza di molti altri dati
- StagingDB, niente di permanente, solo un tempdb potenziato su cui abbiamo più controllo
- MainDB, si interfaccia con tutti gli altri DB ma necessita di backup differenziali quindi ... abbiamo diviso il
- Tabelle HighVolumeTransaction, (che sono relativamente transitorie), al proprio DB in modo da mantenere una dimensione ragionevole del backup.
- Archivio, Molti degli stessi dati da Principale e Rapporti, ma con periodi di conservazione più lunghi e query di risposta più difficili che scavano in profondità nei dati. Se questo fosse ancora combinato con Main / Reporting, il sistema si bloccherebbe.
• Il codice dell'applicazione deve sapere che uno o più database sono distribuiti su più server? In caso contrario, a quale livello vengono filtrate le richieste?
In senso lato, probabilmente lo fanno. Come minimo devono sapere a quale server stanno puntando nella stringa di connessione al database. Elaborazione, reportistica, principale, ecc.
Da lì, hanno bisogno di un contesto di database per eseguire sotto. Generalmente quello sarebbe il più usato per l'applicazione, forse anche quello originale dall'un database / un server giorni dell'applicazione. È possibile che l'applicazione cambi esplicitamente il contesto del database ad ogni chiamata, ma ciò rende molto difficile regolare il database senza modificare l'app.
Il solito approccio (o almeno il MIO solito) è quello di accedere sempre attraverso uno o forse due database principali.
Quindi creare viste in altri database, se necessario, in combinazione con l'interfaccia con il database attraverso procedure memorizzate.
Quindi per illustrare:
Supponiamo che tu voglia ottenere le informazioni demografiche di un cliente, i dati di vendita e il saldo del credito e che si sviluppa su tre tabelle originariamente tutte nel MainDB.
Quindi scrivi una chiamata dalla tua app:
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
Eccezionale. Tuttavia, ora ogni volta che cambiamo un nome di colonna, o rinominiamo / spostiamo una tabella, devi aggiornare il codice dell'app. Quindi invece facciamo due cose:
Creare viste Clienti, Vendite, AccountRicevibili (non useresti Seleziona * ma sto dimostrando qui)
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
Quindi creeremmo anche una procedura memorizzata, spGetClientSalesAR
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
E chiedi alla tua app di chiamarla così.
Ora, purché non modifichi l'interfaccia su quel proc memorizzato, posso praticamente fare tutto ciò che devo fare sul database back-end per ridimensionare o ridurre.
In estrema misura, potrei persino rendere il mio vecchio MainDB solo un mucchio di stored procedure e viste sgusciate tali che sotto quelle viste che abbiamo creato sembravano così:
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
E la tua app non saprebbe mai la differenza (supponendo tra l'altro veloci pipe e dati ben organizzati).
Ovviamente è estremo e mentirei se dicessi che tutto è stato pianificato in questo modo, ma l'uso di procedure / viste memorizzate anche se lo fai mentre il refactoring ti consentirà molta flessibilità man mano che la tua app cresce dal suo umile un database / un server inizio.