Apakah ada kerugian untuk database yang terkandung?

33

SQL Server 2012 memperkenalkan konsep "berisi" database, di mana semuanya (yah, sebagian besar semuanya) kebutuhan database terkandung dalam database itu sendiri. Ini menawarkan keuntungan besar saat memindahkan basis data antar server. Saya ingin tahu, kemudian, apakah ini harus menjadi strategi default saya ketika mendesain database baru.

MSDN daftar beberapa kelemahan untuk database yang terkandung, dan yang besar adalah kurangnya dukungan untuk pelacakan perubahan dan replikasi. Apakah ada yang lain? Jika saya tidak akan menggunakan fitur-fitur ini, apakah ada alasan untuk tidak menggunakan database yang ada?

Menandai
sumber

Jawaban:

33

Tujuan utama dari database yang terkandung adalah untuk membuatnya lebih mudah untuk mem-port database Anda ke server baru tanpa banyak perancah di sekitarnya. Dengan mengingat hal itu, saya akan menangani beberapa masalah potensial yang akan membuat migrasi ini lebih sulit - dan sebagian besar berkisar pada kenyataan bahwa basis data yang terkandung hanya sebagian terkandung dalam SQL Server 2012 (penahanan tidak benar-benar diberlakukan).


String koneksi

String koneksi ke database yang terkandung harus secara eksplisit menentukan database dalam string koneksi. Anda tidak lagi dapat mengandalkan database default login untuk membuat koneksi; jika Anda tidak menentukan basis data, SQL Server tidak akan melangkah melalui semua basis data yang terkandung dan mencoba menemukan basis data di mana kredensial Anda mungkin cocok.


Kueri lintas-db

Bahkan jika Anda membuat pengguna yang sama dengan kata sandi yang sama di dua basis data yang terkandung di server yang sama, aplikasi Anda tidak akan dapat melakukan kueri lintas basis data. Nama pengguna dan kata sandi mungkin sama, tetapi mereka bukan pengguna yang sama. Alasan untuk ini? Jika Anda memiliki basis data di server yang dihosting, Anda tidak boleh dicegah untuk memiliki pengguna yang sama dengan orang lain yang kebetulan menggunakan server yang di-host yang sama. Ketika penahanan penuh tiba (kemungkinan dalam versi setelah SQL Server 2012 tidak pernah), permintaan lintas-basis data mutlak akan dilarang. Saya sangat, sangat, sangat menyarankan agar Anda tidak membuat login tingkat server dengan nama yang sama dengan pengguna database yang terkandung, dan mencoba untuk menghindari membuat nama pengguna yang sama di seluruh database yang ada. Jika Anda perlu menjalankan kueri yang mengenai beberapa basis data yang terkandung, lakukan itu menggunakan login tingkat server yang memiliki hak istimewa yang sesuai (Anda mungkin berpikir ini adalah sysadmin, tetapi untuk kueri hanya-baca, ini adalah CONNECT ANY DATABASEdan SELECT ALL USER SECURABLES).


Sinonim

Sebagian besar nama 3 dan 4 bagian mudah diidentifikasi, dan muncul dalam DMV. Namun jika Anda membuat sinonim yang menunjuk ke nama 3 atau 4 bagian, ini tidak muncul di DMV. Jadi, jika Anda banyak menggunakan sinonim, ada kemungkinan Anda akan kehilangan beberapa dependensi eksternal, dan ini dapat menyebabkan masalah pada titik di mana Anda memigrasi database ke server yang berbeda. Saya mengeluh tentang masalah ini, tetapi ditutup sebagai "oleh desain" dan tidak bertahan migrasi ke sistem umpan balik baru . Perhatikan bahwa DMV juga akan kehilangan nama 3 dan 4 bagian yang dibangun melalui SQL dinamis.


Kebijakan kata sandi

Jika Anda telah membuat pengguna basis data yang terkandung pada sistem tanpa kebijakan kata sandi, Anda mungkin merasa kesulitan untuk membuat pengguna yang sama pada sistem yang berbeda yang memang memiliki kebijakan kata sandi. Ini karena CREATE USERsintaksis tidak mendukung mem-bypass kebijakan kata sandi. Saya mengajukan bug tentang masalah ini, dan itu tetap terbuka (dan itu juga tidak bertahan bergerak ketika Connect sudah pensiun). Dan sepertinya aneh bagi saya bahwa pada sistem dengan kebijakan kata sandi di tempat, Anda dapat membuat login tingkat server yang dengan mudah melewati kebijakan, tetapi Anda tidak dapat membuat pengguna basis data yang melakukannya - meskipun pengguna ini secara inheren kurang dari risiko keamanan.


Pemeriksaan

Karena kita tidak bisa lagi mengandalkan susunan tempdb, Anda mungkin perlu mengubah kode apa pun yang saat ini menggunakan susunan eksplisit atau DATABASE_DEFAULTuntuk digunakan CATALOG_DEFAULTsebagai gantinya. Lihat artikel BOL ini untuk beberapa masalah potensial .


IntelliSense

Jika Anda terhubung ke database yang terkandung sebagai pengguna yang terkandung, SSMS tidak akan sepenuhnya mendukung IntelliSense. Anda akan mendapatkan garis bawah dasar untuk kesalahan sintaks, tetapi tidak ada daftar atau tooltip yang dilengkapi secara otomatis dan semua hal yang menyenangkan. Saya mengajukan bug tentang masalah ini, dan itu tetap terbuka - dan satu lagi yang tidak selamat dari langkah tersebut.


Alat Data SQL Server

Jika Anda berencana menggunakan SSDT untuk pengembangan basis data, saat ini tidak ada dukungan penuh untuk basis data yang terkandung. Yang benar-benar hanya berarti bahwa membangun proyek tidak akan gagal jika Anda menggunakan beberapa fitur atau sintaksis yang merusak kontainmen, karena SSDT saat ini tidak tahu apa kontainmen itu dan apa yang mungkin merusaknya.


Ubah DATABASE

Saat menjalankan ALTER DATABASEperintah dari dalam konteks basis data yang terkandung, lebih baik daripada ALTER DATABASE fooyang perlu Anda gunakan ALTER DATABASE CURRENT- ini adalah agar jika basis data dipindahkan, diganti nama, dll. Perintah ini tidak perlu tahu apa pun tentang konteks eksternal atau referensi mereka .


Beberapa lainnya

Beberapa hal yang mungkin tidak boleh Anda gunakan tetapi tetap harus disebutkan dalam daftar hal-hal yang tidak didukung atau sudah usang dan tidak boleh digunakan dalam database yang terkandung:

  • prosedur bernomor
  • prosedur sementara
  • perubahan susunan pada objek yang terikat
  • ubah pengambilan data
  • ubah pelacakan
  • replikasi

Karena itu, semua ini tidak selalu merugikan untuk menggunakan basis data yang terkandung, itu hanya masalah yang harus Anda ketahui dan tidak semuanya diungkapkan secara eksplisit dalam dokumentasi resmi.

Anda juga perlu memastikan bahwa jika basis data yang terkandung akan dimigrasi, atau merupakan bagian dari grup ketersediaan atau sedang dicerminkan, bahwa semua server tujuan potensial memiliki sp_configureopsi yang contained database authenticationdiatur ke 1.

Anda mungkin menemukan posting blog ini bermanfaat, juga yang ini , meskipun mereka RTM pra-tanggal.

Aaron Bertrand
sumber
Apakah Anda tahu mengapa prosedur sementara tidak diizinkan?
Jon Seigel
2
@JonSeigel mereka masih diizinkan di bawah pengurungan parsial, tetapi mereka melanggar penahanan (artinya tidak ada cara untuk memvalidasi entitas apa yang diakses oleh prosedur, karena metadata dan definisi disimpan di tempat lain) sehingga tidak disarankan. Dari msdn.microsoft.com/en-us/library/ff929071.aspx#Limitations : Prosedur tersimpan sementara saat ini diizinkan. Karena prosedur tersimpan sementara melanggar penahanan, mereka tidak diharapkan didukung dalam versi masa depan dari database yang terkandung.
Aaron Bertrand
9

Bagi mereka yang tertarik untuk mendapatkan rincian lebih lanjut tentang database yang terkandung, saya dapat merekomendasikan mereka untuk membaca artikel ini http://www.sqlshack.com/contained-databases-in-sql-server/

Artikel ini menunjukkan keuntungan / kerugian utama dari penggunaan basis data yang terkandung.

Kekurangan

Basis data yang sebagian terkandung tidak dapat menggunakan fitur seperti replikasi, mengubah pengambilan data, mengubah pelacakan, objek terikat skema yang bergantung pada fungsi bawaan dengan perubahan susunan.

Keuntungan

Di sisi lain, seperti yang telah disebutkan, ada beberapa manfaat menggunakan DB yang terkandung, seperti:

  • Sangat mudah untuk memindahkan database dari satu server ke server lain,
    karena tidak akan ada masalah pengguna yatim
  • Metadata disimpan pada basis data yang terkandung sehingga lebih mudah dan lebih portabel
  • Dimungkinkan untuk memiliki otentikasi SQL Server dan Windows untuk pengguna DB yang terkandung

Artikel juga membantu:

  • membuat database berisi yang baru (dengan membuat tipe penahanan sebagai Bagian di halaman Opsi di SQL Server, dan menggunakan kueri T-SQL untuk membuat database setelahnya)
  • menghubungkan ke DB yang terkandung menggunakan SQL Server Management Studio (perlu untuk menentukan nama DB yang terkandung dalam parameter koneksi)
  • mengubah database yang ada menjadi database yang ada
  • bekerja pada database yang terkandung dan mendaftar semua login yang termasuk tipe pengguna yang terkandung
Alex Kirilov
sumber
4

Salah satu kelemahannya adalah bahwa pengguna basis data yang terkandung tidak dapat dipaksa untuk mengubah kata sandi mereka sendiri seperti yang dapat login ( MUST_CHANGE). Pengguna tidak dapat mengelola kata sandi mereka sendiri kecuali Anda memberi mereka izin pengguna lain dan memberi tahu mereka cara mengubahnya menggunakan pernyataan SQL. Tidak ada tempat yang mudah bagi mereka untuk mengelolanya melalui antarmuka pengguna atau setidaknya saya tidak tahu caranya.

Catatan tambahan adalah bahwa, saya menemukan penggunaan metadata yang tidak terduga dan tidak berdokumen di klausa "PIVOT" DAN "UNPIVOT" yang saya pikir seharusnya hanya di katalog sistem saja (sys.tables / sys.columns / etc). Seperti yang didokumentasikan dalam msdn :

Dalam database yang terkandung, koleksi katalog Latin1_General_100_CI_AS_WS_KS_SC . Susunan ini adalah sama untuk semua database yang ada di semua contoh SQL Server dan tidak dapat diubah.

Tetapi mereka tidak menyebutkan bahwa klausa "PIVOT" DAN "UNPIVOT" juga menggunakan katalog sistem sebagai mekanisme eksekusi. sehingga menghasilkan galat yang bertentangan benturan di mana saja di dekat penggunaan klausa "PIVOT" DAN "UNPIVOT" selama migrasi. berikut adalah beberapa 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

Anda juga dapat melihat bahwa artikel tentang database yang ada sebagian besar tidak lengkap. jadi memutuskan untuk menggunakannya membutuhkan improvisasi yang sangat bagus.

Paul.K
sumber