คุณมีอย่างน้อยห้าตัวเลือกเหล่านี้สำหรับการสร้างแบบจำลองลำดับชั้นชนิดที่คุณอธิบาย:
Single Table Inheritance : หนึ่งตารางสำหรับทุกประเภทผลิตภัณฑ์ที่มีคอลัมน์เพียงพอที่จะเก็บแอตทริบิวต์ทั้งหมดของทุกประเภท นี่หมายถึงคอลัมน์จำนวนมากซึ่งส่วนใหญ่เป็น NULL ในแถวที่กำหนด
การสืบทอดคลาสของตาราง : หนึ่งตารางสำหรับผลิตภัณฑ์ที่จัดเก็บแอตทริบิวต์ที่ใช้ร่วมกันกับผลิตภัณฑ์ทุกประเภท จากนั้นหนึ่งตารางต่อประเภทผลิตภัณฑ์จัดเก็บแอตทริบิวต์เฉพาะผลิตภัณฑ์ประเภทนั้น
การสืบทอดตารางคอนกรีต : ไม่มีตารางสำหรับแอตทริบิวต์ของผลิตภัณฑ์ทั่วไป แทนหนึ่งตารางต่อประเภทผลิตภัณฑ์จัดเก็บทั้งคุณสมบัติของผลิตภัณฑ์ทั่วไปและคุณลักษณะเฉพาะของผลิตภัณฑ์
LOB แบบอนุกรม : หนึ่งตารางสำหรับผลิตภัณฑ์ที่จัดเก็บแอตทริบิวต์ที่ใช้ร่วมกันได้กับผลิตภัณฑ์ทุกประเภท คอลัมน์พิเศษหนึ่งคอลัมน์จะเก็บ BLOB ของข้อมูลกึ่งโครงสร้างในรูปแบบ XML, YAML, JSON หรือรูปแบบอื่น ๆ BLOB นี้ช่วยให้คุณสามารถจัดเก็บแอตทริบิวต์เฉพาะผลิตภัณฑ์แต่ละประเภท คุณสามารถใช้รูปแบบการออกแบบแฟนซีเพื่ออธิบายสิ่งนี้เช่น Facade และ Memento แต่ไม่ว่าคุณจะมีกลุ่มของคุณลักษณะที่ไม่สามารถสืบค้นได้ง่ายภายใน SQL; คุณต้องดึงทั้งหยดกลับไปที่แอปพลิเคชันและเรียงลำดับที่นั่น
เอนทิตี - แอตทริบิวต์ - ค่า : หนึ่งตารางสำหรับผลิตภัณฑ์และหนึ่งตารางที่ pivots คุณลักษณะให้กับแถวแทนที่จะเป็นคอลัมน์ EAV ไม่ใช่การออกแบบที่ถูกต้องเกี่ยวกับกระบวนทัศน์เชิงสัมพันธ์ แต่หลาย ๆ คนใช้อยู่ดี นี่คือ "รูปแบบคุณสมบัติ" ที่กล่าวถึงโดยคำตอบอื่น ดูคำถามอื่น ๆ ด้วยแท็ก eavใน StackOverflow สำหรับข้อผิดพลาดบางอย่าง
ฉันได้เขียนเพิ่มเติมเกี่ยวกับสิ่งนี้ในงานนำเสนอการสร้างแบบจำลองข้อมูลที่ขยายได้
ความคิดเพิ่มเติมเกี่ยวกับ EAV: แม้ว่าหลายคนจะชอบ EAV แต่ฉันก็ไม่ชอบ ดูเหมือนว่าทางออกที่ยืดหยุ่นที่สุดและดีที่สุด แต่เก็บไว้ในใจสุภาษิตTANSTAAFL นี่คือข้อเสียของ EAV:
- ไม่มีวิธีที่จะทำให้คอลัมน์บังคับ (เทียบเท่า
NOT NULL
)
- ไม่มีวิธีใช้ชนิดข้อมูล SQL เพื่อตรวจสอบรายการ
- ไม่มีวิธีที่จะตรวจสอบให้แน่ใจว่าสะกดชื่อแอตทริบิวต์อย่างสม่ำเสมอ
- ไม่มีวิธีที่จะวาง foreign key ในค่าของแอตทริบิวต์ที่กำหนดเช่นสำหรับตารางการค้นหา
- การดึงผลลัพธ์ในรูปแบบตารางแบบดั้งเดิมนั้นซับซ้อนและมีราคาแพงเนื่องจากการรับแอตทริบิวต์จากหลายแถวคุณต้องทำ
JOIN
สำหรับแต่ละแอตทริบิวต์
ระดับความยืดหยุ่น EAV ช่วยให้คุณต้องเสียสละในด้านอื่น ๆ ซึ่งอาจจะทำให้โค้ดของคุณซับซ้อน (หรือแย่กว่านั้น) มากกว่าที่จะแก้ปัญหาเดิมด้วยวิธีการทั่วไป
และในกรณีส่วนใหญ่ไม่จำเป็นต้องมีความยืดหยุ่นในระดับนั้น ในคำถามของ OP เกี่ยวกับประเภทผลิตภัณฑ์จะง่ายกว่ามากในการสร้างตารางต่อประเภทผลิตภัณฑ์สำหรับแอตทริบิวต์เฉพาะผลิตภัณฑ์ดังนั้นคุณจึงมีโครงสร้างที่สอดคล้องกันซึ่งบังคับใช้อย่างน้อยที่สุดสำหรับรายการประเภทผลิตภัณฑ์เดียวกัน
ฉันจะใช้ EAV เฉพาะเมื่อทุกแถวต้องได้รับอนุญาตให้มีแอตทริบิวต์ที่แตกต่างกัน เมื่อคุณมีประเภทผลิตภัณฑ์ที่ จำกัด แน่นอน EAV จะ overkill Class Table มรดกจะเป็นตัวเลือกแรกของฉัน
อัปเดต 2019: ยิ่งฉันเห็นคนที่ใช้ JSON เป็นโซลูชันสำหรับปัญหา "แอตทริบิวต์ที่กำหนดเองจำนวนมาก" ยิ่งฉันชอบโซลูชันนั้นน้อยลง มันทำให้การสืบค้นซับซ้อนเกินไปแม้ว่าจะใช้ฟังก์ชั่น JSONพิเศษเพื่อรองรับ ใช้พื้นที่เก็บข้อมูลมากขึ้นในการจัดเก็บเอกสาร JSON เมื่อเทียบกับการจัดเก็บในแถวและคอลัมน์ปกติ
โดยทั่วไปไม่มีวิธีแก้ปัญหาใด ๆ ที่ง่ายหรือมีประสิทธิภาพในฐานข้อมูลเชิงสัมพันธ์ แนวคิดทั้งหมดของการมี "แอตทริบิวต์ตัวแปร" เป็นพื้นฐานที่ขัดแย้งกับทฤษฎีเชิงสัมพันธ์
สิ่งที่เกิดขึ้นคือคุณต้องเลือกวิธีการแก้ปัญหาที่แย่ที่สุดสำหรับแอพของคุณ ดังนั้นคุณจำเป็นต้องรู้วิธีที่คุณจะสืบค้นข้อมูลก่อนที่คุณจะเลือกการออกแบบฐานข้อมูล ไม่มีทางเลือกโซลูชันหนึ่งที่ "ดีที่สุด" เนื่องจากโซลูชันใด ๆ อาจดีที่สุดสำหรับแอปพลิเคชันที่ระบุ