¿Hay desventajas para las bases de datos contenidas?

33

SQL Server 2012 introdujo el concepto de bases de datos "contenidas", donde todo (bueno, principalmente todo) que necesita la base de datos está contenido dentro de la base de datos. Esto ofrece grandes ventajas al mover bases de datos entre servidores. Me gustaría saber, entonces, si esta debería ser mi estrategia predeterminada al diseñar una nueva base de datos.

MSDN enumera varias desventajas para las bases de datos contenidas, y las grandes son la falta de soporte para el seguimiento y la replicación de cambios. ¿Hay otros? Si no voy a usar estas características, ¿hay alguna razón para no usar bases de datos contenidas?

marca
fuente

Respuestas:

33

El objetivo principal de las bases de datos contenidas es facilitar la transferencia de su base de datos a un nuevo servidor sin muchos andamios. Con eso en mente, trataré algunos problemas potenciales que harán que esta migración sea más difícil, y la mayoría gira en torno al hecho de que las bases de datos contenidas solo están parcialmente contenidas en SQL Server 2012 (la contención no se aplica realmente).


Cadenas de conexión

Las cadenas de conexión a una base de datos contenida deben especificar explícitamente la base de datos en la cadena de conexión. Ya no puede confiar en la base de datos predeterminada del inicio de sesión para establecer una conexión; Si no especifica una base de datos, SQL Server no va a recorrer todas las bases de datos contenidas e intentará encontrar cualquier base de datos donde sus credenciales puedan coincidir.


Cross-db consultas

Incluso si crea el mismo usuario con la misma contraseña en dos bases de datos diferentes en el mismo servidor, su aplicación no podrá realizar consultas entre bases de datos. Los nombres de usuario y contraseñas pueden ser los mismos, pero son no el mismo usuario. ¿La razón de esto? Si ha contenido bases de datos en un servidor alojado, no se le debe impedir tener el mismo usuario contenido que otra persona que esté usando el mismo servidor alojado. Cuando llega la contención completa (probablemente en la versión posterior a SQL Server 2012 nunca), las consultas entre bases de datos estarán absolutamente prohibidas de todos modos. Recomiendo encarecidamente que no cree inicios de sesión a nivel de servidor con el mismo nombre que los usuarios de la base de datos contenida, e intente evitar crear el mismo nombre de usuario contenido en las bases de datos contenidas. Si necesita ejecutar consultas que lleguen a múltiples bases de datos contenidas, hágalo utilizando un inicio de sesión a nivel de servidor que tenga los privilegios apropiados (puede pensar que esto es así sysadmin, pero para consultas de solo lectura, esto es CONNECT ANY DATABASEy SELECT ALL USER SECURABLES).


Sinónimos

La mayoría de los nombres de 3 y 4 partes son fáciles de identificar y aparecen en un DMV. Sin embargo, si crea un sinónimo que apunta a un nombre de 3 o 4 partes, estos no aparecen en el DMV. Por lo tanto, si hace un uso intensivo de sinónimos, es posible que pierda algunas dependencias externas, y esto puede causar problemas en el punto en que migra la base de datos a un servidor diferente. Me quejé de este problema, pero se cerró como "por diseño" y no sobrevivió a la migración al nuevo sistema de comentarios . Tenga en cuenta que el DMV también perderá nombres de 3 y 4 partes que se construyen a través de SQL dinámico.


Política de contraseñas

Si ha creado un usuario de base de datos contenido en un sistema sin una política de contraseñas, puede resultarle difícil crear el mismo usuario en un sistema diferente que tenga una política de contraseñas. Esto se debe a que la CREATE USERsintaxis no admite eludir la política de contraseña. Archivé un error sobre este problema, y ​​permanece abierto (y tampoco sobrevivió al movimiento cuando se retiró Connect). Y me parece extraño que en un sistema con una política de contraseñas, puede crear un inicio de sesión a nivel de servidor que omita fácilmente la política, pero no puede crear un usuario de base de datos que lo haga, aunque este usuario es inherentemente menos riesgo de seguridad.


Colación

Como ya no podemos confiar en la recopilación de tempdb, es posible que deba cambiar cualquier código que actualmente utilice la clasificación explícita o DATABASE_DEFAULTutilizar CATALOG_DEFAULTen su lugar. Consulte este artículo de BOL para conocer algunos posibles problemas .


IntelliSense

Si se conecta a una base de datos contenida como un usuario contenido, SSMS no admitirá completamente IntelliSense. Obtendrá subrayado básico para los errores de sintaxis, pero no habrá listas de autocompletado o información sobre herramientas y todas las cosas divertidas. Archivé un error sobre este problema, y ​​permanece abierto , y uno más que no sobrevivió al movimiento.


Herramientas de datos de SQL Server

Si planea usar SSDT para el desarrollo de bases de datos, actualmente no hay soporte completo para las bases de datos contenidas. Lo que realmente significa que la construcción del proyecto no fallará si usa alguna característica o sintaxis que rompa la contención, ya que SSDT actualmente no sabe qué es la contención y qué podría romperla.


ALTERAR BASE DE DATOS

Al ejecutar un ALTER DATABASEcomando desde el contexto de una base de datos contenida, en lugar de ALTER DATABASE foolo que necesitará usar ALTER DATABASE CURRENT, esto es para que si la base de datos se mueve, cambia de nombre, etc., estos comandos no necesitan saber nada sobre su contexto externo o referencia .


Algunos otros

Algunas cosas que probablemente no deberías seguir usando, pero que deberían mencionarse en la lista de cosas que no son compatibles o están en desuso y no deberían usarse en bases de datos contenidas:

  • procedimientos numerados
  • procedimientos temporales
  • cambios de intercalación en objetos enlazados
  • cambiar la captura de datos
  • seguimiento de cambios
  • replicación

Dicho todo esto, estas no son necesariamente desventajas para usar bases de datos contenidas, son solo problemas que debe tener en cuenta y no se divulgan explícitamente en la documentación oficial.

También deberá asegurarse de que si se va a migrar una base de datos contenida, o es parte de un grupo de disponibilidad o se está duplicando, que todos los servidores de destino potenciales tienen la sp_configureopción contained database authenticationestablecida en 1.

Puede encontrar esta publicación de blog útil, así como esta , aunque sean anteriores a RTM.

Aaron Bertrand
fuente
¿Sabes por qué no se permiten procedimientos temporales?
Jon Seigel
2
@JonSeigel todavía están permitidos bajo contención parcial, pero violan la contención (lo que significa que no hay forma de validar a qué entidades accede el procedimiento, ya que sus metadatos y definición se almacenan en otro lugar), por lo que no se recomienda. Desde msdn.microsoft.com/en-us/library/ff929071.aspx#Limitations : Actualmente se permiten procedimientos almacenados temporales. Debido a que los procedimientos almacenados temporales infringen la contención, no se espera que sean compatibles en futuras versiones de la base de datos contenida.
Aaron Bertrand
9

Para aquellos que estén interesados ​​en obtener más detalles sobre las bases de datos contenidas, puedo recomendarles que lean este artículo http://www.sqlshack.com/contained-databases-in-sql-server/

El artículo señala las principales ventajas / desventajas del uso de bases de datos contenidas.

Desventajas

Las bases de datos parcialmente contenidas no pueden usar características como replicación, captura de datos de cambios, seguimiento de cambios, objetos vinculados a esquemas que dependen de funciones integradas con cambios de intercalación.

Ventajas

Por otro lado, como ya se mencionó, hay algunos beneficios de usar bases de datos contenidas, como:

  • Es bastante fácil mover la base de datos de un servidor a otro,
    ya que no habrá problemas de usuarios huérfanos.
  • Los metadatos se almacenan en bases de datos contenidas para que sea más fácil y portátil.
  • Es posible tener autenticación tanto de SQL Server como de Windows para usuarios de DB contenidos

El artículo también ayuda con:

  • crear una nueva base de datos contenida (al hacer que el tipo de contención sea Parcial en la página Opciones en SQL Server y usar la consulta T-SQL para crear una base de datos después)
  • conectarse a la base de datos contenida utilizando SQL Server Management Studio (es necesario especificar el nombre de la base de datos contenida en el parámetro de conexión)
  • convertir la base de datos existente a una base de datos contenida
  • trabajando en una base de datos contenida y enumerando todos los inicios de sesión que son de tipo de usuario contenido
Alex Kirilov
fuente
4

Una desventaja es que no se puede obligar a un usuario de la base de datos a cambiar su propia contraseña como podrían hacerlo los inicios de sesión ( MUST_CHANGE). Los usuarios no pueden administrar su propia contraseña a menos que les otorgue un permiso de usuario alternativo y les diga cómo cambiarla mediante una instrucción SQL. No les resulta fácil administrarlo a través de las interfaces de usuario o, al menos, no sé cómo.

Una nota adicional es que encontré el uso inesperado e indocumentado de metadatos en la cláusula "PIVOT" Y "UNPIVOT", que pensé que debería estar solo en el catálogo del sistema (sys.tables / sys.columns / etc). Como se documenta en msdn :

En una base de datos contenida, la clasificación del catálogo Latin1_General_100_CI_AS_WS_KS_SC . Esta clasificación es la misma para todas las bases de datos contenidas en todas las instancias de SQL Server y no se puede cambiar.

Pero no mencionaron que la cláusula "PIVOT" Y "UNPIVOT" también usan los catálogos del sistema como mecanismo de ejecución. por lo tanto, produce un error de intercalación en todas partes cerca del uso de la cláusula "PIVOT" Y "UNPIVOT" durante la migración. Aquí hay algo de repro:

/*step1 create a table belongs to a contained database and populate some data*/
create  table dbo.test1 (col1 varchar(100),col2 varchar(100))
insert  dbo.test1 values('a','x')
insert  dbo.test1 values('b','y')
insert  dbo.test1 values('c','z')

/*step2 lets see its collation you will see it is correctly as same as its (contained) database */
select name,collation_name from sys.columns where object_name(object_id) = 'test1'

/*step3 reproduce an unpivoted column*/
select * into dbo.test2
from (select * from dbo.test1) a unpivot (val for col in (col1,col2)) a


/*step4 lets check its collation you will see the column specified at "FOR" clause is created as Latin1_General_100_CI_AS_KS_WS_SC */
select name,collation_name from sys.columns where object_name(object_id) = 'test2'

/*step5 make use of the unpivoted table without awareness will cause an error*/
select val + ' = ' + col from dbo.test2 

/*step6 clean up*/
drop table dbo.test1
drop table dbo.test2

También puede ver que los artículos sobre la base de datos contenida están en su mayoría incompletos. así que decidir usarlo necesita una muy buena improvisación.

Paul.K
fuente