Czy istnieją wady zawartych baz danych?

33

SQL Server 2012 wprowadził koncepcję „zamkniętych” baz danych, w których wszystko (cóż, głównie wszystko), czego potrzebuje baza danych, jest zawarte w samej bazie danych. Ma to duże zalety przy przenoszeniu baz danych między serwerami. Chciałbym zatem wiedzieć, czy powinna to być moja domyślna strategia podczas projektowania nowej bazy danych.

MSDN wymienia kilka wad zawartych baz danych, a duże z nich to brak obsługi śledzenia zmian i replikacji. Czy są jeszcze inni? Jeśli nie zamierzam korzystać z tych funkcji, czy jest jakiś powód, aby nie używać zawartych baz danych?

znak
źródło

Odpowiedzi:

33

Podstawowym celem zawartych baz danych jest ułatwienie przeniesienia bazy danych na nowy serwer bez dużej ilości rusztowań wokół niego. Mając to na uwadze, zajmę się kilkoma potencjalnymi problemami, które utrudnią tę migrację - i większość dotyczy tego, że zawarte bazy danych są tylko częściowo zawarte w SQL Server 2012 (przechowywanie nie jest w rzeczywistości egzekwowane).


Ciągi połączeń

Parametry połączenia z zawartą bazą danych muszą jawnie określać bazę danych w parametrze połączenia. Nie możesz już polegać na domyślnej bazie danych logowania, aby ustanowić połączenie; jeśli nie określisz bazy danych, SQL Server nie przejdzie przez wszystkie zawarte w niej bazy danych i nie spróbuje znaleźć żadnej bazy danych, w której mogą się zgadzać twoje poświadczenia.


Zapytania między bazami danych

Nawet jeśli utworzysz tego samego użytkownika z tym samym hasłem w dwóch różnych zawartych bazach danych na tym samym serwerze, aplikacja nie będzie mogła wykonywać zapytań między bazami danych. Nazwy użytkowników i hasła mogą być takie same, ale nie są to ten sam użytkownik. Powodem tego? Jeśli zawierałeś bazy danych na serwerze hostowanym, nie powinieneś uniemożliwiać posiadania tego samego zamkniętego użytkownika, jak ktoś inny, kto akurat korzysta z tego samego serwera hostowanego. Kiedy nadejdzie pełne zabezpieczenie (prawdopodobnie w wersji po SQL Server 2012 nigdy), zapytania między bazami danych będą absolutnie zabronione. Bardzo, bardzo, gorąco polecam, aby nie tworzyć loginów na poziomie serwera o tej samej nazwie, co użytkownicy zawartej bazy danych i starać się unikać tworzenia tej samej zawartej nazwy użytkownika w zawartych bazach danych. Jeśli chcesz uruchomić zapytania trafiające do wielu zawartych baz danych, zrób to przy użyciu logowania na poziomie serwera, które ma odpowiednie uprawnienia (możesz pomyśleć, że tak jest sysadmin, ale w przypadku zapytań tylko do odczytu to CONNECT ANY DATABASEi SELECT ALL USER SECURABLES).


Synonimy

Większość nazw 3- i 4-częściowych jest łatwa do zidentyfikowania i pojawia się w DMV. Jeśli jednak utworzysz synonim, który wskazuje na 3- lub 4-częściową nazwę, nie pojawią się one w DMV. Jeśli więc intensywnie korzystasz z synonimów, możliwe, że przegapisz niektóre zależności zewnętrzne, co może powodować problemy w miejscu migracji bazy danych na inny serwer. Skarżyłem się na ten problem, ale został on zamknięty jako „z założenia” i nie przetrwałem migracji do nowego systemu przesyłania opinii . Zauważ, że DMV będzie również brakować nazw 3- i 4-częściowych tworzonych za pomocą dynamicznego SQL.


Polityka haseł

Jeśli utworzyłeś użytkownika bazy danych zawartego w systemie bez założonej zasady haseł, może być trudne utworzenie tego samego użytkownika w innym systemie, w którym obowiązują zasady haseł. Wynika to z faktu, że CREATE USERskładnia nie obsługuje omijania zasad haseł. Złożyłem błąd dotyczący tego problemu i pozostaje on otwarty (a także nie przetrwał ruchu, gdy Connect został wycofany). I wydaje mi się dziwne, że w systemie, w którym obowiązują zasady dotyczące haseł, możesz utworzyć login na poziomie serwera, który z łatwością omija zasady, ale nie możesz utworzyć użytkownika bazy danych, który to robi - nawet jeśli ten użytkownik jest z natury mniejsze ryzyko bezpieczeństwa.


Porównanie

Ponieważ nie możemy już polegać na sortowaniu tempdb, może być konieczna zmiana dowolnego kodu, który obecnie używa jawnego sortowania lub DATABASE_DEFAULTużycie CATALOG_DEFAULTzamiast niego. Zobacz ten artykuł BOL, aby zapoznać się z potencjalnymi problemami .


IntelliSense

Jeśli łączysz się z zawartą bazą danych jako zamknięty użytkownik, SSMS nie będzie w pełni obsługiwać IntelliSense. Otrzymasz podstawowe podkreślenie błędów składni, ale nie będzie autouzupełniania list, podpowiedzi i innych fajnych rzeczy. Złożyłem błąd dotyczący tego problemu, który pozostaje otwarty - i jeszcze jeden, który nie przetrwał ruchu.


Narzędzia danych programu SQL Server

Jeśli planujesz używać SSDT do tworzenia baz danych, obecnie nie ma pełnej obsługi zawartych baz danych. Co tak naprawdę oznacza, że ​​zbudowanie projektu nie zawiedzie, jeśli użyjesz funkcji lub składni, która przerywa przechowywanie, ponieważ SSDT obecnie nie wie, co to jest przechowywanie i co może je złamać.


ZMIEŃ bazę danych

Podczas uruchamiania ALTER DATABASEkomendy z kontekstu zawartej bazy danych r Zamiast ALTER DATABASE fooużywać ALTER DATABASE CURRENTtej opcji - jest to tak, że jeśli baza danych zostanie przeniesiona, zmieniona jej nazwa itp., Komendy te nie muszą wiedzieć nic o ich zewnętrznym kontekście lub odwołaniu .


Kilka innych

Niektóre rzeczy, których prawdopodobnie nie powinieneś nadal używać, ale mimo to powinny zostać wymienione na liście rzeczy, które nie są obsługiwane lub są przestarzałe i nie powinny być używane w zawartych bazach danych:

  • procedury numerowane
  • procedury tymczasowe
  • zmiany sortowania w powiązanych obiektach
  • zmień przechwytywanie danych
  • zmiana śledzenia
  • replikacja

To powiedziawszy, niekoniecznie są to wady korzystania z zawartych baz danych, to tylko kwestie, o których powinieneś wiedzieć i nie wszystkie są jawnie ujawnione w oficjalnej dokumentacji.

Musisz również upewnić się, że jeśli migrowana będzie zawarta baza danych, część grupy dostępności lub kopia lustrzana, wszystkie potencjalne serwery docelowe mają sp_configureopcję contained database authenticationustawioną na 1.

Może ci się przydać ten post na blogu , a także ten , mimo że są one wcześniejsze niż RTM.

Aaron Bertrand
źródło
Czy wiesz, dlaczego tymczasowe procedury są niedozwolone?
Jon Seigel,
2
@JonSeigel są one nadal dozwolone w ramach częściowego przechowywania, ale naruszają one przechowywanie (co oznacza, że ​​nie ma sposobu na sprawdzenie, do których podmiotów dostęp ma procedura, ponieważ jej metadane i definicja są przechowywane gdzie indziej), więc nie jest to zalecane. Od msdn.microsoft.com/en-us/library/ff929071.aspx#Limitations : Tymczasowe procedury składowane są obecnie dozwolone. Ponieważ tymczasowe procedury składowane naruszają przechowywanie, nie oczekuje się, że będą obsługiwane w przyszłych wersjach zawartej bazy danych.
Aaron Bertrand
9

Dla tych, którzy są zainteresowani uzyskaniem dodatkowych informacji na temat zawartych baz danych, mogę polecić im przeczytanie tego artykułu http://www.sqlshack.com/contained-databases-in-sql-server/

W artykule wskazano główne zalety / wady korzystania z zawartych baz danych.

Niedogodności

Częściowo zawarte bazy danych nie mogą korzystać z funkcji takich jak replikacja, przechwytywanie danych, śledzenie zmian, obiekty związane ze schematem, które zależą od wbudowanych funkcji ze zmianami sortowania.

Zalety

Z drugiej strony, jak już wspomniano, istnieją pewne zalety korzystania z zawartych DB, takie jak:

  • Przenoszenie bazy danych z jednego serwera na drugi jest dość łatwe,
    ponieważ nie będzie problemów z osieroconymi użytkownikami
  • Metadane są przechowywane w zawartych bazach danych, dzięki czemu jest łatwiejsze i bardziej przenośne
  • Możliwe jest uwierzytelnianie SQL Server i Windows dla użytkowników DB

Artykuł pomaga również w:

  • tworzenie nowej zawartej bazy danych (poprzez utworzenie typu ograniczenia jako Częściowe na stronie Opcje w SQL Server i użycie zapytania T-SQL do utworzenia bazy danych później)
  • łączenie się z zawartą bazą danych za pomocą SQL Server Management Studio (konieczne jest określenie zawartej nazwy bazy danych w parametrze połączenia)
  • przekształcanie istniejącej bazy danych w zawartą bazę danych
  • praca na zawartej bazie danych i wyświetlenie wszystkich danych logowania zawartych w typie użytkownika
Alex Kirilov
źródło
4

Jedną wadą jest to, że użytkownik zawartej bazy danych nie może być zmuszony do zmiany własnego hasła, tak jak loginy ( MUST_CHANGE). Użytkownicy nie mogą zarządzać własnym hasłem, chyba że udzielisz im uprawnienia do zmiany użytkownika i nie powiesz im, jak je zmienić za pomocą instrukcji SQL. Nie ma dla nich łatwego zarządzania za pomocą interfejsów użytkownika, a przynajmniej nie wiem jak.

Dodatkowa uwaga jest taka, że ​​znalazłem nieoczekiwane i nieudokumentowane użycie metadanych w klauzulach „PIVOT” I „UNPIVOT”, które moim zdaniem powinny znajdować się tylko w katalogu systemowym (sys.tables / sys.columns / etc). Jak udokumentowano w msdn :

W zawartej bazie danych zestawienie katalogu Latin1_General_100_CI_AS_WS_KS_SC . To zestawienie jest takie samo dla wszystkich zawartych baz danych we wszystkich instancjach SQL Server i nie można go zmienić.

Nie wspomnieli jednak, że klauzule „PIVOT” I „UNPIVOT” również używają katalogów systemowych jako mechanizmu wykonywania. dlatego generuje błąd konfliktu sortowania wszędzie przy użyciu klauzuli „PIVOT” I „UNPIVOT” podczas migracji. oto kilka 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

widać również, że artykuły o zawartej bazie danych są w większości niekompletne. więc decyzja o użyciu wymaga bardzo dobrej improwizacji.

Paul.K
źródło