คุณจำลองการสืบทอดอย่างมีประสิทธิภาพในฐานข้อมูลได้อย่างไร?


131

แนวทางปฏิบัติที่ดีที่สุดสำหรับการสร้างแบบจำลองการสืบทอดในฐานข้อมูลคืออะไร?

อะไรคือการแลกเปลี่ยน (เช่นความสามารถในการตอบสนอง)?

(ฉันสนใจ SQL Server และ. NET มากที่สุด แต่ฉันก็อยากเข้าใจว่าแพลตฟอร์มอื่น ๆ แก้ไขปัญหานี้อย่างไร)


14
หากคุณสนใจ "แนวทางปฏิบัติที่ดีที่สุด" คำตอบส่วนใหญ่ไม่ถูกต้อง แนวทางปฏิบัติที่ดีที่สุดกำหนดว่า RDb และแอปเป็นอิสระ พวกเขามีเกณฑ์การออกแบบที่แตกต่างกันอย่างสิ้นเชิง ดังนั้น "การสืบทอดการสร้างแบบจำลอง" ในฐานข้อมูล (หรือการสร้างโมเดล RDb ให้เหมาะกับแอปเดียวหรือภาษาของแอปเดียว) จึงเป็นการปฏิบัติที่ไม่ดีมากไม่มีข้อมูลและละเมิดกฎพื้นฐานในการออกแบบ RDb และทำให้มันพิการ
PerformanceDBA


6
@PerformanceDBA คุณมีข้อเสนอแนะอย่างไรในการหลีกเลี่ยงการสืบทอดใน DB Model? สมมติว่าเรามีครู 50 ประเภทที่แตกต่างกันและเราต้องการเชื่อมโยงครูคนนั้นกับชั้นเรียน คุณจะประสบความสำเร็จได้อย่างไรโดยไม่ต้องมีมรดก?
svlada

1
@svlada ซึ่งตรงไปตรงมาเพื่อนำไปใช้ใน RDb ดังนั้นจึงจำเป็นต้องมี "การสืบทอด" ถามคำถามรวมถึง defns ตารางและตัวอย่างแล้วฉันจะตอบโดยละเอียด ถ้าคุณทำในเงื่อนไข OO มันจะเป็นระเบียบ
PerformanceDBA

คำตอบ:


162

มีหลายวิธีในการจำลองการสืบทอดในฐานข้อมูล ที่คุณเลือกขึ้นอยู่กับความต้องการของคุณ นี่คือตัวเลือกบางส่วน:

ตารางต่อประเภท (TPT)

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

ตัวอย่างเช่น:

class Person {
    public int ID;
    public string FirstName;
    public string LastName;
}

class Employee : Person {
    public DateTime StartDate;
}

จะส่งผลให้ตารางเช่น:

table Person
------------
int id (PK)
string firstname
string lastname

table Employee
--------------
int id (PK, FK)
datetime startdate

ตารางต่อลำดับชั้น (TPH)

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

จากชั้นเรียนข้างต้นคุณจะได้รับตารางนี้:

table Person
------------
int id (PK)
int rowtype (0 = "Person", 1 = "Employee")
string firstname
string lastname
datetime startdate

สำหรับแถวใด ๆ ที่เป็น rowtype 0 (Person) วันที่เริ่มต้นจะเป็นโมฆะเสมอ

ตารางต่อคอนกรีต (TPC)

แต่ละคลาสมีตารางที่สร้างขึ้นอย่างสมบูรณ์โดยไม่มีการอ้างอิงถึงตารางอื่น ๆ

จากชั้นเรียนข้างต้นคุณจะได้รับตารางเหล่านี้:

table Person
------------
int id (PK)
string firstname
string lastname

table Employee
--------------
int id (PK)
string firstname
string lastname
datetime startdate

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

12
ดูความคิดเห็นของฉันในคำถาม การใช้ชื่อใหม่ตลก ๆ สำหรับคำศัพท์ทางเทคนิคของ Rdb ที่มีอยู่ทำให้เกิดความสับสน "TPT" คือ supertype-subtype "TPH" ผิดปกติซึ่งเป็นข้อผิดพลาดขั้นต้น "TPH" น้อยกว่า Normalized อีกข้อผิดพลาดขั้นต้น
PerformanceDBA

45
มีเพียง DBA เท่านั้นที่จะถือว่าการทำให้ผิดปกติเป็นข้อผิดพลาดเสมอ :)
Brad Wilson

7
แม้ว่าฉันจะยอมรับว่าการทำให้เป็นปกติทำให้ประสิทธิภาพเพิ่มขึ้นในบางกรณีสิ่งนี้เกิดจากการแยกโครงสร้างทางตรรกะและทางกายภาพที่ไม่สมบูรณ์ (หรือไม่มีอยู่จริง) ใน DBMS น่าเสียดายที่ DBMS เชิงพาณิชย์ส่วนใหญ่ประสบปัญหานี้ @PerformanceDBA ถูกต้อง Undernormalization เป็นข้อผิดพลาดในการตัดสินโดยเสียสละความสอดคล้องของข้อมูลเพื่อความเร็ว น่าเศร้าที่ DBA หรือ dev ไม่จำเป็นต้องเลือกหาก DBMS ได้รับการออกแบบอย่างเหมาะสม สำหรับบันทึกฉันไม่ใช่ DBA
Kenneth Cochran

6
@ แบรดวิลสัน. มีเพียงนักพัฒนาเท่านั้นที่จะปฏิเสธ "เพื่อประสิทธิภาพ" หรืออื่น ๆ บ่อยครั้งที่มันไม่ใช่ de-normalization ความจริงก็คือมันผิดปกติ de-Normalization หรือผิดปกตินั้นเป็นข้อผิดพลาดเป็นความจริงที่ได้รับการสนับสนุนจากทฤษฎีและมีประสบการณ์มาแล้วนับล้านไม่ใช่ "ข้อสันนิษฐาน"
PerformanceDBA

133

การออกแบบฐานข้อมูลที่เหมาะสมไม่เหมือนกับการออกแบบวัตถุที่เหมาะสม

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

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

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

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

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

ตัวอย่าง:

ในระบบการจองโรงแรมคุณอาจต้องจัดเก็บข้อเท็จจริงที่ว่า Jane Doe มีการจองห้องพักที่ Seaview Inn ในวันที่ 10-12 เมษายน นั่นเป็นแอตทริบิวต์ของเอนทิตีลูกค้าหรือไม่? เป็นแอตทริบิวต์ขององค์กรโรงแรมหรือไม่ เป็นหน่วยงานการจองที่มีคุณสมบัติที่รวมลูกค้าและโรงแรมหรือไม่ อาจเป็นสิ่งใดสิ่งหนึ่งหรือทั้งหมดในระบบเชิงวัตถุ ในฐานข้อมูลไม่ใช่สิ่งเหล่านั้น มันเป็นเพียงความจริงที่ว่างเปล่า

หากต้องการดูความแตกต่างให้พิจารณาสองคำค้นหาต่อไปนี้ (1) Jane Doe มีการจองโรงแรมจำนวนเท่าใดในปีหน้า? (2) จำนวนห้องที่จองไว้สำหรับวันที่ 10 เมษายนที่ Seaview Inn?

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

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

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


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

2
คำตอบที่น่าสนใจ คุณจะแนะนำการสร้างแบบจำลองตัวอย่างพนักงาน - พนักงานอย่างไรในคำตอบที่ยอมรับ
sevenforce

2
@ sevenforce- การออกแบบ DB ขึ้นอยู่กับข้อกำหนดของระบบซึ่งไม่ได้กำหนดไว้ มีข้อมูลไม่เพียงพอในการตัดสินใจ ในหลาย ๆ กรณีสิ่งที่คล้ายกับการออกแบบ "ตารางต่อประเภท" อาจเหมาะสมหากไม่ปฏิบัติตามอย่างลวก ๆ ตัวอย่างเช่นวันที่เริ่มต้นอาจเป็นคุณสมบัติที่ดีสำหรับออบเจ็กต์ของพนักงานที่จะมี แต่ในฐานข้อมูลควรเป็นฟิลด์ในตารางการจ้างงานเนื่องจากสามารถจ้างบุคคลได้หลายครั้งโดยมีวันที่เริ่มต้นหลายวัน สิ่งนี้ไม่สำคัญสำหรับวัตถุ (ซึ่งจะใช้ล่าสุด) แต่เป็นสิ่งสำคัญในฐานข้อมูล
Jeffrey L Whitledge

2
แน่นอนว่าคำถามของฉันส่วนใหญ่เกี่ยวกับวิธีการสร้างแบบจำลองการสืบทอด ขออภัยที่ไม่ชัดเจนพอ ขอบคุณ ดังที่คุณได้กล่าวไว้ส่วนใหญ่ควรมีEmploymentตารางซึ่งรวบรวมการจ้างงานทั้งหมดพร้อมวันเริ่มงาน ดังนั้นหากการทราบวันที่เริ่มต้นการจ้างงานในปัจจุบันของ an Employerเป็นสิ่งสำคัญนั่นอาจเป็นกรณีการใช้งานที่เหมาะสมสำหรับ a Viewซึ่งรวมถึงคุณสมบัตินั้นโดยการสอบถาม? (หมายเหตุ: ดูเหมือนว่าเป็นเพราะ '-' ทันทีหลังจากที่ฉันเรียกฉันไม่ได้รับการแจ้งเตือนใด ๆ ในความคิดเห็นของคุณ)
sevenforce

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

9

คำตอบสั้น ๆ : คุณทำไม่ได้

หากคุณต้องการจัดลำดับวัตถุของคุณให้ใช้ ORM หรือสิ่งที่ดีกว่านั้นเช่น activerecord หรือ prevaylence

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


3
+1 การพยายามสร้างแบบจำลองการสืบทอดในฐานข้อมูลเป็นการสิ้นเปลืองทรัพยากรเชิงสัมพันธ์ที่ดี
Daniel Spiewak

7

รูปแบบ TPT, TPH และ TPC เป็นวิธีที่คุณจะไปตามที่กล่าวโดย Brad Wilson แต่สองข้อสังเกต:

  • คลาสย่อยที่สืบทอดมาจากคลาสฐานสามารถถูกมองว่าเป็นเอนทิตีที่อ่อนแอไปยังนิยามคลาสพื้นฐานในฐานข้อมูลซึ่งหมายความว่าพวกมันขึ้นอยู่กับคลาสพื้นฐานและไม่สามารถดำรงอยู่ได้หากปราศจากมัน ฉันเคยเห็นหลายครั้ง ID ที่ไม่ซ้ำกันจะถูกเก็บไว้สำหรับแต่ละตารางย่อยในขณะที่เก็บ FK ไว้ที่ตารางหลัก FK หนึ่งตัวนั้นเพียงพอและดีกว่าที่จะเปิดใช้งานการเรียงซ้อนแบบ on-delete สำหรับความสัมพันธ์ FK ระหว่างตารางลูกและฐาน

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

สมมติว่าเราต้องการออกแบบฐานข้อมูลที่มีแผนภาพคลาสรูปร่างต่อไปนี้:

public class Shape {
int id;
Color color;
Thickness thickness;
//other fields
}

public class Rectangle : Shape {
Point topLeft;
Point bottomRight;
}

public class Circle : Shape {
Point center;
int radius;
}

การออกแบบฐานข้อมูลสำหรับคลาสข้างต้นสามารถเป็นดังนี้:

table Shape
-----------
int id; (PK)
int color;
int thichkness;
int rowType; (0 = Rectangle, 1 = Circle, 2 = ...)

table Rectangle
----------
int ShapeID; (FK on delete cascade)
int topLeftX;
int topLeftY;
int bottomRightX;
int bottomRightY;

table Circle
----------
int ShapeID; (FK on delete cascade)  
int centerX;
int center;
int radius;

4

การสืบทอดมีสองประเภทหลักที่คุณสามารถตั้งค่าในฐานข้อมูลตารางต่อเอนทิตีและตารางต่อลำดับชั้น

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

ข้อความแสดงแทน

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

ข้อความแสดงแทน SessionTypeID เป็นตัวแยกแยะ

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

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


ฉันจะพิจารณา Target per Concrete class เพื่อไม่ให้สร้างแบบจำลองการสืบทอดได้ดีดังนั้นฉันจึงไม่ได้แสดง
mattlant

คุณช่วยเพิ่มข้อมูลอ้างอิงที่มาจากภาพประกอบได้ไหม
chryss

ภาพที่คุณกำลังพูดถึงในตอนท้ายของคำตอบของคุณอยู่ที่ไหน?
Musa Haidari

1

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


2
เหตุใดผู้คนจึงเชื่อว่าการทำให้ฐานข้อมูลเป็นปกติทำให้ประสิทธิภาพลดลง ผู้คนยังคิดว่าหลักการ DRY ทำให้ประสิทธิภาพของโค้ดลดลงหรือไม่? ความเข้าใจผิดนี้มาจากไหน?
Steven A. Lowe

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

2
ในช่วงเริ่มต้นการทำให้เป็นมาตรฐานอาจมีผลเล็กน้อยต่อประสิทธิภาพ แต่เมื่อเวลาผ่านไปเมื่อจำนวนแถวเพิ่มขึ้น JOIN ที่มีประสิทธิภาพจะเริ่มมีประสิทธิภาพดีกว่าตารางที่ใหญ่กว่า แน่นอนว่าการทำให้เป็นมาตรฐานมีประโยชน์อื่น ๆ ที่มากกว่า - ความสม่ำเสมอและการขาดความซ้ำซ้อน ฯลฯ
Rob

1

ทำซ้ำคำตอบของเธรดที่คล้ายกัน

ในการแมปหรือการแมปมรดกจะแมปกับตารางหลักที่ตารางพาเรนต์และตารางรองใช้ตัวระบุเดียวกัน

ตัวอย่างเช่น

create table Object (
    Id int NOT NULL --primary key, auto-increment
    Name varchar(32)
)
create table SubObject (
    Id int NOT NULL  --primary key and also foreign key to Object
    Description varchar(32)
)

SubObject มีความสัมพันธ์คีย์ต่างประเทศกับ Object เมื่อคุณสร้างแถว SubObject ก่อนอื่นคุณต้องสร้างแถว Object และใช้ Id ในทั้งสองแถว

แก้ไข: หากคุณต้องการสร้างแบบจำลองพฤติกรรมด้วยคุณจะต้องมีตาราง Type ที่แสดงรายการความสัมพันธ์การสืบทอดระหว่างตารางและระบุแอสเซมบลีและชื่อคลาสที่ใช้พฤติกรรมของแต่ละตาราง

ดูเหมือนจะ overkill แต่ทั้งหมดนี้ขึ้นอยู่กับว่าคุณต้องการใช้มันเพื่ออะไร!


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

1

การใช้ SQL ALchemy (Python ORM) คุณสามารถสืบทอดได้สองประเภท

สิ่งที่ฉันเคยมีประสบการณ์คือการใช้ singe-table และมีคอลัมน์ที่เลือกปฏิบัติ สำหรับอินสแตนซ์ฐานข้อมูล Sheep (ไม่ใช่เรื่องตลก!) เก็บ Sheep ทั้งหมดไว้ในตารางเดียวและ Rams และ Ewes ได้รับการจัดการโดยใช้คอลัมน์เพศในตารางนั้น

ดังนั้นคุณสามารถค้นหาแกะทั้งหมดและรับแกะทั้งหมดได้ หรือคุณสามารถค้นหาโดย Ram เท่านั้นและจะได้รับ Rams เท่านั้น นอกจากนี้คุณยังสามารถทำสิ่งต่างๆเช่นมีความสัมพันธ์ที่เป็นได้เฉพาะ Ram (เช่น Sire of a Sheep) เป็นต้น


1

โปรดทราบว่าบางระบบฐานข้อมูลแล้วให้กลไกมรดกกำเนิดเช่นPostgres ดูที่เอกสาร

ตัวอย่างเช่นคุณจะสอบถามระบบบุคคล / พนักงานที่อธิบายไว้ในคำตอบข้างต้นดังนี้:

  / * แสดงชื่อของบุคคลหรือพนักงานทั้งหมด * /
  เลือกชื่อจากบุคคล 

  / * แสดงวันที่เริ่มต้นของพนักงานทั้งหมดเท่านั้น * /
  เลือกวันที่เริ่มต้นจากพนักงาน

ในนั้นคือตัวเลือกฐานข้อมูลของคุณคุณไม่จำเป็นต้องฉลาดเป็นพิเศษ!

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