ตกลงมาทำลายมันกัน:
- ตัวเชื่อมถูกสร้างขึ้นระหว่างสองตารางในหลายฐานข้อมูลอย่างไร (ตัวอย่างรหัสที่นี่จะเป็นประโยชน์)
ตรงนี้ค่อนข้างตรงไปตรงมา วัตถุ SQL มีที่ใดก็ได้จากแบบแผนการตั้งชื่อส่วนหนึ่งถึงสี่:
Servername.databasename.schemaname.tablename
หากตารางทั้งหมดของคุณอยู่บนเซิร์ฟเวอร์เดียวกันบนฐานข้อมูลเดียวกันโดยมีเจ้าของ / สคีมาเหมือนกันคุณสามารถละเว้นสามส่วนแรกและใช้สิ่งที่คุณคุ้นเคยมากที่สุดในการ:
Select a.*,b.* from
tableA a inner join
tableB b on a.col1=b.col1
หากหนึ่งในตารางของคุณอยู่ในฐานข้อมูลอื่นและทั้งคู่ใช้สคีมาเริ่มต้นสำหรับฐานข้อมูลของคุณคุณเพียงเพิ่มฐานข้อมูลลงในตารางที่สอง:
Select a.*,b.* from
tableA a inner join
databaseC..tableB b on a.col1 = b.col1
หากคุณอยู่ในฐานข้อมูลที่สามแตกต่างจากอย่างใดอย่างหนึ่งที่คุณกำลังสอบถามคุณใช้ชื่อฐานข้อมูลทั้งสองอย่างชัดเจน:
Select a.*,b.* from
databaseD..tableA a inner join
databaseC..tableB b on a.col1 = b.col1
หากคุณใช้ schema และ / หรือเจ้าของอื่น ๆ คุณสามารถเพิ่มสิ่งเหล่านี้ใน:
Select a.*,b.* from
databaseD.john.tableA a inner join
databaseC.accounting.tableB b on a.col1 = b.col1
และสุดท้ายถ้าคุณระมัดระวังมากและมีเหตุผลที่ดีมากคุณสามารถเข้าร่วมตาราง (มักจะเล็ก) บนเซิร์ฟเวอร์อื่น:
Select a.* from
databaseD.john.TableA a inner join
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
- เวลาที่จะย้ายเกินกว่าการตั้งค่าเซิร์ฟเวอร์ 1 / ฐานข้อมูล 1? การทำเช่นนี้ต้องทำกันมากแค่ไหน? มีกลยุทธ์พิเศษสำหรับการติดตามตารางใดในฐานข้อมูลใดบ้าง
ฉันจะรวมสองอันนี้เข้าด้วยกัน โดยทั่วไปคุณเกือบจะเริ่มต้นด้วยการสันนิษฐานว่าฐานข้อมูลเดียวหนึ่งเซิร์ฟเวอร์ก็เพียงพอแล้วจนกระทั่งข้อ จำกัด ด้านการออกแบบ / ธุรกิจ / ทางเทคนิคบังคับให้คุณใช้งานมากขึ้น
ดังนั้นเพื่อตอบคำถามที่สองของคุณก่อนเนื่องจากคุณมีเหตุผลในการมีฐานข้อมูลแยกต่างหากมันควรจะค่อนข้างชัดเจนจากการรู้การออกแบบระบบของคุณว่ามีอะไรอยู่บ้าง
ว่าเมื่อใด / เพราะเหตุใดจึงต้องย้ายเกินฐานข้อมูลเดียว โดยปกติแล้วเป็นการผสมผสานระหว่างกฎเกณฑ์ทางธุรกิจการเมืองและ / หรือเหตุผลทางเทคนิค
ตัวอย่างเช่นที่ทำงานฉันมีฐานข้อมูล 16 แห่งกระจายอยู่ทั่วเซิร์ฟเวอร์ 4 แห่ง เรามี MainDB, ImageDB, ReferencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB ในการให้ตัวอย่างว่าทำไมพวกเขาถึงแตกต่าง:
- FinancialDB ข้อมูลที่ละเอียดอ่อน
- Image DB, ข้อกำหนดหน่วยเก็บข้อมูลและการกู้คืนที่แตกต่างกันโดยเฉพาะ
- ReferenceDB ธุรกรรมต่ำอ่านสูง
- ReportingDB ต้องอ่านสูงมากต้องถูกเรียกคืน / ทำซ้ำไปยังสภาพแวดล้อมอื่น ๆ ซึ่งแตกต่างจากข้อมูลอื่น ๆ มากมาย
- StagingDB ไม่มีอะไรถาวรเพียงแค่เพิ่มอุณหภูมิ tempdb ที่เราสามารถควบคุมได้มากขึ้น
- MainDB อินเทอร์เฟซกับ DBs อื่น ๆ ทั้งหมด แต่ต้องการการสำรองข้อมูลที่แตกต่างดังนั้น ... เราจึงแยกออก
- ตาราง HighVolumeTransaction (ซึ่งค่อนข้างชั่วคราว) ไปยังฐานข้อมูลของตนเองเพื่อรักษาขนาดการสำรองข้อมูลที่เหมาะสม
- เก็บถาวรข้อมูลเดียวกันจำนวนมากจากหน้าหลักและการรายงาน แต่ด้วยระยะเวลาการเก็บรักษาที่ยาวนานขึ้นและการสืบค้นที่ยากขึ้นจะส่งผลให้ข้อมูลลึก หากสิ่งนี้ยังคงถูกรวมเข้ากับหลัก / การรายงานมันจะทำให้ระบบของเราชะงัก
• รหัสแอปพลิเคชันจำเป็นต้องรู้หรือไม่ว่าฐานข้อมูลอย่างน้อยหนึ่งฐานข้อมูลกระจายอยู่ในหลาย ๆ เซิร์ฟเวอร์ หากไม่ได้รับการกรองคำขอในระดับใด
ในแง่กว้างพวกเขาอาจทำ อย่างน้อยพวกเขาจำเป็นต้องรู้ว่าเซิร์ฟเวอร์ใดที่พวกเขากำลังชี้ไปที่สตริงการเชื่อมต่อฐานข้อมูล การประมวลผลการรายงานหลัก ฯลฯ
จากนั้นพวกเขาต้องการบริบทฐานข้อมูลเพื่อดำเนินการภายใต้ โดยทั่วไปแล้วจะเป็นแอพพลิเคชั่นที่มีการใช้งานมากที่สุดอาจจะเป็นแอพพลิเคชั่นที่ใช้บ่อยที่สุดจากฐานข้อมูลหนึ่ง / เซิร์ฟเวอร์หนึ่งวันของแอปพลิเคชัน คุณสามารถให้แอปพลิเคชันสลับบริบทฐานข้อมูลอย่างชัดเจนในทุกการโทร แต่นั่นทำให้ยากที่จะปรับฐานข้อมูลโดยไม่ต้องเปลี่ยนแอป
วิธีปกติ (หรืออย่างน้อยที่สุดปกติของฉัน) วิธีการคือเข้าถึงฐานข้อมูลหลักหนึ่งหรือสองฐานเสมอ
จากนั้นสร้างมุมมองลงในฐานข้อมูลอื่น ๆ ตามความจำเป็นรวมกับการเชื่อมต่อกับฐานข้อมูลผ่านขั้นตอนการจัดเก็บ
ดังนั้นเพื่ออธิบาย:
สมมติว่าคุณต้องการได้รับข้อมูลประชากรของลูกค้าข้อมูลการขายและเครดิตบาลานซ์และกระจายไปทั่วทั้งสามตารางใน MainDB
ดังนั้นคุณจึงโทรออกจากแอพของคุณ:
Select c.ClientName, c.ClientAddress, s.totalSales,f.CreditBlance from
Clients c join Sales s on c.clientid = s.clientid inner join AccountReceivable f on
c.clientid=f.clientid where c.clientid = @clientid
น่ากลัว อย่างไรก็ตามตอนนี้เมื่อใดก็ตามที่เราเปลี่ยนชื่อคอลัมน์หรือเปลี่ยนชื่อ / ย้ายตารางคุณต้องอัปเดตรหัสแอป ดังนั้นแทนที่จะทำสองสิ่ง:
สร้างลูกค้าการขายมุมมอง AccountReceivables (คุณจะไม่ใช้ Select * แต่ฉันกำลังสาธิตที่นี่)
Use MainDB
GO
Create view v_Clients as select * from Clients
Create view v_Sales as select * from Sales
Create view v_AccountReceivable as select * from AccountReceivable
Go
จากนั้นเราจะสร้างโพรซีเดอร์ที่เก็บไว้ spGetClientSalesAR
Create proc spGetClientSalesAR @clientID int
as
Select c.ClientName as ClientName,
c.ClientAddress as ClientAddress,
s.totalSales as TotalSales,
f.CreditBlance as CreditBalance
from
v_Clients c join v_Sales s
on c.clientid = s.clientid
inner join v_AccountReceivable f
on c.clientid=f.clientid
where c.clientid = @clientid
และให้แอพของคุณเรียกว่า
ตราบใดที่ฉันไม่ได้เปลี่ยนอินเทอร์เฟซบน proc ที่เก็บไว้ฉันสามารถทำอะไรก็ได้ที่ฉันต้องทำกับฐานข้อมูลส่วนหลังเพื่อขยายหรือย่อขนาด
ในที่สุดฉันก็สามารถทำให้ MainDB เก่าของฉันเป็นเพียงแค่กระบวนการเก็บและมุมมองที่เก็บไว้แบบ shelled ซึ่งภายใต้มุมมองเหล่านั้นที่เราสร้างขึ้นดูเหมือนว่า:
Create view v_Clients as select * from ServerX.DatabaseY.dbo.Clients
Create view v_Sales as select * from ServerQ.DatabaseP.dbo.Sales
Create view v_AccountReceivable as select * from ServerJ.DatabaseK.dbo.AccountReceivable
และแอปของคุณจะไม่มีทางรู้ถึงความแตกต่าง (สมมติว่ามีท่อที่รวดเร็วและมีการจัดเตรียมข้อมูลที่ดีในหมู่สิ่งอื่น ๆ )
เห็นได้ชัดว่ามันสุดขั้วและฉันจะโกหกถ้าฉันบอกว่าทุกอย่างถูกวางแผนด้วยวิธีนี้ แต่การใช้ขั้นตอน / มุมมองที่เก็บไว้แม้ว่าคุณจะทำในขณะที่การสร้างใหม่จะช่วยให้คุณมีความยืดหยุ่นมากขึ้น จุดเริ่มต้น