Ci sono svantaggi per i database contenuti?


33

SQL Server 2012 ha introdotto il concetto di database "contenuti", in cui tutto (bene, soprattutto tutto) di cui il database ha bisogno è contenuto all'interno del database stesso. Ciò offre grandi vantaggi quando si spostano database tra server. Vorrei sapere, quindi, se questa dovrebbe essere la mia strategia predefinita durante la progettazione di un nuovo database.

MSDN elenca numerosi svantaggi per i database contenuti e quelli grandi sono la mancanza di supporto per il rilevamento e la replica delle modifiche. Ce ne sono altri? Se non ho intenzione di usare queste funzionalità, c'è qualche motivo per non usare database contenuti?

Risposte:


33

Lo scopo principale dei database contenuti è quello di semplificare il porting del database su un nuovo server senza molte impalcature al suo interno. Con questo in mente, tratterò alcuni potenziali problemi che renderanno più difficile questa migrazione - e la maggior parte ruota attorno al fatto che i database contenuti sono contenuti solo parzialmente in SQL Server 2012 (il contenimento non è effettivamente applicato).


Stringhe di connessione

Le stringhe di connessione a un database contenuto devono specificare esplicitamente il database nella stringa di connessione. Non è più possibile fare affidamento sul database predefinito di accesso per stabilire una connessione; se non si specifica un database, SQL Server non eseguirà il controllo di tutti i database contenuti e tenterà di trovare qualsiasi database in cui le credenziali possano corrispondere.


Query cross-db

Anche se si crea lo stesso utente con la stessa password in due diversi database contenuti sullo stesso server, l'applicazione non sarà in grado di eseguire query tra database. I nomi utente e password possono essere gli stessi, ma sono non lo stesso utente. La ragione di questo? Se hai contenuto database su un server ospitato, non dovresti impedire loro di avere lo stesso utente contenuto di qualcun altro che utilizza lo stesso server ospitato. Quando arriva il contenimento completo (probabilmente nella versione dopo SQL Server 2012 mai), le domande tra database saranno assolutamente vietate. Consiglio vivamente, caldamente, di non creare accessi a livello di server con lo stesso nome degli utenti di database contenuti e di provare a evitare di creare lo stesso nome utente contenuto su database contenuti. Se è necessario eseguire query che colpiscono più database contenuti, farlo utilizzando un accesso a livello di server con privilegi appropriati (si potrebbe pensare che lo sia sysadmin, ma per query di sola lettura, questo è CONNECT ANY DATABASEe SELECT ALL USER SECURABLES).


Sinonimi

La maggior parte dei nomi di 3 e 4 parti sono facili da identificare e compaiono in un DMV. Tuttavia, se si crea un sinonimo che punta a un nome di 3 o 4 parti, questi non vengono visualizzati nel DMV. Pertanto, se si fa un uso intensivo dei sinonimi, è possibile che manchino alcune dipendenze esterne e ciò può causare problemi nel momento in cui si esegue la migrazione del database su un altro server. Mi sono lamentato di questo problema, ma è stato chiuso come "di progettazione" e non è sopravvissuto alla migrazione al nuovo sistema di feedback . Notare che al DMV mancheranno anche i nomi di 3 e 4 parti che sono costruiti tramite SQL dinamico.


Politica password

Se è stato creato un utente di database contenuto su un sistema senza un criterio password in atto, potrebbe essere difficile creare lo stesso utente su un sistema diverso in cui è presente un criterio password. Questo perché la CREATE USERsintassi non supporta l'esclusione del criterio password. Ho segnalato un bug su questo problema, e rimane aperto (e non è sopravvissuto alla mossa quando Connect è stato ritirato). E mi sembra strano che su un sistema con una politica di password in atto, è possibile creare un accesso a livello di server che ignori facilmente la politica, ma non è possibile creare un utente di database che lo faccia, anche se questo utente è intrinsecamente meno rischi per la sicurezza.


confronto

Dal momento che non possiamo più fare affidamento sul confronto di tempdb, potrebbe essere necessario modificare qualsiasi codice che attualmente utilizza il confronto esplicito o DATABASE_DEFAULTutilizzare CATALOG_DEFAULTinvece. Vedi questo articolo BOL per alcuni potenziali problemi .


IntelliSense

Se ci si connette a un database contenuto come utente contenuto, SSMS non supporterà completamente IntelliSense. Otterrai una sottolineatura di base per gli errori di sintassi, ma non elenchi o descrizioni comandi di completamento automatico e tutte le cose divertenti. Ho segnalato un bug su questo problema, e rimane aperto - e un altro che non è sopravvissuto alla mossa.


SQL Server Data Tools

Se si prevede di utilizzare SSDT per lo sviluppo di database, al momento non è disponibile il supporto completo per i database contenuti. Ciò significa che la costruzione del progetto non fallirà se si utilizzano alcune funzionalità o sintassi che interrompono il contenimento, dal momento che SSDT attualmente non sa cosa sia il contenimento e cosa potrebbe romperlo.


ALTER DATABASE

Quando si esegue un ALTER DATABASEcomando all'interno del contesto di un database contenuto, rR piuttosto ALTER DATABASE fooche sarà necessario utilizzare ALTER DATABASE CURRENT- questo è così che se il database viene spostato, rinominato, ecc., Questi comandi non devono sapere nulla sul loro contesto esterno o riferimento .


Pochi altri

Alcune cose che probabilmente non dovresti ancora usare ma che comunque dovrebbero essere menzionate nell'elenco delle cose che non sono supportate o sono deprecate e non dovrebbero essere usate in database contenuti:

  • procedure numerate
  • procedure temporanee
  • le modifiche delle regole di confronto negli oggetti associati
  • modifica acquisizione dati
  • rilevamento delle modifiche
  • replicazione

Detto questo, questi non sono necessariamente svantaggi dell'utilizzo di database contenuti, sono solo problemi di cui dovresti essere a conoscenza e che non sono tutti esplicitamente divulgati nella documentazione ufficiale.

Dovrai anche essere sicuro che se un database contenuto verrà migrato, o fa parte di un gruppo di disponibilità o viene sottoposto a mirroring, tutti i potenziali server di destinazione hanno l' sp_configureopzione contained database authenticationimpostata su 1.

Puoi trovare utile questo post sul blog , oltre a questo , anche se hanno una data precedente a RTM.


Sai perché non sono consentite procedure temporanee?
Jon Seigel,

2
@JonSeigel sono ancora consentiti in contenimento parziale, ma violano il contenimento (il che significa che non c'è modo di convalidare le entità a cui accede la procedura, poiché i suoi metadati e la definizione sono memorizzati altrove), quindi non è raccomandato. Da msdn.microsoft.com/en-us/library/ff929071.aspx#Limitations : le stored procedure temporanee sono attualmente consentite. Poiché le procedure memorizzate temporanee violano il contenimento, non si prevede che saranno supportate nelle versioni future del database contenuto.
Aaron Bertrand

9

Per coloro che sono interessati a ottenere maggiori dettagli sui database contenuti, posso raccomandarli di leggere questo articolo http://www.sqlshack.com/contained-database-in-sql-server/

L'articolo individua i principali vantaggi / svantaggi dell'utilizzo di database contenuti.

svantaggi

I database parzialmente contenuti non possono utilizzare funzionalità come la replica, l'acquisizione dei dati di modifica, il rilevamento delle modifiche, oggetti associati allo schema che dipendono da funzioni integrate con modifiche delle regole di confronto.

vantaggi

D'altra parte, come già accennato, ci sono alcuni vantaggi dell'utilizzo di DB contenuti, come:

  • È abbastanza facile spostare il database da un server a un altro,
    poiché non ci saranno problemi di utente orfano
  • I metadati sono archiviati su database contenuti, quindi è più semplice e portatile
  • È possibile disporre sia dell'autenticazione di SQL Server che di Windows per utenti DB contenuti

L'articolo aiuta anche con:

  • creando un nuovo database contenuto (impostando il tipo di contenimento come Parziale nella pagina Opzioni in SQL Server e usando successivamente la query T-SQL per creare un database)
  • connessione al DB contenuto tramite SQL Server Management Studio (è necessario specificare il nome DB contenuto nel parametro di connessione)
  • convertire un database esistente in un database contenuto
  • lavorando su un database contenuto e elencando tutti gli accessi di tipo utente contenuto

4

Uno svantaggio è che un utente del database contenuto non può essere costretto a cambiare la propria password come potrebbe fare il login ( MUST_CHANGE). Gli utenti non possono gestire la propria password a meno che non si conceda loro un permesso utente alter e si dica loro come cambiarla usando un'istruzione SQL. Non è facile per loro gestirlo tramite le interfacce utente o almeno non so come.

Un'ulteriore nota è che, ho trovato l'uso di metadati imprevisto e non documentato nella clausola "PIVOT" E "UNPIVOT" che pensavo dovesse essere solo nel catalogo di sistema (sys.tables / sys.columns / etc). Come documentato in msdn :

In un database contenuto, le regole di confronto del catalogo Latin1_General_100_CI_AS_WS_KS_SC . Questo confronto è uguale per tutti i database contenuti in tutte le istanze di SQL Server e non può essere modificato.

Ma non hanno menzionato che la clausola "PIVOT" E "UNPIVOT" usano anche i cataloghi di sistema come meccanismo di esecuzione. quindi produce un errore di conflitto collation ovunque vicino all'uso della clausola "PIVOT" E "UNPIVOT" durante la migrazione. ecco qualche riproduzione:

/*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

puoi anche vedere che gli articoli sul database contenuto sono per lo più incompleti. quindi decidere di usarlo ha bisogno di un'ottima improvvisazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.