Ok, vamos a desglosarlo:
- ¿Cómo se construyen las uniones entre dos tablas en múltiples bases de datos? (Un ejemplo de código aquí sería útil).
Esto es bastante sencillo. Los objetos SQL tienen desde una convención de nomenclatura de una a cuatro partes:
Servername.databasename.schemaname.tablename
Si todas sus tablas están en el mismo servidor en la misma base de datos, con el mismo propietario / esquema, puede ignorar las tres primeras partes y usar lo que está más acostumbrado a:
Select a.*,b.* from
tableA a inner join
tableB b on a.col1=b.col1
Si una de sus tablas está en una base de datos diferente y ambas usan el esquema predeterminado para sus bases de datos, simplemente agregue la base de datos a la segunda tabla:
Select a.*,b.* from
tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Si se encuentra en una tercera base de datos diferente de cualquiera de las que está consultando, use ambos nombres de base de datos explícitamente:
Select a.*,b.* from
databaseD..tableA a inner join
databaseC..tableB b on a.col1 = b.col1
Si termina utilizando diferentes esquemas y / o propietarios, puede agregarlos en:
Select a.*,b.* from
databaseD.john.tableA a inner join
databaseC.accounting.tableB b on a.col1 = b.col1
Y, por último, si tiene mucho cuidado y tiene una muy buena razón, puede unirse a una tabla (generalmente pequeña) en otro servidor:
Select a.* from
databaseD.john.TableA a inner join
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
- ¿Cuándo es el momento de ir más allá de una configuración de 1 base de datos / 1 servidor? ¿Qué tan común es tener que hacer esto? ¿Existen estrategias especiales para rastrear qué tablas están en qué base de datos?
Combinaré estos dos porque van juntos. En general, casi siempre está bien comenzar con la suposición de que una base de datos de un servidor es suficiente hasta que sus limitaciones técnicas / comerciales / de diseño lo obliguen a usar más.
Entonces, para responder a su segunda pregunta primero, dado que generalmente tiene una razón para tener bases de datos separadas, debería ser bastante obvio saber el diseño de su sistema donde está algo.
En cuanto a cuándo / por qué es necesario ir más allá de una sola base de datos. Por lo general, es una combinación de reglas comerciales, políticas y / o razones técnicas.
Por ejemplo, donde trabajo tenemos 16 bases de datos repartidas en 4 servidores. Tenemos MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB. Para dar algunos ejemplos de por qué son diferentes:
- FinancialDB, información sensible
- Image DB, requisitos específicos de almacenamiento y recuperación diferentes
- Referencia DB, transacción baja, lectura alta
- ReportingDB, lectura muy alta, necesita ser restaurado / replicado a varios otros entornos a diferencia de muchos otros datos
- StagingDB, nada permanente, solo un tempdb reforzado sobre el que tenemos más control
- MainDB, interactúa con todos los otros DB pero necesita copias de seguridad diferenciales, así que ... dividimos el
- Las tablas de HighVolumeTransaction (que son relativamente transitorias) a su propia base de datos para mantener el tamaño razonable de la copia de seguridad.
- Archivo, muchos de los mismos datos de Principal e Informes, pero con períodos de retención más largos y consultas más difíciles de cavar en profundidad en los datos. Si esto todavía se combinara con Main / Reporting, se estancaría nuestro sistema.
• ¿El código de la aplicación necesita saber que una o más bases de datos están distribuidas en múltiples servidores? Si no, ¿a qué nivel se filtran las solicitudes?
En un sentido amplio, probablemente lo hagan. Como mínimo, necesitan saber a qué servidor apuntan en la cadena de conexión de la base de datos. Procesamiento, Informes, Principal, etc.
A partir de ahí, necesitan un contexto de base de datos para ejecutar. En general, ese sería el más utilizado para la aplicación, tal vez incluso el original de la base de datos / un servidor días de la aplicación. PUEDE hacer que la aplicación cambie explícitamente el contexto de la base de datos en cada llamada, pero eso hace que sea muy difícil ajustar la base de datos sin cambiar la aplicación.
El enfoque habitual (o al menos MI habitual) es acceder siempre a través de una o quizás dos bases de datos principales.
Luego, cree vistas en otras bases de datos según sea necesario combinadas con la interfaz con la base de datos a través de procedimientos almacenados.
Entonces para ilustrar:
Supongamos que desea obtener la información demográfica, los datos de ventas y el saldo de crédito de un Cliente, y eso se distribuye en tres tablas originalmente todas en MainDB.
Entonces escribes una llamada desde tu aplicación:
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
Increíble. Sin embargo, ahora cada vez que cambiemos el nombre de una columna, o cambiemos el nombre / muevamos una tabla, debe actualizar el código de la aplicación. Entonces, en su lugar, hacemos dos cosas:
crear clientes, ventas, vistas de cuentas por cobrar (no usaría Select * pero estoy haciendo una demostración aquí)
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
Luego también creamos un procedimiento almacenado, 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
Y que tu aplicación llame así.
Ahora, siempre y cuando no cambie la interfaz en ese proceso almacenado, puedo hacer casi cualquier cosa que necesite hacer en la base de datos de back-end para escalar o escalar.
En el extremo, incluso podría hacer que mi viejo MainDB fuera solo un montón de procedimientos almacenados y vistas almacenadas de forma tal que debajo de esas vistas que creamos se veía así:
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
Y su aplicación nunca notaría la diferencia (suponiendo entregas rápidas y datos bien organizados, entre otras cosas).
Obviamente, eso es extremo y estaría mintiendo si dijera que todo fue planeado de esta manera, pero el uso de procedimientos / vistas almacenados, incluso si lo hace durante la refactorización, le permitirá mucha flexibilidad a medida que su aplicación crezca desde su humilde base de datos / servidor comenzando.