변수 엔티티를 관계형 테이블로 변환하는 방법을 모른다


9

소개 및 관련 정보 :

다음 예제는 내가 직면 한 문제를 보여줍니다.

동물고양이개가 될 수있는 종족을 가지고 있습니다 . 고양이 또는 페르시아어 일 수 있습니다 . 독일 셰퍼드 또는 래브라도 retriver 일 수 있습니다 .

동물은 강력한 실체이며, 인종은 두 가지 값 중 하나를 가질 수있는 속성입니다 (cat 또는 dog). 이 두 값은 복잡합니다 (문제를 설명하기 위해 개 / 고양이 유형 만 추가했지만 고양이 / 개 이름과 다른 것들도있을 수 있습니다).

문제:

이 예제에서 관계형 테이블을 만드는 방법을 모르겠습니다.

문제를 해결하기위한 나의 노력 :

나는 Chen의 표기법을 사용하여 문제를 나타내는 ER 다이어그램을 그리려고 노력했지만 초보자가되어서 제대로했는지 잘 모르겠습니다. 내가 가진 것은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

문제가 발생하면 죄송합니다. 문제가있는 경우 수정 해주세요. 나는 단순히 "무료 솔루션"을 원치 않고이 문제를 다루는 방법을 배우기 위해 미래에 스스로 해결할 수 있습니다.

내 마음에 오는 유일한 것은 고양이와 개를위한 두 개의 별도 테이블을 만드는 것입니다. 또한 Animal 테이블 의 race 속성은 cat 또는 dog 값만 저장 합니다. 이 같은:

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 : 확장 된 엔터티 관계 모델을 사용한 관계형 데이터베이스의 논리적 설계 방법론의 1986 년 부터이 백서에서 확인할 수 있습니다 . 그것은 간단하고 내가 가장 좋아하는 논문 중 하나입니다.
miracle173

답변:


11

이 시나리오의 올바른 구조는 하위 클래스 / 상속 모델이며이 답변에서 제안한 개념과 거의 동일합니다. 이기종 순서의 값 목록 .

이 질문에서 제안 된 모델은 Animal실체에 유형 (예 :) race과 모든 유형에 공통적 인 속성이 포함되어 있다는 점에서 매우 가깝습니다 . 그러나 두 가지 사소한 변경이 필요합니다.

  1. 해당 엔티티에서 Cat_ID 및 Dog_ID 필드를 제거하십시오.

    여기서 핵심 개념 은 : ,, 등에 관계없이 모든 것이라는 입니다 . 포인트를 시작하는 것은, 특정 점을 감안 의이 진정 이후 별도의 식별자를 필요로하지 않는다 :AnimalraceCatDogElephantraceAnimal

    1. Animal_ID고유
    2. Cat, Dog및 추가적인 race향후에 추가 엔티티는, 그 자체로 완전히 특정 표현하지 않는다 Animal; 부모 엔터티에 포함 된 정보와 함께 사용될 때만 의미가 Animal있습니다.

    따라서, Animal_ID의 property에서 Cat, Dog등 엔티티는 PK와 FK로 뒤로 모두 인 Animal엔티티.

  2. 유형의 구별 breed:

    두 속성이 동일한 이름을 공유한다고해서 동일한 이름이 그러한 관계를 암시 하더라도 해당 속성이 반드시 동일한 것은 아닙니다 . 이 경우, 당신이 정말이 것은 실제로 및 별도의 "유형"으로CatBreedDogBreed

초기 메모

  1. SQL은 Microsoft SQL Server에만 적용됩니다 (예 : T-SQL). 즉, 모든 RDBMS에서 데이터 유형이 동일하지 않으므로 데이터 유형에주의하십시오. 예를 들어, 나는 사용하고 VARCHAR있지만 표준 ASCII 세트 이외의 것을 저장 해야하는 경우 실제로 사용해야 NVARCHAR합니다.
  2. "type"테이블 ( Race,, CatBreedDogBreed) 의 ID 필드 는 응용 프로그램 상수 (예 : 응용 프로그램의 일부)이기 때문에 자동 증가 하지 않습니다 (예 : T-SQL의 관점에서 IDENTITY). enumC # (또는 다른 언어)에서 s로 표시됩니다 . 값이 추가되면 제어 된 상황에서 추가됩니다. 응용 프로그램을 통해 들어오는 사용자 데이터에 자동 증분 필드를 사용합니다.
  3. 내가 사용하는 명명 규칙은 기본 클래스 이름으로 시작하여 하위 클래스 이름으로 시작하는 각 하위 클래스 테이블의 이름을 지정하는 것입니다. 이를 통해 테이블을 구성하고 서브 클래스 테이블과 기본 엔티티 테이블의 관계를 명확하게 (FK를 보지 않고) 표시 할 수 있습니다.
  4. 보기에 대한 참고 사항은 마지막에있는 "최종 편집"섹션을 참조하십시오.

"레이스"별 접근 방식으로 "품종"

인종 별 다이어그램으로 번식
이 첫 번째 테이블 세트는 조회 / 유형 테이블입니다.

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. 모든 데이터 race의 모든 속성 Animal은이 데이터를 나타내는 매우 평평하고 (관계가 거의없는) 엔터티에 저장되어야합니다 . 그렇습니다. 사람들은 항상이 작업을 수행하지만 해당 속성에 적합하지 않은 속성에 대해 행당 많은 NULL 필드를 가지며 해당 레코드 race의 특정 필드와 관련된 행당 필드를 알고 race있어야합니다.
    2. 나중에 속성으로 포함 되지 않은 race의 를 추가 할 수 Animal없습니다 breed. 그리고 모든 경우에도 Animal의가있다 breed, 그 때문에 이전에 대해 언급 된 내용에 대한 구조 변하지 않을 것입니다 breed: breed온 의존을 race(즉, breed위해이 Cat같은 일이 아니다 breed에 대한 Dog).

공통 / 공유 속성 접근 방식으로 "사육"

여기에 이미지 설명을 입력하십시오
참고 사항 :

  1. 아래의 SQL은 위에 제시된 모델과 동일한 데이터베이스에서 실행될 수 있습니다.

    1. Race테이블은 동일
    2. Breed표는 새로운
    3. 세 개의 Animal테이블이 추가되었습니다2
  2. Breed현재는 일반적인 자산 임에도 불구하고 Race(기술적으로 관계가 정확하더라도) 주 / 부모 단체에 언급 되지 않은 것이 옳지 않은 것 같습니다 . 그래서, 모두 RaceIDBreedID표현된다 Animal2. 사이의 불일치 방지하기 위해 RaceID에 주목 Animal2하고 BreedID다른위한 즉 RaceID, I 모두에 FK 추가 한 RaceID, BreedID것을 참조합니다에서 해당 필드의 UNIQUE CONSTRAINT Breed테이블. 나는 일반적으로 FK가 고유 제약 조건을 가리키는 것을 멸시하지만, 그렇게하는 몇 가지 유효한 이유 중 하나입니다. UNIQUE CONSTRAINT는 논리적으로 "대체 키"이므로이 용도에 유효합니다. 또한 Breed테이블에는 여전히 PK가 있습니다 BreedID.
    1. 결합 된 필드에서 PK 만 사용하지 않고 UNIQUE CONSTRAINT가없는 이유는 BreedID서로 다른 값 에서 동일한 값을 반복 할 수 있기 때문입니다 RaceID.
    2. PK와 UNIQUE CONSTRAINT를 전환하지 않는 이유는 이것이의 유일한 사용법이 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, 그것 동일한 서브 클래스 / 상속 개념이지만 함께 채용 할 수 Breed메인 엔티티로한다. 이 설정에서 Breed테이블의 모든 유형에 공통된 속성 것 Breed(단지 등 Animal테이블)과 RaceID유형을 나타내는 것이다 Breed(그것은에서와 동일하게 Animal테이블). 그러면 BreedCat, 등의 서브 클래스 테이블이 생깁니다 BreedDog. 소규모 프로젝트의 경우 이것은 "과도한 엔지니어링"으로 간주 수 있지만, 이점이있는 상황에 대한 옵션으로 언급되고 있습니다.
  2. 두 가지 방법 모두 뷰를 전체 엔터티에 대한 바로 가기로 만드는 데 도움이되는 경우가 있습니다. 예를 들어, 다음을 고려하십시오.

    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

@AlwaysLearningNewStuff 안녕하세요. 이 메시지를 미리 받았지만 지금 바로 연락 할 시간이 없었습니다. 위의 이름을 클릭하여 새 질문을 찾을 수 있었고 모든 질문이 표시됩니다 :-).
Solomon Rutzky 2016 년

나는 이 질문 을 언급하고 있었다 . 간단히 말해서 : 나는 공통 속성을 가진 3 개의 엔티티를 가지고 D있으므로 귀하의 답변에서 메소드를 적용하고 싶었습니다. 두 엔터티에는 E세 번째 엔터티에없는 공통 특성 이 있습니다. 이 사실을 무시하고 표준 솔루션을 적용해야합니까, 아니면 디자인을 더욱 최적화 할 수있는 방법이 있습니까?
AlwaysLearningNewStuff 2016 년

4

우선, ER 모델링과 관계형 모델링을 구별하기 위해 잘하고 있습니다. 많은 초보자는 그렇지 않습니다.

다음은 웹에서 유용한 기사를 찾는 데 사용할 수있는 전문 용어입니다.

귀하의 경우는 클래스 / 하위 클래스의 고전적인 경우이거나 원하는 경우 유형 / 하위 유형입니다.

ER 모델링에 사용되는 문구는 "일반화 / 전문화"입니다. 그리고 많은 기사들이 이것을 EER (Enhanced Entity-Relationship) 모델링이라고합니다. Peter Chen이 ER 모델링을 처음 발표 한 것은 아닙니다. 나중에 추가되었습니다. pdf 형식의 gen / spec에 대한 요약 정보를 보려면 여기를 클릭하십시오.

다음으로 클래스 / 서브 클래스 케이스를 관계형 모델링으로 변환 할 때 테이블을 디자인합니다. 하나 이상의 접근 방식이 있습니다. 두 가지 주요 접근 방식을 단일 테이블 상속과 클래스 테이블 상속이라고합니다. 각각의 장점과 단점이 있습니다. 이 두 가지 디자인에 대한 최고의 프레젠테이션은 Martin Fowler가 제공합니다. 당신은 여기여기에 그의 개요를 볼 수 있습니다 .

단일 테이블 상속의 큰 장점은 단순성입니다. 모두 하나의 테이블에 저장됩니다. 큰 단점은 많은 NULL입니다. 공간과 시간을 낭비하고 혼란스러운 논리를 초래할 수 있습니다.

클래스 테이블 상속에는 조인이 필요하지만 간단하고 빠릅니다. 특히 공유 기본 키라는 기술을 사용하는 경우 서브 클래스 테이블의 PK가 수퍼 클래스 테이블의 PK 사본입니다. 수퍼 클래스 데이터를 서브 클래스 데이터와 결합하는 각 서브 클래스에 대한보기를 작성할 수 있습니다.

마지막으로,이 영역에는 귀하와 같은 질문을 함께 모으는 태그가 있습니다.
여기 있습니다 :


1
+1 혼란스러운 점은 테이블 다이어그램에 기본 키가 없다는 것입니다. 특히 "classTableInheritance"에서 이러한 모든 테이블이 동일한 기본 키로 연결되어 있음을 알 수 없습니다.
miracle173

@ miracle173은 유효한 포인트입니다. 어떤 이유로 Fowler는 다이어그램에 PK와 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....

위의 PK는 자동 증가 열입니다. Animal테이블의 다른 열은 그에 따라 이름을 지정할 수 있습니다.

여기에 이미지 설명을 입력하십시오


또한 속도를 향상시키기 위해 나중에 색인을 사용하기 위해 Animal 테이블에 Race 및 Type 키 (트리거 일 수 있음)가있는 필드를 추가합니다.
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.