Ok, décomposons-le:
- Comment les jointures sont-elles construites entre deux tables sur plusieurs bases de données? (Un exemple de code ici serait utile).
C'est assez simple. Les objets SQL ont une convention de dénomination d'une à quatre parties:
Servername.databasename.schemaname.tablename
Si toutes vos tables sont sur le même serveur sur la même base de données, avec le même propriétaire / schéma, vous pouvez simplement ignorer les trois premières parties et utiliser ce à quoi vous êtes le plus habitué:
Select a.*,b.* from
tableA a inner join
tableB b on a.col1=b.col1
Si l'une de vos tables se trouve dans une base de données différente et que les deux utilisent le schéma par défaut pour leurs bases de données, vous ajoutez simplement la base de données à la deuxième table:
Select a.*,b.* from
tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Si vous vous trouvez dans une troisième base de données différente de l'une de celles que vous interrogez, vous utilisez explicitement les deux noms de base de données:
Select a.*,b.* from
databaseD..tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Si vous finissez par utiliser différents schémas et / ou propriétaires, vous pouvez les ajouter dans:
Select a.*,b.* from
databaseD.john.tableA a inner join
databaseC.accounting.tableB b on a.col1 = b.col1
Et enfin, si vous y faites très attention et que vous avez une très bonne raison, vous pouvez rejoindre une table (généralement petite) sur un autre serveur:
Select a.* from
databaseD.john.TableA a inner join
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
- Quand est-il temps d'aller au-delà d'une configuration à 1 base de données / 1 serveur? Est-il courant de devoir faire cela? Existe-t-il des stratégies spéciales pour suivre les tables dans quelle base de données?
Je vais combiner ces deux parce qu'ils vont ensemble. Vous êtes presque toujours d'accord pour commencer avec l'hypothèse qu'une base de données, un serveur est suffisant jusqu'à ce que vos contraintes de conception / métier / techniques vous obligent à en utiliser davantage.
Donc, pour répondre à votre deuxième question en premier, puisque vous avez généralement une raison d'avoir des bases de données distinctes, il devrait être assez évident de connaître la conception de votre système où se trouve quelque chose.
Quant à savoir quand / pourquoi il est nécessaire d'aller au-delà d'une seule base de données. Il s'agit généralement d'un mélange de règles commerciales, politiques et / ou techniques.
Par exemple, où je travaille, nous avons 16 bases de données réparties sur 4 serveurs. Nous avons un MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB. Pour donner quelques exemples de leurs différences:
- FinancialDB, informations sensibles
- Base de données d'images, différentes exigences spécifiques de stockage et de récupération
- ReferenceDB, faible transaction, lecture élevée
- ReportingDB, lecture très élevée, doit être restauré / répliqué dans divers autres environnements contrairement à beaucoup d'autres données
- StagingDB, rien de permanent, juste un tempdb renforcé sur lequel nous avons plus de contrôle
- MainDB, s'interface avec toutes les autres bases de données, mais a besoin de sauvegardes différentielles donc ... nous divisons le
- Tables HighVolumeTransaction, (qui sont relativement transitoires), vers leur propre base de données afin de conserver une taille de sauvegarde raisonnable.
- Archive, Beaucoup des mêmes données de Main et Reporting, mais avec des périodes de rétention plus longues et des requêtes plus difficiles à creuser profondément dans les données. Si cela était toujours combiné avec Main / Reporting, cela entraînerait un blocage de notre système.
• Le code d'application doit-il savoir qu'une ou plusieurs bases de données sont réparties sur plusieurs serveurs? Sinon, à quel niveau les demandes sont-elles filtrées?
Au sens large, ils le font probablement. Ils doivent au minimum savoir sur quel serveur ils pointent dans la chaîne de connexion à la base de données. Traitement, rapport, principal, etc.
À partir de là, ils ont besoin d'un contexte de base de données pour s'exécuter. En général, ce serait le plus utilisé pour l'application, peut-être même l'original de la base de données / un serveur jours de l'application. Vous POUVEZ faire en sorte que l'application change explicitement le contexte de la base de données à chaque appel, mais cela rend très difficile l'ajustement de la base de données sans changer l'application.
L'approche habituelle (ou du moins MON habituelle) consiste à toujours accéder via une ou peut-être deux bases de données principales.
Créez ensuite des vues dans d'autres bases de données si nécessaire, combinées à une interface avec la base de données via des procédures stockées.
Donc pour illustrer:
Supposons que vous souhaitiez obtenir les informations démographiques, les données de vente et le solde créditeur d'un client, et que ces informations soient réparties sur trois tableaux, tous à l'origine dans MainDB.
Vous écrivez donc un appel depuis votre application:
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
Impressionnant. Cependant, à chaque fois que nous modifions un nom de colonne ou renommons / déplaçons une table, vous devez mettre à jour le code de l'application. Donc, au lieu de cela, nous faisons deux choses:
créer des clients, des ventes, des vues AccountReceivables (vous n'utiliseriez pas Select * mais je fais une démonstration ici)
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
Ensuite, nous créerions également une procédure stockée, 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
Et demandez à votre application d'appeler cela.
Maintenant, tant que je ne change pas l'interface sur ce proc stocké, je peux à peu près faire tout ce que je dois faire à la base de données principale pour augmenter ou réduire.
À l'extrême, je pouvais même créer mon ancien MainDB juste un tas de procédures stockées et de vues shellées de sorte que sous ces vues que nous avons créées, cela ressemblait à ceci:
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
Et votre application ne connaîtra jamais la différence (en supposant, entre autres, des canaux rapides et des données bien organisées).
Évidemment, c'est extrême et je mentirais si je disais que tout était planifié de cette façon, mais l'utilisation de procédures / vues stockées même si vous le faites tout en refactorisant vous permettra beaucoup de flexibilité à mesure que votre application se développe à partir de son humble base de données / serveur début.