ระบบหลายผู้เช่าที่ควรใช้ SQL Server 2016, Shard หรือแยกผู้เช่าผ่านฐานข้อมูลแยกต่างหากต่อผู้เช่าหรือไม่?


12

รับกรณีการใช้งาน:

  • ข้อมูลผู้เช่าไม่ควรพูดคุยข้าม, ผู้เช่ารายหนึ่งไม่ต้องการข้อมูลของผู้เช่ารายอื่น
  • ผู้เช่าแต่ละรายอาจมีปริมาณข้อมูลประวัติขนาดใหญ่ได้
  • SQL Server โฮสต์อยู่ในอินสแตนซ์ของ AWS EC2
  • ผู้เช่าแต่ละรายอยู่ห่างจากพื้นที่ทางภูมิศาสตร์
  • มีความตั้งใจที่จะใช้เครื่องมือสร้างภาพข้อมูลบุคคลที่สามเช่น PowerBI Embedded
  • คาดว่าปริมาณข้อมูลจะเพิ่มขึ้นเมื่อเวลาผ่านไป
  • ค่าใช้จ่ายของระบบถูก จำกัด
  • การแก้ปัญหาจะต้องสามารถบำรุงรักษาได้โดยไม่ต้องมี DBA ผลิต 24/7
  • การแก้ปัญหาควรจะสามารถปรับขนาดในแนวนอน
  • จำนวนผู้เช่าทั้งหมดน้อยกว่า 50

สิ่งที่จะเป็นสถาปัตยกรรมที่แนะนำมีการใช้งานอ้างอิงสำหรับกรณีการใช้งานนี้หรือไม่? ฉันเชื่อว่าหลายคนอาจประสบปัญหานี้แล้วสำหรับการพัฒนาซอฟต์แวร์ระดับองค์กร

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

คำตอบ:


16

gotcha ที่มีการแบ่งส่วนคือแอปพลิเคชันต้องทราบว่าจะต้องใช้การค้นหาส่วนใด โดยทั่วไปจะทำโดย sharding ในบางสิ่งบางอย่างเช่นลูกค้า ฉันจะปรับหนึ่งในบล็อกโพสต์เก่าของฉันเพื่อใช้เป็นคำตอบของฉัน

เมื่อคุณสร้างแอปพลิเคชันสำหรับลูกค้าจำนวนมากมีวิธีการทั่วไปสองวิธีในการออกแบบฐานข้อมูล:

  • ตัวเลือก A: ใส่ลูกค้าทั้งหมดในฐานข้อมูลเดียวกัน
  • ตัวเลือก 2: สร้างฐานข้อมูลหนึ่งต่อลูกค้า

ทำให้ลูกค้าทั้งหมดในฐานข้อมูลเดียวกัน

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

ประโยชน์ของวิธีนี้:

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

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

สร้าง API ภายนอกได้ง่ายขึ้น หากเราต้องการให้สิทธิ์การเข้าถึงฐานข้อมูลทั้งหมดของเราเพื่อให้บุคคลภายนอกสร้างผลิตภัณฑ์เราสามารถทำได้ง่ายขึ้นหากข้อมูลทั้งหมดอยู่ในฐานข้อมูลเดียว หาก API ต้องจัดการกับการจัดกลุ่มข้อมูลจากหลายฐานข้อมูลบนเซิร์ฟเวอร์หลายตัวมันจะเพิ่มเวลาในการพัฒนาและทดสอบ (ในทางตรงกันข้ามสิ่งที่“ เซิร์ฟเวอร์หลายตัว” เริ่มบ่งบอกถึงข้อ จำกัด สำหรับสถานการณ์แบบหนึ่งฐานข้อมูลต่อกฎ - พวกเขาทั้งหมด: ฐานข้อมูลหนึ่งมักจะหมายถึงภาระของเราทั้งหมดส่งผลกระทบต่อเซิร์ฟเวอร์ฐานข้อมูลเดียว) ในกรณีของคุณ ด้วย PowerBI การมีทุกคนในฐานข้อมูลเดียวจะทำให้การจัดการการเชื่อมต่อง่ายขึ้นมาก

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

การทำให้ลูกค้าแต่ละรายอยู่ในฐานข้อมูลของตัวเองหรือของตัวเอง

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

ประโยชน์ของวิธีนี้:

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

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

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

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

การจัดการความปลอดภัยที่ง่ายขึ้น ตราบใดที่เราได้ปิดการรักษาความปลอดภัยอย่างถูกต้องกับผู้ใช้หนึ่งคนต่อฐานข้อมูลเราไม่ต้องกังวลกับการที่ Client X เข้าถึงข้อมูลของ Client Y อย่างไรก็ตามหากเราเพียงแค่ใช้การเข้าสู่ระบบเพียงครั้งเดียวสำหรับทุกคนแล้วเรายังไม่ได้แก้ไขข้อกังวลนี้

หน้าต่างบำรุงรักษาง่ายขึ้น ในสภาพแวดล้อมระดับโลกที่ลูกค้ากระจัดกระจายไปทั่วโลกมันง่ายกว่าที่ลูกค้าจะซ่อมบำรุงออฟไลน์ถ้าเราสามารถทำได้ในกลุ่มหรือโซน

อันไหนที่เหมาะกับคุณ

ไม่มีทางเลือกที่ถูกต้องคุณต้องรู้จักจุดแข็งและจุดอ่อนของ บริษัท ของคุณเอง ลองมาดูตัวอย่างลูกค้าของฉันสองคน

บริษัท A มีความสามารถในการปรับแต่งประสิทธิภาพของฮาร์ดแวร์ พวกเขาเก่งจริง ๆ ในการบีบฮาร์ดแวร์ประสิทธิภาพออกมาและพวกเขาก็ไม่รังเกียจที่จะเปลี่ยนฮาร์ดแวร์ SQL Server ของพวกเขาในรอบ 12-18 เดือน (พวกเขารีเฟรชเว็บเซิร์ฟเวอร์ทุก ๆ 4-6 เดือน!) จุดอ่อนของพวกเขาคือการปฏิบัติตามข้อกำหนดและความปลอดภัย พวกเขามีความต้องการการตรวจสอบที่ไม่น่าเชื่อและมันง่ายกว่าสำหรับพวกเขาที่จะใช้การควบคุมแบบกันกระสุนบนเซิร์ฟเวอร์เดียวฐานข้อมูลเดียวมากกว่าที่จะจัดการความต้องการเหล่านั้นในฐานข้อมูลนับพันบนเซิร์ฟเวอร์หลายสิบแห่ง พวกเขาเลือกหนึ่งฐานข้อมูลหนึ่งเซิร์ฟเวอร์ลูกค้าจำนวนมาก

บริษัท 2 มีความเชี่ยวชาญในการพัฒนา การจัดการการเปลี่ยนแปลงสคีมาและการใช้รหัสในฐานข้อมูลนับพันนั้นไม่ใช่ปัญหาสำหรับพวกเขา พวกเขามีลูกค้าทั่วโลกและพวกเขากำลังประมวลผลธุรกรรมบัตรเครดิตสำหรับลูกค้าเหล่านั้นตลอดเวลา พวกเขาต้องการความสามารถในการกระจายโหลดทางภูมิศาสตร์และพวกเขาไม่ต้องการแทนที่เซิร์ฟเวอร์ทั่วโลกทุก ๆ 12-18 เดือน พวกเขาเลือกฐานข้อมูลหนึ่งฐานสำหรับลูกค้าแต่ละรายและจะชำระเงินเมื่อพวกเขาเริ่มวางเซิร์ฟเวอร์ SQL ในเอเชียและยุโรปสำหรับลูกค้าในต่างประเทศ


"ในกรณีของคุณกับ PowerBI การมีทุกคนในฐานข้อมูลเดียวจะทำให้การจัดการการเชื่อมต่อง่ายขึ้น" ตอนนี้ PowerBI สมองกลฝังตัวไม่มีความปลอดภัยระดับแถวและการมีผู้เช่าทุกคนในฐานข้อมูลหนึ่งทำให้เกิดข้อสงสัยเกี่ยวกับกรณีการใช้งานนี้ดู: community.powerbi.com/t5/Developer/ ...... ในแง่ของข้อมูลนี้คุณสามารถกรุณาใช้ถ้อยคำใหม่ หรือแนะนำทางเลือกอื่นหรือแก้ไขความเข้าใจของฉัน
DS

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

ฉันแค่จะบอกว่าการปรับใช้กับฐานข้อมูลมากกว่าหนึ่งฐานนั้นไม่ได้แย่อย่างที่คุณทำ ในปี 2560 เรามีตัวเลือกมากมายที่ทำให้ง่ายต่อการปรับใช้การเปลี่ยนแปลงกับฐานข้อมูล 1, 5 หรือ 900 และเมื่อคุณมีข้อยกเว้นสำหรับลูกค้าเฉพาะเหล่านี้มักจะสามารถนำไปใช้กับฐานข้อมูลเหล่านั้นในลักษณะที่พวกเขาจะไม่ยุ่งเกี่ยวกับรหัสทั่วไป
Aaron Bertrand

5

ข้อพิจารณาอีกข้อหนึ่งที่ฉันยังไม่ได้เห็นในคำตอบอื่น ๆ

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

การย้อนกลับไม่เป็นความจริง การรวมฐานข้อมูลผู้เช่ารายหนึ่งจำนวนมากจะต้องใช้งานมากขึ้น


4

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

* มันไม่ได้ทำให้การฟื้นฟูเป็นเรื่องปกติเสมอไป แต่ทำได้ ตัวอย่างเช่นถ้าคุณมีPersonและPersonAddressตาราง Personตารางจะต้องTenantID, PersonIDเป็นคีย์หลัก PersonAddressตารางจะต้องTenantID, PersonID, AddressTypeIDเป็นคีย์หลักกับสิ่งที่ผมแนะนำ

ปกติเพียงPersonIDจะเพียงพอเพราะคุณจะได้เข้าร่วมที่กลับไปที่ตารางเพื่อหาสิ่งที่Person Tenantฉันขอแนะนำให้คุณยกTenantIDไปข้างหน้าในทุกตารางที่ตามมาแม้ว่ากุญแจทินเนอร์จะทำงาน

ฉันเข้าใจว่าการส่งต่อข้อมูลใด ๆ ไปยังตารางที่สามารถได้มาจากข้อมูลอื่น ๆ ถือเป็นการละเมิดมาตรฐาน แต่บางทีการใช้ปุ่มแบบบางเป็นการปฏิบัติที่ดีที่สุด


ขอบคุณฉันเห็นด้วยกับข้อเสนอแนะและเพื่อเพิ่มด้านบนของมันฉันอยากจะพูดถึงฟิลด์นี้ TenantID จะต้องเป็นประเภทจำนวนเต็มและไม่ใช่ GUID เราได้เผาวิธีการทำงาน
DS

3
แต่แม้ว่าคุณจะเลือกที่จะนำ TenantID ไปไว้ในตารางลูกซึ่งคุณไม่ต้องทำกุญแจที่กว้างกว่านั้นก็ไม่ได้หมายความว่า เช่นเดียวกับการเลือก GUID แทนการระบุตัวตน (คีย์ที่กว้างขึ้น) จะไม่ทำให้เกิดความผิดปกติหรือการเลือกคีย์ธรรมชาติที่กว้างกว่าแทนที่จะใช้ตัวแทนเสมือน
Aaron Bertrand
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.