ไม่ทราบวิธีเปลี่ยนเอนทิตีของตัวแปรเป็นตารางสัมพันธ์


9

ข้อมูลเบื้องต้นและข้อมูลที่เกี่ยวข้อง:

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงปัญหาที่ฉันเผชิญ:

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

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

ปัญหา:

ฉันไม่ทราบวิธีสร้างตารางเชิงสัมพันธ์สำหรับตัวอย่างนี้

ความพยายามของฉันในการแก้ไขปัญหา:

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

ป้อนคำอธิบายรูปภาพที่นี่

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

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

Animal< # Animal_ID, race, other attributes >
Cat < # Cat_ID, $ Animal_ID, breed >
Dog < # Dog_ID, $ Animal_ID, breed >

ฉันมีความรู้สึกไม่ดีจริง ๆ เกี่ยวกับวิธีการแก้ปัญหาของฉันและฉันกลัวว่ามันผิด

คำถาม:

  • ฉันจะแปลงตัวอย่างเป็นแผนภาพ ER ได้อย่างไร
  • จะแปลงแผนภาพ ER นั้นให้เป็นตารางสัมพันธ์ได้อย่างไร

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

ขอบคุณ.


1
การเปลี่ยนแปลงของแผนภาพ EER เป็นตารางสามารถพบได้ในบทความนี้จาก 1986 ของTJTeorey, D.Yang, JPFry: วิธีการออกแบบเชิงตรรกะสำหรับฐานข้อมูลเชิงสัมพันธ์โดยใช้แบบจำลองความสัมพันธ์เอนทิตีที่เพิ่มขึ้น มันตรงไปตรงมาและเป็นหนึ่งในเอกสารที่ฉันชอบ
miracle173

คำตอบ:


11

โครงสร้างที่เหมาะสมสำหรับสถานการณ์นี้เป็นรูปแบบ subclass / มรดกและเกือบจะเหมือนกับแนวคิดที่ผมนำเสนอในคำตอบนี้: วิวิธรายการสั่งซื้อของมูลค่า

แบบจำลองที่เสนอในคำถามนี้เป็นจริงค่อนข้างใกล้ที่Animalเอนทิตีประกอบด้วยประเภท (เช่นrace) และคุณสมบัติที่พบได้ทั่วไปในทุกประเภท อย่างไรก็ตามมีการเปลี่ยนแปลงเล็กน้อยสองประการที่จำเป็น:

  1. ลบฟิลด์ Cat_ID และ Dog_ID จากเอนทิตีที่เกี่ยวข้อง:

    แนวคิดที่สำคัญที่นี่คือว่าทุกอย่างเป็นAnimalโดยไม่คำนึงถึงrace: Cat, Dog, Elephantและอื่น ๆ ระบุว่าจุดเริ่มต้นในด้านraceของการAnimalไม่ได้ต้องการอย่างแท้จริงตัวระบุที่แยกจากกันตั้งแต่:

    1. Animal_IDเป็นเอกลักษณ์
    2. Cat, Dogและอื่น ๆ ที่raceหน่วยงานเพิ่มในอนาคตไม่ได้ด้วยตัวเองแทนใด ๆ โดยเฉพาะอย่างเต็มที่Animal; Animalพวกเขาเท่านั้นที่มีความหมายเมื่อใช้ร่วมกับข้อมูลที่มีอยู่ในกิจการที่ผู้ปกครอง

    ดังนั้นAnimal_IDทรัพย์สินในCat, Dogฯลฯ หน่วยงานที่เป็นทั้ง PK และ FK กลับไปที่Animalนิติบุคคล

  2. แยกความแตกต่างระหว่างประเภทของbreed:

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

หมายเหตุเบื้องต้น

  1. SQL มีเฉพาะกับ Microsoft SQL Server (เช่น T-SQL) ควรระวังเกี่ยวกับประเภทข้อมูลเนื่องจากไม่เหมือนกันใน RDBMS ทั้งหมด ยกตัวอย่างเช่นผมใช้VARCHARแต่ถ้าคุณต้องออกไปข้างนอกร้านอะไรของชุด ASCII NVARCHARมาตรฐานคุณจริงๆควรใช้
  2. ฟิลด์ ID ของ "พิมพ์" ตาราง ( Race, CatBreedและDogBreed) จะไม่อัตโนมัติที่เพิ่มขึ้น (IDENTITY คือในแง่ของ T-SQL) เพราะพวกเขามีค่าคงที่แอพลิเคชัน (กล่าวคือพวกเขาเป็นส่วนหนึ่งของโปรแกรม) ที่มีค่าการค้นหาแบบคงที่ใน ฐานข้อมูลและแสดงเป็นenums ใน C # (หรือภาษาอื่น ๆ ) หากมีการเพิ่มค่าพวกเขาจะถูกเพิ่มในสถานการณ์ที่ควบคุม ฉันขอสงวนการใช้ฟิลด์การเพิ่มอัตโนมัติสำหรับข้อมูลผู้ใช้ที่เข้ามาทางแอปพลิเคชัน
  3. หลักการตั้งชื่อที่ฉันใช้คือตั้งชื่อตารางย่อยแต่ละคลาสที่ขึ้นต้นด้วยชื่อคลาสหลักตามด้วยชื่อคลาสย่อย สิ่งนี้จะช่วยจัดระเบียบตารางรวมทั้งบ่งบอกอย่างชัดเจน (โดยไม่ต้องดูที่ FKs) ความสัมพันธ์ของตารางคลาสย่อยกับตารางเอนทิตีหลัก
  4. โปรดดูส่วน "การแก้ไขขั้นสุดท้าย" ในตอนท้ายเพื่อรับทราบเกี่ยวกับการดู

"Breed" เป็น "Race" - วิธีการเฉพาะ

สายพันธุ์เป็นแผนภาพเฉพาะการแข่งขัน
ชุดแรกของตารางนี้เป็นตารางการค้นหา / ประเภท:

CREATE TABLE Race
(
  RaceID INT NOT NULL PRIMARY KEY
  RaceName VARCHAR(50) NOT NULL
);

CREATE TABLE CatBreed
(
  CatBreedID INT NOT NULL PRIMARY KEY,
  BreedName VARCHAR(50),
  CatBreedAttribute1 INT,
  CatBreedAttribute2 VARCHAR(10)
  -- other "CatBreed"-specific properties as needed
);

CREATE TABLE DogBreed
(
  DogBreedID INT NOT NULL PRIMARY KEY,
  BreedName VARCHAR(50),
  DogBreedAttribute1 TINYINT
  -- other "DogBreed"-specific properties as needed
);

รายชื่อที่สองนี้เป็นนิติบุคคล "สัตว์" หลัก:

CREATE TABLE Animal
(
  AnimalID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
  RaceID INT NOT NULL, -- FK to Race
  Name VARCHAR(50)
  -- other "Animal" properties that are shared across "Race" types
);

ALTER TABLE Animal
  ADD CONSTRAINT [FK_Animal_Race]
  FOREIGN KEY (RaceID)
  REFERENCES Race (RaceID);

นี้ชุดที่สามของตารางเป็นหน่วยงานย่อยระดับฟรีที่เสร็จสิ้นความหมายของแต่ละRaceของAnimal:

CREATE TABLE AnimalCat
(
  AnimalID INT NOT NULL PRIMARY KEY, -- FK to Animal
  CatBreedID INT NOT NULL, -- FK to CatBreed
  HairColor VARCHAR(50) NOT NULL
  -- other "Cat"-specific properties as needed
);

ALTER TABLE AnimalCat
  ADD CONSTRAINT [FK_AnimalCat_CatBreed]
  FOREIGN KEY (CatBreedID)
  REFERENCES CatBreed (CatBreedID);

ALTER TABLE AnimalCat
  ADD CONSTRAINT [FK_AnimalCat_Animal]
  FOREIGN KEY (AnimalID)
  REFERENCES Animal (AnimalID);


CREATE TABLE AnimalDog
(
  AnimalID INT NOT NULL PRIMARY KEY, -- FK to Animal
  DogBreedID INT NOT NULL, -- FK to DogBreed
  HairColor VARCHAR(50) NOT NULL
  -- other "Dog"-specific properties as needed
);

ALTER TABLE AnimalDog
  ADD CONSTRAINT [FK_AnimalDog_DogBreed]
  FOREIGN KEY (DogBreedID)
  REFERENCES DogBreed (DogBreedID);

ALTER TABLE AnimalDog
  ADD CONSTRAINT [FK_AnimalDog_Animal]
  FOREIGN KEY (AnimalID)
  REFERENCES Animal (AnimalID);

รูปแบบที่ใช้breedประเภทที่แชร์จะปรากฏหลังส่วน "หมายเหตุเพิ่มเติม"

หมายเหตุเพิ่มเติม

  1. แนวคิดของการbreedดูเหมือนจะเป็นจุดโฟกัสสำหรับความสับสน มันได้รับการแนะนำโดย jcolebrand (ในความคิดเห็นเกี่ยวกับคำถาม) ซึ่งbreedเป็นคุณสมบัติที่ใช้ร่วมกันในหลาย ๆraces และอีกสองคำตอบก็รวมอยู่ในแบบจำลองของพวกเขาเช่นกัน นี้เป็นความผิดพลาด แต่เนื่องจากค่าสำหรับไม่ได้ใช้ร่วมกันในค่าที่แตกต่างกันของbreed raceใช่ฉันทราบว่าทั้งสองรุ่นที่นำเสนออื่น ๆ พยายามที่จะแก้ปัญหานี้โดยการทำให้ผู้ปกครองของrace breedในขณะที่ในทางเทคนิคแก้ปัญหาความสัมพันธ์ก็ไม่ได้ช่วยแก้ปัญหาคำถามการสร้างแบบจำลองโดยรวมของสิ่งที่ต้องทำเกี่ยวกับอสังหาริมทรัพย์ที่ไม่ใช่ที่พบบ่อยหรือวิธีการจัดการที่ไม่ได้มีrace breedแต่ในกรณีที่ทรัพย์สินดังกล่าวรับประกันว่าจะมีอยู่ทั้งหมดAnimals ฉันจะรวมตัวเลือกสำหรับสิ่งนั้นด้วย (ด้านล่าง)
  2. โมเดลที่เสนอโดย vijayp และ DavidN (ซึ่งดูเหมือนจะเหมือนกัน) ไม่ทำงานเพราะ:
    1. พวกเขาทั้งสอง
      1. ไม่อนุญาตให้มีการจัดเก็บคุณสมบัติที่ไม่ทั่วไป (อย่างน้อยก็ไม่ใช่สำหรับแต่ละอินสแตนซ์ของใด ๆAnimal) หรือ
      2. ต้องการให้คุณสมบัติทั้งหมดสำหรับทุกraces ถูกเก็บไว้ในAnimalเอนทิตีซึ่งเป็นวิธีที่เรียบมาก (และเกือบจะไม่สัมพันธ์กัน) ในการแสดงข้อมูลนี้ ใช่ผู้คนทำสิ่งนี้ตลอดเวลา แต่มันหมายถึงการมีเขตข้อมูล NULL จำนวนมากต่อแถวสำหรับคุณสมบัติที่ไม่ได้มีไว้สำหรับเฉพาะนั้นraceและการรู้ว่าเขตข้อมูลต่อแถวเกี่ยวข้องกับraceระเบียนใดระเบียนหนึ่ง
    2. พวกเขาไม่อนุญาตให้มีการเพิ่มraceของAnimalในอนาคตที่ไม่ได้breedเป็นทรัพย์สิน และแม้ว่า ALL Animals มีbreedที่จะไม่เปลี่ยนโครงสร้างเนื่องจากสิ่งที่ได้รับการบันทึกไว้ก่อนหน้านี้เกี่ยวกับbreed: ที่breedขึ้นอยู่กับrace(เช่นbreedสำหรับการCatไม่ได้เป็นสิ่งเดียวกับbreedสำหรับDog)

"พันธุ์" เป็นวิธีการทั่วไป / ใช้ร่วมกัน - ทรัพย์สิน

ป้อนคำอธิบายรูปภาพที่นี่
โปรดทราบ:

  1. SQL ด้านล่างสามารถทำงานในฐานข้อมูลเดียวกับรุ่นที่แสดงด้านบน:

    1. Raceตารางเดียวกัน
    2. Breedตารางใหม่
    3. Animalตารางทั้งสามได้รับการต่อท้ายด้วย2
  2. แม้ว่าBreedจะเป็นทรัพย์สินทั่วไปในตอนนี้ก็ดูเหมือนจะไม่ถูกต้องที่จะไม่ได้Raceบันทึกไว้ในเอนทิตีหลัก / ผู้ปกครอง (แม้ว่ามันจะถูกต้องทางเทคนิคสัมพันธ์) ดังนั้นทั้งสองRaceIDและBreedIDมีการแสดงสิ่งAnimal2ต่อไปนี้ เพื่อป้องกันไม่ให้เกิดความไม่ตรงกันระหว่างที่RaceIDระบุไว้ในAnimal2และ a BreedIDที่เป็นของที่แตกต่างกันRaceIDฉันได้เพิ่ม FK ลงบนทั้งสองRaceID, BreedIDที่อ้างถึงข้อ จำกัด เฉพาะของเขตข้อมูลเหล่านั้นในBreedตาราง ฉันมักจะดูถูก FK ชี้ไปที่ข้อ จำกัด ที่ไม่เหมือนใคร แต่นี่คือหนึ่งในเหตุผลที่ถูกต้อง ข้อ จำกัด ที่ไม่ซ้ำกันคือ "คีย์สำรอง" ในเชิงตรรกะซึ่งทำให้ถูกต้องสำหรับการใช้งานนี้ โปรดทราบว่าBreedตารางยังคงมี PK BreedIDบนเพียง
    1. เหตุผลที่ไม่ได้ไปมีเพียง PK สาขารวมกันและไม่มีข้อ จำกัด ที่ไม่ซ้ำกันก็คือว่ามันจะช่วยให้การเดียวกันจะซ้ำข้ามค่าที่แตกต่างของBreedIDRaceID
    2. เหตุผลที่ไม่เปลี่ยนที่ PK และไม่ซ้ำกันข้อ จำกัด รอบคือว่าอาจนี้ไม่สามารถใช้งานเพียงคนเดียวBreedIDดังนั้นจึงควรจะยังคงเป็นไปได้ที่จะอ้างอิงค่าเฉพาะของBreedโดยไม่ต้องRaceIDใช้ได้
  3. ในขณะที่รุ่นต่อไปนี้ใช้งานได้ แต่มีข้อบกพร่องที่อาจเกิดขึ้นสองประการเกี่ยวกับแนวคิดของการแชร์Breed(และเป็นเหตุผลที่ฉันชอบตารางที่RaceเฉพาะเจาะจงBreed)
    1. มีข้อสมมติโดยนัยที่ค่าทั้งหมดของBreedมีคุณสมบัติเหมือนกันคือ ไม่มีวิธีที่ง่ายในรุ่นนี้ที่จะมีคุณสมบัติที่แตกต่างกันระหว่างDog"สายพันธุ์" และElephant"สายพันธุ์" อย่างไรก็ตามยังมีวิธีการทำเช่นนี้ซึ่งถูกบันทึกไว้ในส่วน "การแก้ไขขั้นสุดท้าย"
    2. ไม่มีทางที่จะแบ่งปันการBreedแข่งขันมากกว่าหนึ่งการแข่งขัน ฉันไม่แน่ใจว่าเป็นสิ่งที่พึงทำหรือไม่ (หรืออาจไม่ได้อยู่ในแนวคิดของสัตว์ แต่อาจอยู่ในสถานการณ์อื่นที่จะใช้แบบจำลองประเภทนี้) แต่ไม่สามารถทำได้ที่นี่
CREATE TABLE Race
(
  RaceID INT NOT NULL PRIMARY KEY,
  RaceName VARCHAR(50) NOT NULL
);

CREATE TABLE Breed
(
  BreedID INT NOT NULL PRIMARY KEY,
  RaceID INT NOT NULL, -- FK to Race
  BreedName VARCHAR(50)
);

ALTER TABLE Breed
  ADD CONSTRAINT [UQ_Breed]
  UNIQUE (RaceID, BreedID);

ALTER TABLE Breed
  ADD CONSTRAINT [FK_Breed_Race]
  FOREIGN KEY (RaceID)
  REFERENCES Race (RaceID);

CREATE TABLE Animal2
(
  AnimalID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
  RaceID INT NOT NULL, -- FK to Race, FK to Breed
  BreedID INT NOT NULL, -- FK to Breed
  Name VARCHAR(50)
  -- other properties common to all "Animal" types
);

ALTER TABLE Animal2
  ADD CONSTRAINT [FK_Animal2_Race]
  FOREIGN KEY (RaceID)
  REFERENCES Race (RaceID);

-- This FK points to the UNIQUE CONSTRAINT on Breed, _not_ to the PK!
ALTER TABLE Animal2
  ADD CONSTRAINT [FK_Animal2_Breed]
  FOREIGN KEY (RaceID, BreedID)
  REFERENCES Breed (RaceID, BreedID);


CREATE TABLE AnimalCat2
(
  AnimalID INT NOT NULL PRIMARY KEY, -- FK to Animal
  HairColor VARCHAR(50) NOT NULL
);

ALTER TABLE AnimalCat2
  ADD CONSTRAINT [FK_AnimalCat2_Animal2]
  FOREIGN KEY (AnimalID)
  REFERENCES Animal2 (AnimalID);

CREATE TABLE AnimalDog2
(
  AnimalID INT NOT NULL PRIMARY KEY,
  HairColor VARCHAR(50) NOT NULL
);

ALTER TABLE AnimalDog2
  ADD CONSTRAINT [FK_AnimalDog2_Animal2]
  FOREIGN KEY (AnimalID)
  REFERENCES Animal2 (AnimalID);


แก้ไขครั้งสุดท้าย (หวังว่า ;-)

  1. เกี่ยวกับความเป็นไปได้ (และความยาก) ของการจัดการคุณสมบัติที่แตกต่างกันระหว่างประเภทของBreedมันเป็นไปได้ที่จะใช้แนวคิด subclass / มรดกเดียวกัน แต่Breedเป็นหน่วยงานหลัก ในการตั้งค่านี้Breedตารางจะมีคุณสมบัติทั่วไปสำหรับทุกประเภทBreed(เช่นเดียวกับAnimalตาราง) และRaceIDจะแสดงถึงประเภทของBreed(เหมือนกับที่ทำในAnimalตาราง) แล้วคุณจะมีตาราง subclass เช่นBreedCat, BreedDogและอื่น ๆ สำหรับโครงการขนาดเล็กสิ่งนี้อาจถูกพิจารณาว่าเป็น "over-engineering" แต่มันถูกกล่าวถึงว่าเป็นตัวเลือกสำหรับสถานการณ์ที่จะได้รับประโยชน์จากมัน
  2. สำหรับทั้งสองวิธีบางครั้งช่วยในการสร้าง Views เป็นทางลัดไปยังเอนทิตีแบบเต็ม ตัวอย่างเช่นพิจารณา:

    CREATE VIEW Cats AS
       SELECT  an.AnimalID,
               an.RaceID,
               an.Name,
               -- other "Animal" properties that are shared across "Race" types
               cat.CatBreedID,
               cat.HairColor
               -- other "Cat"-specific properties as needed
       FROM    Animal an
       INNER JOIN  AnimalCat cat
               ON  cat.AnimalID = an.AnimalID
       -- maybe add in JOIN(s) and field(s) for "Race" and/or "Breed"
  3. แม้ว่าจะไม่ได้เป็นส่วนหนึ่งของเอนทิตีแบบลอจิคัล แต่ก็เป็นเรื่องปกติที่จะมีเขตข้อมูลการตรวจสอบในตารางอย่างน้อยที่สุดจะได้รับความรู้สึกเมื่อมีการแทรกและปรับปรุงระเบียน ดังนั้นในแง่การปฏิบัติ:
    1. CreatedDateฟิลด์จะถูกเพิ่มเข้าไปในAnimalตาราง ฟิลด์นี้ไม่จำเป็นในตารางย่อยใด ๆ (เช่นAnimalCat) เนื่องจากแถวที่ถูกแทรกสำหรับตารางทั้งสองควรทำพร้อมกันภายในธุรกรรม
    2. LastModifiedDateฟิลด์จะถูกเพิ่มเข้าไปในAnimalตารางและตารางคลาสย่อยทั้งหมด ฟิลด์นี้ได้รับการอัปเดตเฉพาะในกรณีที่มีการอัปเดตตารางโดยเฉพาะ: หากมีการอัปเดตเกิดขึ้นAnimalCatแต่ไม่ได้อยู่ในAnimalเฉพาะจะมีการตั้งค่าAnimalIDเฉพาะLastModifiedDateฟิลด์ที่AnimalCatระบุ

2
ยังไงก็เถอะฉันรู้สึกว่าคุณเข้าใจว่าปัญหาของฉันคือ ฉันจะให้คำตอบที่เชื่อมโยงของคุณดูและศึกษาอย่างระมัดระวัง คำจำกัดความง่ายๆของตารางจะดีเช่นกัน (ถ้าแบบสอบถาม SQL มากเกินไปสำหรับคุณที่จะเขียนในขณะนี้) หากคุณตัดสินใจที่จะอัพเดทโพสต์ของคุณด้วยคำสั่ง SQL หรือคำจำกัดความของตาราง ขอขอบคุณอีกครั้ง. ขอแสดงความนับถืออย่างสูง.
AlwaysLearningNewStuff

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

@ เสมอเรียนรู้ NewStuff สวัสดี รับข้อความนี้ก่อนหน้านี้ แต่ไม่มีเวลาที่จะไปได้ทันที ฉันสามารถค้นหาคำถามใหม่ได้โดยคลิกที่ชื่อของคุณด้านบนและจะแสดงคำถามทั้งหมดของคุณ :-)
โซโลมอน Rutzky

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

4

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

นี่คือ buzzwords บางส่วนที่คุณสามารถใช้เพื่อค้นหาบทความที่เป็นประโยชน์บนเว็บ

กรณีของคุณเป็นกรณีคลาสสิกของคลาส / คลาสย่อยหรือหากคุณต้องการให้พิมพ์ / ชนิดย่อย

วลีที่ใช้ในการสร้างแบบจำลอง ER คือ "การทำให้เป็นเรื่องทั่วไป / ความเชี่ยวชาญเฉพาะทาง" และบทความจำนวนมากแสดงสิ่งนี้ภายใต้แบบจำลอง EER (Enhanced Entity-Relationship) สิ่งนี้ไม่ได้อยู่ในการนำเสนอแบบจำลอง ER ดั้งเดิมของ Peter Chen มันถูกเพิ่มเข้ามาในภายหลัง สำหรับบทสรุป gen / spec ที่ดีในรูปแบบ pdf คลิกที่นี่

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

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

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

ในที่สุดก็มีแท็กในพื้นที่นี้ที่รวบรวมคำถามเช่นคุณด้วยกัน
นี่มันคือ:


1
+1 สิ่งที่ทำให้ฉันสับสนคือการไม่มีคีย์หลักในตารางไดอะแกรม โดยเฉพาะอย่างยิ่งใน "classTableInheritance" ฉันไม่เห็นว่าตารางเหล่านี้ทั้งหมดเชื่อมต่อกันด้วยคีย์หลักเดียวกัน
miracle173

@ miracle173 จุดที่ถูกต้อง ด้วยเหตุผลบางอย่างฟาวเลอร์ไม่ได้รวม PKs และ FK ในแผนภาพ มีบทความอื่น ๆ ภายใต้การสืบทอดตารางคลาสที่ให้รายละเอียดนี้ การใช้งานของการสืบทอดตารางคลาสไม่รวมทั้งหมดกับคีย์หลักที่ใช้ร่วมกัน ฉันแนะนำมัน มันทำงานได้มากขึ้นในเวลาแทรก แต่จะง่ายขึ้นและเร็วขึ้นเมื่อถึงเวลาดึงข้อมูล
Walter Mitty

3

ฉันเห็นการออกแบบที่เป็นไปได้

โต๊ะ Race

RaceId- PK- Int
RaceName - Varchar(50)

โต๊ะ Breed

BreedId - PK- Int
RaceId - FK - Int
BreedName - varchar(50)

โต๊ะ Animal

AnimalId - PK- Int
BreedId - FK - Int
Other Columns....

PKs ด้านบนจะเป็นคอลัมน์ที่เพิ่มขึ้นอัตโนมัติ คอลัมน์อื่น ๆ ในAnimalตารางสามารถตั้งชื่อตามนั้นได้

ป้อนคำอธิบายรูปภาพที่นี่


นอกจากนี้ฉันจะเพิ่มฟิลด์ที่มีคีย์ของเชื้อชาติและประเภท (อาจเป็นทริกเกอร์) ในตาราง Animal เพื่ออำนวยความสะดวกในการสร้างดัชนีในภายหลังเพื่อปรับปรุงความเร็ว
Felipe Alcacibar

0

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

Animal < # Animal_ID, Breed_ID, other attributes >
Breed < # Breed_ID, Race_ID >
Race < # Race_ID >

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

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