ความสัมพันธ์แบบหนึ่งต่อหนึ่งเป็นมาตรฐานหรือไม่


12

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

ข้อได้เปรียบของอดีตคือการหลีกเลี่ยงJOINและเข้าถึงข้อมูลสถิติทั้งหมดสำหรับบันทึกที่เกี่ยวข้องได้อย่างรวดเร็ว

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

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


2
'Normalized' หมายถึงรูปแบบปกติแรก (1NF) และเป็นข้อกำหนดพื้นฐานของโมเดลเชิงสัมพันธ์ 'Normalized Normal' หมายถึง 5NF หรือสูงกว่า ตาราง 'ความสัมพันธ์แบบหนึ่งต่อหนึ่ง' ที่เสนอของคุณมีโอกาสที่ดีกว่าที่จะอยู่ในรูปแบบปกติที่สูงขึ้น (อาจเป็น 6NF) มากกว่าความสัมพันธ์ปัจจุบันของคุณเพราะมันจะถูกย่อยสลาย! ตารางที่คุณมีอยู่ในรูปแบบปกติแบบใด
oneday เมื่อ

@onedaywhen เช่นเดียวกับคนอื่น ๆ ฉันไม่ได้ทำตามขั้นตอนการทำให้ปกติเป็นขั้นตอนเพราะบางครั้งการลดความปกติก็มีประโยชน์เช่นกัน โดยทั่วไปฐานข้อมูลทั้งหมดควรมีระดับการทำให้เป็นมาตรฐานระหว่าง 3NF - 5NF (ฉันมักจะมีปัญหากับ 4NF!)
Googlebot

คำตอบ:


19

หากมันสอดคล้องกับกฎของการทำให้เป็นมาตรฐานแล้วความสัมพันธ์แบบ 1: 1 สามารถทำให้เป็นมาตรฐานได้ (ตามคำนิยาม!) - กล่าวอีกนัยหนึ่งไม่มีความสัมพันธ์แบบ 1: 1 ที่ทำให้พวกเขาไม่สามารถเชื่อฟังรูปแบบปกติได้

ในการตอบคำถามของคุณเกี่ยวกับการปฏิบัติจริงของความสัมพันธ์แบบ 1: 1 มีบางครั้งที่สิ่งนี้เป็นโครงสร้างที่มีประโยชน์อย่างสมบูรณ์เช่นเมื่อคุณมีชนิดย่อยที่มีภาคแสดง (คอลัมน์) ที่แตกต่างกัน

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

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

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

  • คุณมีบางคอลัมน์ที่เป็นทางเลือกโดยทั่วไป แต่จะมีผลบังคับใช้เมื่อคุณรู้ว่าบันทึกเป็นประเภทที่แน่นอน

  • คุณมีบางคอลัมน์ที่มีเหตุผลร่วมกันสำหรับชนิดย่อยและคุณต้องการสร้างแบบจำลองเหล่านั้นให้พอดีกับโมเดลวัตถุของรหัสของคุณ

  • คุณมีบางคอลัมน์ที่สามารถใช้ได้กับบางประเภทย่อยของเอนทิตี super-type และคุณต้องการให้สคีมาของคุณบังคับใช้การขาดข้อมูลนี้สำหรับประเภทย่อยอื่น ๆ

  • คุณมีบางคอลัมน์ที่เป็นของเอนทิตี แต่คุณต้องปกป้องคอลัมน์เหล่านี้โดยใช้กฎการเข้าถึงที่ จำกัด มากขึ้น (เช่นเงินเดือนในตารางพนักงาน)

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


You have some subset of columns that are very wide and you want to segregate them physically in your storage for performance reasons.การแยกพวกเขาปรับปรุงประสิทธิภาพอย่างไร (สมมติว่ามีการเข้าถึงคอลัมน์ทุกครั้งที่มีตารางหลัก)
Gili

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

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

@Gili - re: ค่าใช้จ่ายของการเข้าร่วม: ไม่มีคำตอบที่ถูกต้องสำหรับคำถามนั้นนอกเหนือจาก "มันขึ้นอยู่กับ" ค่าใช้จ่ายในการเข้าร่วมนั้นได้รับผลกระทบจากหลายปัจจัย ไม่ว่าพวกเขาจะเล็กน้อยตอบยากยิ่งขึ้นเพราะนั่นเป็นเรื่องส่วนตัวในที่สุด วิธีที่ดีที่สุดในการตอบคำถามของคุณคือการจำลองข้อมูลการทดสอบและทำการทดสอบปริมาณ ลองทั้งสองวิธีและดูว่าคุณสามารถบอกความแตกต่างได้โดยใช้ปริมาณข้อมูลโลกแห่งความจริง
Joel Brown

ฉันทำและได้ผลลัพธ์ที่น่าประหลาดใจ: dba.stackexchange.com/q/74693/4719 ฉันยอมรับว่านี่ไม่ใช่ตัวอย่างของการทำให้เป็นมาตรฐาน แต่มันไม่ได้เน้นว่า JOIN นั้นมีราคาแพงมาก
Gili

4

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

a) ตารางมีข้อมูลแบบไบนารี / clob / blob ในตารางที่เข้าถึงบ่อยดังนั้นจึงทำให้ประสิทธิภาพการทำงานช้าลงเนื่องจากคอลัมน์ขนาดใหญ่ได้รับการจัดการแตกต่างกัน

b) ตารางมีหลายคอลัมน์ที่เข้าถึงได้โดยการสืบค้นที่แตกต่างกันดังนั้นประสิทธิภาพจะลดลงดังนั้นคุณจะย้ายคอลัมน์ที่เกี่ยวข้องไปยังตารางที่แยกต่างหากเพื่อปรับปรุงประสิทธิภาพการเข้าถึง

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


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