มีข้อเสียสำหรับฐานข้อมูลที่มีอยู่หรือไม่?


33

SQL Server 2012 นำเสนอแนวคิดของฐานข้อมูล "ที่มีอยู่" ซึ่งทุกอย่าง (ส่วนใหญ่ทุกอย่าง) ความต้องการของฐานข้อมูลนั้นมีอยู่ภายในฐานข้อมูลนั้นเอง สิ่งนี้มีข้อได้เปรียบที่ยิ่งใหญ่เมื่อย้ายฐานข้อมูลระหว่างเซิร์ฟเวอร์ ฉันอยากรู้ว่าถ้านี่เป็นกลยุทธ์เริ่มต้นของฉันเมื่อออกแบบฐานข้อมูลใหม่

MSDN แสดงข้อเสียหลายประการสำหรับฐานข้อมูลที่มีอยู่และสิ่งที่สำคัญคือขาดการสนับสนุนสำหรับการติดตามการเปลี่ยนแปลงและการจำลองแบบ มีคนอื่นไหม? ถ้าฉันจะไม่ใช้คุณสมบัติเหล่านี้มีเหตุผลใดที่จะไม่ใช้ฐานข้อมูลที่มีอยู่หรือไม่

คำตอบ:


33

วัตถุประสงค์หลักของฐานข้อมูลที่มีอยู่คือเพื่อให้ง่ายต่อการย้ายฐานข้อมูลของคุณไปยังเซิร์ฟเวอร์ใหม่โดยไม่ต้องนั่งร้านอยู่รอบ ๆ โดยที่ในใจฉันจะจัดการกับปัญหาที่อาจเกิดขึ้นเล็กน้อยซึ่งจะทำให้การโยกย้ายนี้ยากขึ้น - และส่วนใหญ่หมุนรอบข้อเท็จจริงที่ว่าฐานข้อมูลที่มีอยู่นั้นมีอยู่เพียงบางส่วนใน SQL Server 2012 (การบังคับใช้การกักกันไม่ได้บังคับจริง)


สตริงการเชื่อมต่อ

สตริงการเชื่อมต่อกับฐานข้อมูลที่มีอยู่จะต้องระบุฐานข้อมูลในสตริงการเชื่อมต่ออย่างชัดเจน คุณไม่สามารถพึ่งพาฐานข้อมูลเริ่มต้นของล็อกอินเพื่อสร้างการเชื่อมต่อได้อีกต่อไป หากคุณไม่ได้ระบุฐานข้อมูล SQL Server จะไม่ดำเนินการผ่านฐานข้อมูลที่มีอยู่ทั้งหมดและลองค้นหาฐานข้อมูลใด ๆ ที่ข้อมูลรับรองของคุณอาจตรงกัน


แบบสอบถามข้ามฐานข้อมูล

แม้ว่าคุณจะสร้างผู้ใช้เดียวกันด้วยรหัสผ่านเดียวกันในฐานข้อมูลที่มีอยู่สองแห่งบนเซิร์ฟเวอร์เดียวกันแอพพลิเคชันของคุณจะไม่สามารถทำการสืบค้นข้ามฐานข้อมูลได้ ชื่อผู้ใช้และรหัสผ่านอาจเหมือนกัน แต่ไม่ใช่ชื่อผู้ใช้เดียวกัน เหตุผลนี้ หากคุณมีฐานข้อมูลบนเซิร์ฟเวอร์ที่โฮสต์คุณไม่ควรป้องกันไม่ให้มีผู้ใช้ที่มีอยู่เดิมกับบุคคลอื่นที่ใช้เซิร์ฟเวอร์โฮสต์เดียวกัน เมื่อมาถึงการบรรจุเต็มรูปแบบ (น่าจะเป็นในรุ่นหลังจาก SQL Server 2012 ไม่เคย) การสืบค้นข้ามฐานข้อมูลจะถูกห้ามอย่างเด็ดขาด ฉันขอแนะนำอย่างยิ่งว่าคุณไม่ควรสร้างการเข้าสู่ระบบในระดับเซิร์ฟเวอร์ด้วยชื่อเดียวกับผู้ใช้ฐานข้อมูลที่มีอยู่และพยายามหลีกเลี่ยงการสร้างชื่อผู้ใช้ที่มีอยู่เดิมในฐานข้อมูลที่มีอยู่ หากคุณต้องการเรียกใช้แบบสอบถามที่มีฐานข้อมูลที่มีอยู่หลายแห่งให้ทำเช่นนั้นโดยใช้การเข้าสู่ระบบระดับเซิร์ฟเวอร์ที่มีสิทธิ์ที่เหมาะสม (คุณอาจคิดว่านี่เป็นsysadminแต่สำหรับแบบสอบถามแบบอ่านอย่างเดียวนี่คือCONNECT ANY DATABASEและSELECT ALL USER SECURABLES)


ชื่อพ้อง

ชื่อ 3- และ 4 ส่วนส่วนใหญ่สามารถระบุได้ง่ายและปรากฏใน DMV อย่างไรก็ตามหากคุณสร้างคำพ้องความหมายที่ชี้ไปที่ชื่อ 3 หรือ 4 ส่วนสิ่งเหล่านี้จะไม่ปรากฏใน DMV ดังนั้นหากคุณใช้คำพ้องความหมายอย่างหนักคุณอาจพลาดการพึ่งพาจากภายนอกและอาจทำให้เกิดปัญหา ณ จุดที่คุณย้ายฐานข้อมูลไปยังเซิร์ฟเวอร์อื่น ฉันบ่นเกี่ยวกับปัญหานี้ แต่มันจะถูกปิดเป็น "โดยการออกแบบ"และไม่ได้อยู่รอดการโยกย้ายไปยังระบบการตอบใหม่ โปรดทราบว่า DMV จะพลาดชื่อ 3 และ 4 ส่วนที่สร้างผ่าน SQL แบบไดนามิก


นโยบายรหัสผ่าน

หากคุณสร้างผู้ใช้ฐานข้อมูลที่มีอยู่บนระบบที่ไม่มีนโยบายรหัสผ่านคุณอาจพบว่าเป็นการยากที่จะสร้างผู้ใช้รายเดียวกันบนระบบอื่นที่มีนโยบายรหัสผ่านอยู่ นี่เป็นเพราะCREATE USERไวยากรณ์ไม่สนับสนุนการข้ามนโยบายรหัสผ่าน ฉันยื่นข้อผิดพลาดเกี่ยวกับปัญหานี้และยังคงเปิดอยู่ (และยังไม่รอดจากการย้ายเมื่อเชื่อมต่อถูกยกเลิก) และดูเหมือนว่าสำหรับฉันแล้วในระบบที่มีนโยบายรหัสผ่านคุณสามารถสร้างการเข้าสู่ระบบระดับเซิร์ฟเวอร์ที่ข้ามนโยบายได้อย่างง่ายดาย แต่คุณไม่สามารถสร้างผู้ใช้ฐานข้อมูลที่ทำเช่นนั้น - แม้ว่าผู้ใช้รายนี้จะเป็นผู้สืบทอด น้อยกว่าความเสี่ยงด้านความปลอดภัย


การตรวจทาน

เนื่องจากเราไม่สามารถพึ่งพาการจัดเรียงของ tempdb ได้อีกต่อไปคุณอาจต้องเปลี่ยนรหัสใด ๆ ที่ใช้การเปรียบเทียบที่ชัดเจนหรือDATABASE_DEFAULTใช้CATALOG_DEFAULTแทน ดูบทความ BOL นี้สำหรับประเด็นที่มีศักยภาพบางอย่าง


IntelliSense

หากคุณเชื่อมต่อกับฐานข้อมูลที่มีอยู่ในฐานะผู้ใช้ที่มีอยู่ SSMS จะไม่สนับสนุน IntelliSense อย่างสมบูรณ์ คุณจะได้รับการขีดเส้นใต้พื้นฐานสำหรับข้อผิดพลาดทางไวยากรณ์ แต่ไม่มีรายการหรือคำแนะนำเครื่องมืออัตโนมัติและรายการสนุก ๆ ทั้งหมด ฉันยื่นข้อผิดพลาดเกี่ยวกับปัญหานี้และยังคงเปิดอยู่ - และอีกหนึ่งเรื่องที่ไม่รอดจากการย้าย


เครื่องมือ SQL Server Data

หากคุณวางแผนที่จะใช้ SSDT สำหรับการพัฒนาฐานข้อมูลปัจจุบันยังไม่มีการสนับสนุนอย่างเต็มที่สำหรับฐานข้อมูลที่มีอยู่ ซึ่งหมายความว่าการสร้างโครงการจะไม่ล้มเหลวหากคุณใช้คุณลักษณะหรือไวยากรณ์ที่แบ่งการบรรจุเนื่องจาก SSDT ในปัจจุบันไม่ทราบว่าการบรรจุคืออะไรและสิ่งใดที่อาจทำลายได้


แก้ไขฐานข้อมูล

เมื่อรันALTER DATABASEคำสั่งจากภายในบริบทของฐานข้อมูลที่มีอยู่ rRather กว่าที่ALTER DATABASE fooคุณจะต้องใช้ALTER DATABASE CURRENT- นี่คือเพื่อที่ว่าถ้าฐานข้อมูลถูกย้ายเปลี่ยนชื่อ ฯลฯ คำสั่งเหล่านี้ไม่จำเป็นต้องรู้อะไรเกี่ยวกับบริบทภายนอกหรือการอ้างอิงของพวกเขา .


อีกไม่กี่คน

บางสิ่งที่คุณอาจไม่ควรใช้ แต่ถึงกระนั้นก็ควรพูดถึงในรายการสิ่งที่ไม่สนับสนุนหรือเลิกใช้แล้วและไม่ควรใช้ในฐานข้อมูลที่มีอยู่:

  • ขั้นตอนการกำหนดหมายเลข
  • ขั้นตอนชั่วคราว
  • การเปลี่ยนแปลงการเรียงในวัตถุที่ถูกผูกไว้
  • เปลี่ยนการดักจับข้อมูล
  • ติดตามการเปลี่ยนแปลง
  • การทำซ้ำ

ทุกคนกล่าวว่าสิ่งเหล่านี้ไม่ได้เป็นข้อเสียเปรียบในการใช้ฐานข้อมูลที่มีอยู่พวกเขาเป็นเพียงปัญหาที่คุณควรระวังและไม่ได้เปิดเผยอย่างชัดเจนในเอกสารอย่างเป็นทางการ

คุณจะต้องตรวจสอบให้แน่ใจว่าหากฐานข้อมูลที่มีอยู่กำลังจะถูกโยกย้ายหรือเป็นส่วนหนึ่งของกลุ่มความพร้อมใช้งานหรือกำลังทำมิรเรอร์เซิร์ฟเวอร์ปลายทางที่เป็นไปได้ทั้งหมดจะมีsp_configureตัวเลือกที่contained database authenticationกำหนดเป็น 1

คุณอาจพบว่าการโพสต์บล็อกนี้มีประโยชน์เช่นเดียวกับโพสต์นี้ถึงแม้ว่าพวกเขาจะอัปเดต RTM ล่วงหน้า


คุณรู้หรือไม่ว่าทำไมขั้นตอนชั่วคราวจึงไม่ได้รับอนุญาต
Jon Seigel

2
@JonSeigel พวกเขายังคงได้รับอนุญาตภายใต้การบรรจุบางส่วน แต่พวกเขาละเมิดการกักกัน (หมายถึงไม่มีทางที่จะตรวจสอบสิ่งที่กระบวนการเข้าถึงเอนทิตีเนื่องจากเมตาดาต้าและความหมายจะถูกเก็บไว้ที่อื่น) จึงไม่แนะนำ จากmsdn.microsoft.com/en-us/library/ff929071.aspx#Limitations : ปัจจุบันอนุญาตให้มีการจัดเก็บชั่วคราว เนื่องจากกระบวนงานที่เก็บไว้ชั่วคราวละเมิดการกักกันจึงไม่คาดว่าจะได้รับการสนับสนุนในเวอร์ชันฐานข้อมูลที่มีอยู่ในอนาคต
Aaron Bertrand

9

สำหรับผู้ที่สนใจรับรายละเอียดเพิ่มเติมเกี่ยวกับฐานข้อมูลที่มีอยู่ฉันสามารถแนะนำให้อ่านบทความนี้ได้ที่http://www.sqlshack.com/contained-databases-in-sql-server/

บทความระบุข้อดี / ข้อเสียหลักของการใช้ฐานข้อมูลที่มีอยู่

ข้อเสีย

ฐานข้อมูลที่มีอยู่บางส่วนไม่สามารถใช้คุณสมบัติเช่นการจำลองข้อมูลเปลี่ยนการจับข้อมูลการติดตามการเปลี่ยนแปลงวัตถุที่ถูกผูกไว้กับสกีมาที่ขึ้นอยู่กับฟังก์ชั่นในตัวที่มีการเปลี่ยนแปลงการเปรียบเทียบ

ข้อดี

ในทางกลับกันตามที่กล่าวไว้แล้วมีประโยชน์บางอย่างของการใช้ฐานข้อมูลที่มีอยู่เช่น:

  • ค่อนข้างง่ายในการย้ายฐานข้อมูลจากเซิร์ฟเวอร์หนึ่งไปยังเซิร์ฟเวอร์อื่น
    เนื่องจากจะไม่มีปัญหาผู้ใช้กำพร้า
  • ข้อมูลเมตาจะถูกจัดเก็บในฐานข้อมูลที่มีอยู่เพื่อให้ง่ายและพกพาได้มากขึ้น
  • เป็นไปได้ที่จะมีทั้ง SQL Server และ Windows authentication สำหรับผู้ใช้ DB ที่มีอยู่

บทความนี้ยังช่วยด้วย:

  • การสร้างฐานข้อมูลที่มีอยู่ใหม่ (โดยทำให้ประเภทการบรรจุเป็นบางส่วนในหน้าตัวเลือกใน SQL Server และการใช้แบบสอบถาม T-SQL เพื่อสร้างฐานข้อมูลในภายหลัง)
  • การเชื่อมต่อกับฐานข้อมูลที่มีอยู่โดยใช้ SQL Server Management Studio (จำเป็นต้องระบุชื่อฐานข้อมูลที่มีอยู่ในพารามิเตอร์การเชื่อมต่อ)
  • การแปลงฐานข้อมูลที่มีอยู่เป็นฐานข้อมูลที่มีอยู่
  • ทำงานกับฐานข้อมูลที่มีอยู่และแสดงรายการการเข้าสู่ระบบทั้งหมดที่เป็นประเภทผู้ใช้ที่มีอยู่

4

ข้อเสียอย่างหนึ่งคือผู้ใช้ฐานข้อมูลที่มีอยู่ไม่สามารถบังคับให้เปลี่ยนรหัสผ่านของตนเองได้เช่นเดียวกับการเข้าสู่ระบบ ( MUST_CHANGE) ผู้ใช้ไม่สามารถจัดการรหัสผ่านของตนเองได้เว้นแต่คุณจะให้สิทธิ์ผู้ใช้ในการเปลี่ยนแปลงและแจ้งให้พวกเขาทราบถึงวิธีการเปลี่ยนแปลงโดยใช้คำสั่ง SQL ไม่มีที่ไหนง่ายสำหรับพวกเขาที่จะจัดการผ่านส่วนต่อประสานผู้ใช้หรืออย่างน้อยก็ไม่รู้

หมายเหตุเพิ่มเติมคือฉันพบการใช้ข้อมูลเมตาที่ไม่คาดคิดและไม่มีเอกสารในประโยค "PIVOT" และ "UNPIVOT" ซึ่งฉันคิดว่าควรอยู่ในแค็ตตาล็อกของระบบเท่านั้น (sys.tables / sys.columns / etc) ตามที่บันทึกไว้ในmsdn :

ในฐานข้อมูลที่มีอยู่ในแคตตาล็อกเปรียบเทียบLatin1_General_100_CI_AS_WS_KS_SC การเปรียบเทียบนี้จะเหมือนกันสำหรับฐานข้อมูลที่มีอยู่ทั้งหมดในอินสแตนซ์ทั้งหมดของ SQL Server และไม่สามารถเปลี่ยนแปลงได้

แต่พวกเขาไม่ได้กล่าวว่าประโยค "PIVOT" และ "UNPIVOT" ใช้แคตตาล็อกระบบเป็นกลไกในการดำเนินการ ดังนั้นจึงสร้างข้อผิดพลาดการเปรียบเทียบที่ขัดแย้งกันทุกที่ใกล้กับการใช้ประโยค "PIVOT" และ "UNPIVOT" ระหว่างการย้ายข้อมูล นี่คือการทำสำเนาบางส่วน:

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

คุณจะเห็นว่าบทความเกี่ยวกับฐานข้อมูลที่มีอยู่นั้นส่วนใหญ่ไม่สมบูรณ์ ดังนั้นการตัดสินใจที่จะใช้มันต้องมีการปรับตัวที่ดีมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.