Existem desvantagens nos bancos de dados contidos?

33

O SQL Server 2012 introduziu o conceito de bancos de dados "contidos", onde tudo (bem, principalmente tudo) o que o banco de dados precisa está contido no próprio banco de dados. Isso oferece grandes vantagens ao mover bancos de dados entre servidores. Gostaria de saber, então, se essa deve ser minha estratégia padrão ao projetar um novo banco de dados.

O MSDN lista várias desvantagens dos bancos de dados contidos, e os grandes são a falta de suporte para rastreamento e replicação de alterações. Existem outros? Se não vou usar esses recursos, existe algum motivo para não usar bancos de dados contidos?

Marca
fonte

Respostas:

33

O objetivo principal dos bancos de dados contidos é facilitar a portabilidade do banco de dados para um novo servidor sem muitos andaimes. Com isso em mente, tratarei alguns problemas em potencial que dificultarão essa migração - e a maioria gira em torno do fato de que os bancos de dados contidos estão apenas parcialmente contidos no SQL Server 2012 (a contenção não é realmente imposta).


Strings de conexão

As cadeias de conexão com um banco de dados contido devem especificar explicitamente o banco de dados na cadeia de conexão. Você não pode mais confiar no banco de dados padrão do logon para estabelecer uma conexão; se você não especificar um banco de dados, o SQL Server não percorrerá todos os bancos de dados contidos e tentará encontrar qualquer banco de dados em que suas credenciais possam corresponder.


Consultas entre bancos de dados

Mesmo se você criar o mesmo usuário com a mesma senha em dois bancos de dados diferentes contidos no mesmo servidor, seu aplicativo não poderá executar consultas entre bancos de dados. Os nomes de usuários e senhas pode ser o mesmo, mas eles são não o mesmo usuário. A razão disso? Se você possui bancos de dados em um servidor hospedado, não deve ser impedido de ter o mesmo usuário contido que outra pessoa que esteja usando o mesmo servidor hospedado. Quando chega a contenção total (provavelmente na versão após o SQL Server 2012 nunca), as consultas entre bancos de dados serão absolutamente proibidas de qualquer maneira. Eu recomendo que você não crie logins no nível do servidor com o mesmo nome que os usuários de banco de dados contidos e tente evitar a criação do mesmo nome de usuário contido nos bancos de dados contidos. Se você precisar executar consultas que atinjam vários bancos de dados contidos, faça-o usando um logon no nível do servidor que possua privilégios apropriados (você pode pensar que sysadminsim, mas para consultas somente leitura, é CONNECT ANY DATABASEe SELECT ALL USER SECURABLES).


Sinônimos

A maioria dos nomes de 3 e 4 partes é fácil de identificar e aparece em uma DMV. No entanto, se você criar um sinônimo que aponte para um nome de 3 ou 4 partes, eles não aparecerão na DMV. Portanto, se você fizer uso pesado de sinônimos, é possível que você perca algumas dependências externas e isso pode causar problemas no momento em que você migra o banco de dados para um servidor diferente. Reclamei sobre esse problema, mas ele foi fechado como "por design" e não sobreviveu à migração para o novo sistema de feedback . Observe que o DMV também perderá nomes de 3 e 4 partes que são construídos via SQL dinâmico.


Política de senha

Se você criou um usuário de banco de dados contido em um sistema sem uma política de senha em vigor, pode ser difícil criar o mesmo usuário em um sistema diferente que possui uma política de senha. Isso ocorre porque a CREATE USERsintaxe não suporta ignorar a política de senha. Eu registrei um bug sobre esse problema, e ele permanece aberto (e também não sobreviveu à mudança quando o Connect foi retirado). E me parece estranho que, em um sistema com uma política de senha, você possa criar um logon no nível do servidor que ignore facilmente a política, mas não possa criar um usuário de banco de dados que o faça - mesmo que esse usuário seja inerentemente menos risco de segurança.


Agrupamento

Como não podemos mais confiar no agrupamento do tempdb, pode ser necessário alterar qualquer código que atualmente usa agrupamento explícito ou DATABASE_DEFAULTusá-lo CATALOG_DEFAULT. Consulte este artigo da BOL para alguns problemas em potencial .


IntelliSense

Se você se conectar a um banco de dados contido como um usuário contido, o SSMS não oferecerá suporte total ao IntelliSense. Você terá sublinhado básico para erros de sintaxe, mas nenhuma lista ou dicas de ferramenta de preenchimento automático e todas as coisas divertidas. Eu registrei um bug sobre esse problema, e ele permanece aberto - e mais um que não sobreviveu à mudança.


Ferramentas de dados do SQL Server

Se você planeja usar o SSDT para desenvolvimento de banco de dados, atualmente não há suporte completo para bancos de dados contidos. O que realmente significa apenas que a construção do projeto não falhará se você usar algum recurso ou sintaxe que quebre a contenção, pois o SSDT atualmente não sabe o que é a contenção e o que pode quebrá-la.


ALTER DATABASE

Ao executar um ALTER DATABASEcomando a partir do contexto de um banco de dados contido, r Em vez de ALTER DATABASE foovocê precisar usá ALTER DATABASE CURRENT-lo - é para que, se o banco de dados for movido, renomeado, etc., esses comandos não precisem saber nada sobre seu contexto ou referência externa. .


Alguns outros

Algumas coisas que você provavelmente ainda não deveria estar usando, mas devem ser mencionadas na lista de coisas que não são suportadas ou estão obsoletas e não devem ser usadas em bancos de dados contidos:

  • procedimentos numerados
  • procedimentos temporários
  • mudanças de agrupamento em objetos vinculados
  • alterar captura de dados
  • rastreamento de alterações
  • replicação

Dito isso, essas não são necessariamente desvantagens do uso de bancos de dados contidos, são apenas questões que você deve estar ciente e nem todas são explicitamente divulgadas na documentação oficial.

Você também precisará ter certeza de que, se um banco de dados contido for migrado ou fizer parte de um grupo de disponibilidade ou estiver sendo espelhado, todos os servidores de destino em potencial tenham a sp_configureopção contained database authenticationdefinida como 1.

Você pode achar útil este post do blog , bem como este , mesmo que eles sejam anteriores à RTM.

Aaron Bertrand
fonte
Você sabe por que procedimentos temporários não são permitidos?
Jon Seigel
2
@JonSeigel ainda são permitidos sob contenção parcial, mas violam a contenção (o que significa que não há como validar quais entidades o procedimento acessa, pois seus metadados e definição são armazenados em outro local), portanto, não é recomendado. De msdn.microsoft.com/en-us/library/ff929071.aspx#Limitations : procedimentos armazenados temporários são atualmente permitidos. Como os procedimentos armazenados temporários violam a contenção, não se espera que eles sejam suportados em versões futuras do banco de dados contido.
Aaron Bertrand
9

Para quem estiver interessado em obter mais detalhes sobre bancos de dados contidos, recomendo que leiam este artigo http://www.sqlshack.com/contained-databases-in-sql-server/

O artigo aponta as principais vantagens / desvantagens do uso de bancos de dados contidos.

Desvantagens

Bancos de dados parcialmente contidos não podem usar recursos como replicação, captura de dados alterados, rastreamento de alterações, objetos vinculados ao esquema que dependem de funções internas com alterações de agrupamento.

Vantagens

Por outro lado, como já mencionado, existem alguns benefícios do uso de bancos de dados contidos, como:

  • É muito fácil mover o banco de dados de um servidor para outro,
    pois não haverá problemas de usuários órfãos
  • Os metadados são armazenados em bancos de dados independentes, tornando-os mais fáceis e portáteis
  • É possível ter autenticação do SQL Server e do Windows para usuários de banco de dados contidos

O artigo também ajuda com:

  • criando um novo banco de dados contido (tornando o tipo de contenção como Parcial na página Opções no SQL Server e usando a consulta T-SQL para criar um banco de dados posteriormente)
  • conectando-se ao banco de dados contido usando o SQL Server Management Studio (é necessário especificar o nome do banco de dados contido no parâmetro de conexão)
  • convertendo banco de dados existente em um banco de dados contido
  • trabalhando em um banco de dados contido e listando todos os logins que são do tipo de usuário contido
Alex Kirilov
fonte
4

Uma desvantagem é que um usuário de banco de dados contido não pode ser forçado a alterar sua própria senha como os logins poderiam ( MUST_CHANGE). Os usuários não podem gerenciar sua própria senha, a menos que você conceda a eles uma permissão de usuário alterado e diga a eles como alterá-la usando uma instrução SQL. Em nenhum lugar é fácil gerenciá-lo por meio de interfaces de usuário ou pelo menos não sei como.

Nota adicional é que, encontrei o uso inesperado e não documentado de metadados na cláusula "PIVOT" AND "UNPIVOT", que eu pensava que deveria estar apenas no catálogo do sistema (sys.tables / sys.columns / etc). Conforme documentado no msdn :

Em um banco de dados contido, o agrupamento de catálogo Latin1_General_100_CI_AS_WS_KS_SC . Esse agrupamento é o mesmo para todos os bancos de dados contidos em todas as instâncias do SQL Server e não pode ser alterado.

Mas eles não mencionaram que a cláusula "PIVOT" E "UNPIVOT" também usa os catálogos do sistema como um mecanismo de execução. portanto, produz um erro conflitante de agrupamento em qualquer lugar próximo ao uso da cláusula "PIVOT" E "UNPIVOT" durante a migração. aqui está uma 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

Você também pode ver que os artigos sobre o banco de dados contido estão incompletos. então, decidir usá-lo precisa de uma improvisação muito boa.

Paul.K
fonte