예, 다 대다 (간결한 M : N) 연관 또는 관계의 식별은 개념 스키마를 배치 할 때 데이터베이스 전문가가 매우 일반적으로 직면하는 상황입니다. 카디널리티 비율의 연관성은 매우 다른 성격의 비즈니스 환경 에서 발생하며, 예를 들어 SQL-DDL 배열을 통해 논리적 레벨에서 적절하게 표현되면 유해 중복성을 도입 않습니다 .
이러한 방식으로 데이터베이스 모델링 실습의 목적은 관심있는 비즈니스 컨텍스트의 관련 특성을 높은 정밀도로 반영하는 것입니다 . 따라서 수많은 M : N 연관이 있음을 올바르게 식별하면 (a) 개념 스키마 및 (b) 각각의 논리적 레벨 선언에 관계없이 (또는 그 연결 수에 관계없이)이를 표현 해야 합니다. 기타 – 카디널리티 비율이 해결되어야합니다.
비즈니스 규칙
상황에 맞는 질문을 제공했으며 현재 작업중인 데이터베이스가 단순한 가상이라는 점을 분명히했습니다. 이는 고려중인 시나리오와 같은 "실제"비즈니스 시나리오가 훨씬 더 광범위 할 것으로 생각하기 때문에 중요한 시점입니다. 따라서보다 복잡한 정보 요구 사항을 의미합니다.
나는 (1) 당신이 제공 한 비즈니스 규칙을 약간 수정하고 확장하기로 결정했다. 다음은 제가 조합 한 몇 가지 공식입니다.
- 파티 (1) 중 하나 인 사람 또는 기관
- 파티는 정확히-하나에 의해 분류된다 PartyType
- PartyType의 , 분류 제로 하나 또는-많은 당사국
- 기구는 제로 일 또는 일대 개발 제품
- 제품 중 하나입니다 시스템 이나 게임
- 제품은 정확하게-하나에 의해 분류된다 ProductType
- 시스템 정확히-하나 탈 로그 SystemType
- 게임 일대을 통해 재생할 수 있습니다 시스템
- 시스템 을 일대 재생하는 데 사용됩니다 게임
- 게임은 제로 일 또는 일대 다로 분류된다 장르
- 장르 를 분류 제로 하나 또는-많은 게임을
- 제품 일대를 기원 채용
- 작업은 제로 하나 또는-많은 성취 사람들이 재생됩니다 역할 의를 공동 작업자를
- 사람 A는 공동 작업자 제로 일 또는 일대에서 채용
1 당사자 는 단일 실체를 구성하는 개인 또는 개인 그룹을 지칭 할 때 법적 상황에서 사용되는 용어이므로이 명칭은 사람 과 조직 을 나타내는 데 적합합니다 .
IDEF1X 다이어그램
그런 다음 그림 1에 표시된 IDEF1X 2 다이어그램을 만들었습니다 (링크를 클릭하여 더 높은 해상도로 확인하십시오). 위에 제시된 비즈니스 규칙을 하나의 그래픽 장치에 통합합니다 (관련된 다른 규칙과 함께).
2 정보 모델링 통합 정의 ( IDEF1X )는 1993 년 12 월 미국 표준 기술 연구소 (NIST) 에서 표준 으로 확립 한 권장 데이터 모델링 기법입니다 . (a) 관계형 모델의 유일한 창시자, 즉 Dr. EF Codd가 저술 한 초기 이론적 자료; (b) PP Chen 박사가 개발 한 데이터 의 개체-관계 관점 ; 또한 (c) Robert G. Brown이 만든 논리적 데이터베이스 디자인 기법.
보시다시피, 나는 대응하는 연관 엔티티 유형 을 통해 세 개의 M : N 연관만을 묘사했습니다 .
다른 측면들 중에서도 다음과 같은 두 가지 별개의 수퍼 타입-서브 타입 구조가 있습니다.
수퍼 타입-서브 타입 연관에 익숙하지 않은 경우 다음과 같은 질문에 대한 답변과 같은 도움을받을 수 있습니다.
예시적인 논리적 SQL-DDL 레이아웃
계속해서 논리적 수준에서 다음을 확인해야합니다.
- 각 엔티티 유형은 개인으로 표시됩니다 기본 테이블로
- 적용 가능한 엔터티 유형의 각 단일 속성은 특정 열로
- INT, DATETIME, CHAR 등 (물론, Firebird 또는 PostgreSQL을 사용할 때) 포함 된 모든 값 이 특정하고 잘 정의 된 세트에 속 하는지 확인하기 위해 각 열에 정확한 데이터 유형 이 고정됩니다 . 더 강력한 DOMAIN을 사용하고 싶을 수도 있습니다.)
- 모든 테이블에 보유 된 행 형식의 어설 션 이 개념적 수준에서 결정된 비즈니스 규칙을 준수 하도록 보장하기 위해 여러 제약 조건 이 선언적으로 구성 됩니다.
그래서 이전에 표시된 IDEF1X 다이어그램을 기반으로 다음 DDL 배열을 선언했습니다.
CREATE TABLE PartyType ( -- Stands for an independent entity type.
PartyTypeCode CHAR(1) NOT NULL, -- To retain 'P' or 'O'.
Name CHAR(30) NOT NULL, -- To keep 'Person' or 'Organization'.
--
CONSTRAINT PartyType_PK PRIMARY KEY (PartyTypeCode)
);
CREATE TABLE Party ( -- Represents an entity supertype.
PartyId INT NOT NULL,
PartyTypeCode CHAR(1) NOT NULL, -- To hold the value that indicates the type of the row denoting the complementary subtype occurrence: either 'P' for 'Person' or 'O' for 'Organization'.
CreatedDateTime TIMESTAMP NOT NULL,
--
CONSTRAINT Party_PK PRIMARY KEY (PartyId),
CONSTRAINT PartyToPartyType_FK FOREIGN KEY (PartyTypeCode)
REFERENCES PartyType (PartyTypeCode)
);
CREATE TABLE Person ( -- Denotes an entity subtype.
PersonId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
GenderCode CHAR(3) NOT NULL,
BirthDate DATE NOT NULL,
--
CONSTRAINT Person_PK PRIMARY KEY (PersonId),
CONSTRAINT Person_AK UNIQUE (FirstName, LastName, GenderCode, BirthDate), -- Composite ALTERNATE KEY.
CONSTRAINT PersonToParty_FK FOREIGN KEY (PersonId)
REFERENCES Party (PartyId)
);
CREATE TABLE Organization ( -- Stands for an entity subtype.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Name CHAR(30) NOT NULL,
FoundingDate DATE NOT NULL,
--
CONSTRAINT Organization_PK PRIMARY KEY (OrganizationId),
CONSTRAINT Organization_AK UNIQUE (Name), -- Single-column ALTERNATE KEY.
CONSTRAINT OrganizationToParty_FK FOREIGN KEY (OrganizationId)
REFERENCES Party (PartyId)
);
CREATE TABLE ProductType ( -- Represents an independent entity type.
ProductTypeCode CHAR(1) NOT NULL, -- To enclose the values 'S' and 'G' in the corresponding rows.
Name CHAR(30) NOT NULL, -- To comprise the values 'System' and 'Person' in the respective rows.
--
CONSTRAINT ProductType_PK PRIMARY KEY (ProductTypeCode)
);
CREATE TABLE Product ( -- Denotes an entity supertype.
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
ProductTypeCode CHAR(1) NOT NULL, -- To keep the value that indicates the type of the row denoting the complementary subtype occurrence: either 'S' for 'System' or 'G' for 'Game'.
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Product_PK PRIMARY KEY (OrganizationId, ProductNumber), -- Composite PRIMARY KEY.
CONSTRAINT ProductToOrganization_FK FOREIGN KEY (OrganizationId)
REFERENCES Organization (OrganizationId),
CONSTRAINT ProductToProductType_FK FOREIGN KEY (ProductTypeCode)
REFERENCES ProductType (ProductTypeCode)
);
CREATE TABLE SystemType ( -- Stands for an independent entity type.
SystemTypeCode CHAR(1) NOT NULL,
Name CHAR(30) NOT NULL,
--
CONSTRAINT SystemType_PK PRIMARY KEY (SystemTypeCode)
);
CREATE TABLE MySystem ( -- Represents a dependent entity type.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
SystemNumber INT NOT NULL,
SystemTypeCode CHAR(1) NOT NULL,
ParticularColumn CHAR(30) NOT NULL,
--
CONSTRAINT System_PK PRIMARY KEY (OrganizationId, SystemNumber),
CONSTRAINT SystemToProduct_FK FOREIGN KEY (OrganizationId, SystemNumber)
REFERENCES Product (OrganizationId, ProductNumber),
CONSTRAINT SystemToSystemType_FK FOREIGN KEY (SystemTypeCode)
REFERENCES SystemType (SystemTypeCode)
);
CREATE TABLE Game ( -- Denotes an entity subtype.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
GameNumber INT NOT NULL,
SpecificColumn CHAR(30) NOT NULL,
--
CONSTRAINT Game_PK PRIMARY KEY (OrganizationId, GameNumber),
CONSTRAINT GameToProduct_FK FOREIGN KEY (OrganizationId, GameNumber)
REFERENCES Product (OrganizationId, ProductNumber)
);
CREATE TABLE Genre ( -- Stands for an independent entity type.
GenreNumber INT NOT NULL,
Name CHAR(30) NOT NULL,
Description CHAR(90) NOT NULL,
--
CONSTRAINT Genre_PK PRIMARY KEY (GenreNumber),
CONSTRAINT Genre_AK1 UNIQUE (Name),
CONSTRAINT Genre_AK2 UNIQUE (Description)
);
CREATE TABLE SystemGame ( -- Represents an associative entity type or M:N association.
SystemOrganizationId INT NOT NULL,
SystemNumber INT NOT NULL,
GameOrganizationId INT NOT NULL,
GameNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT SystemGame_PK PRIMARY KEY (SystemOrganizationId, SystemNumber, GameOrganizationId, GameNumber), -- Composite PRIMARY KEY.
CONSTRAINT SystemGameToSystem_FK FOREIGN KEY (SystemOrganizationId, SystemNumber) -- Multi-column FOREIGN KEY.
REFERENCES MySystem (OrganizationId, SystemNumber),
CONSTRAINT SystemGameToGame_FK FOREIGN KEY (SystemOrganizationId, GameNumber) -- Multi-column FOREIGN KEY.
REFERENCES Game (OrganizationId, GameNumber)
);
CREATE TABLE GameGenre ( -- Denotes an associative entity type or M:N association.
GameOrganizationId INT NOT NULL,
GameNumber INT NOT NULL,
GenreNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT GameGenre_PK PRIMARY KEY (GameOrganizationId, GameNumber, GenreNumber), -- Composite PRIMARY KEY.
CONSTRAINT GameGenreToGame_FK FOREIGN KEY (GameOrganizationId, GameNumber)
REFERENCES Game (OrganizationId, GameNumber), -- Multi-column FOREIGN KEY.
CONSTRAINT GameGenreToGenre_FK FOREIGN KEY (GenreNumber)
REFERENCES Genre (GenreNumber)
);
CREATE TABLE Job ( -- Stands for an associative entity type or M:N association.
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
JobNumber INT NOT NULL,
Title CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Job_PK PRIMARY KEY (OrganizationId, ProductNumber, JobNumber), -- Composite PRIMARY KEY.
CONSTRAINT Job_AK UNIQUE (Title), -- Single-column ALTERNATE KEY.
CONSTRAINT JobToProduct_FK FOREIGN KEY (OrganizationId, ProductNumber) -- Multi-column FOREIGN KEY.
REFERENCES Product (OrganizationId, ProductNumber)
);
CREATE TABLE Collaborator ( -- Represents an associative entity type or M:N association.
CollaboratorId INT NOT NULL,
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
JobNumber INT NOT NULL,
AssignedDateTime DATETIME NOT NULL,
--
CONSTRAINT Collaborator_PK PRIMARY KEY (CollaboratorId, OrganizationId, ProductNumber, JobNumber), -- Composite PRIMARY KEY.
CONSTRAINT CollaboratorToPerson_FK FOREIGN KEY (CollaboratorId)
REFERENCES Person (PersonId),
CONSTRAINT CollaboratorToJob_FK FOREIGN KEY (OrganizationId, ProductNumber, JobNumber) -- Multi-column FOREIGN KEY.
REFERENCES Job (OrganizationId, ProductNumber, JobNumber)
);
여러 테이블에 걸쳐 복합 PRIMARY KEY 제약 조건의 선언이 있음을 강조하는 것이 좋습니다. 이는 개념적 엔터티 유형간에 발생하는 연결 계층 구조, 예를 들어 SELECT를 표현할 때 데이터 검색과 관련하여 매우 유익한 배열을 나타냅니다. 파생 을 얻기 위해 JOIN 절을 포함하는 연산 테이블 .
예, (i) 모든 M : N 연관 및 (ii) 모든 관련 엔티티 유형은 (iii) 논리 DDL 구조의 해당 테이블로 표시되므로 PRIMARY 및 FOREIGN KEY 제약 조건 (및 이러한 개념적 요소를 나타내는 표를 주석으로 남겨 두었습니다. 관련 행 간의 연결이 해당 카디널리티 비율을 충족시키는 데 도움이되기 때문입니다.
EF Codd 는 복합 키의 사용법을 1970 년대의 대규모 공유 데이터 뱅크를위한 관계형 모델 (A 관계형 모델) 논문에 포함 된 예제에서 입증 된 관계형 패러다임의 기원에서 소개했습니다 . 소개했습니다. 개념적 M : N 연관을 처리하는 가장 우아한 방법).
db <> fiddle 과 SQL Fiddle을 넣었습니다 . 구조가 "행동"테스트 할 수 그래서, 마이크로 소프트 SQL 서버 2014 모두 실행.
표준화
정규화는 기본적으로 다음을 암시하는 논리 수준 절차입니다.
첫 번째 정규 형식을 통해 비 원자 열을 제거 하여 데이터 하위 언어 사용 (예 : SQL)으로 데이터 조작 및 수축을 훨씬 쉽게 처리 할 수 있습니다.
연속적인 일반 형식으로 인해 특정 테이블의 열 사이 에 바람직하지 않은 종속성을 제거하여 업데이트 이상 을 피할 수 있습니다.
당연히, 문제 가되는 테이블과 열에 의해 수반되는 의미 를 고려해야합니다 .
나는 표준화 가 과학에 기초한 테스트라고 생각하고 싶다 . 디자이너가 아이템이 일반적인 형태 중 하나를 따르는 지 여부를 결정하기 위해 안정적인 논리적 수준의 배열을 묘사하면 관련 요소에 적용한다는 것을 생각한다. 그런 다음 필요한 경우 설계자가 적절한 수정 조치를 취합니다.
여분
관계형 모델에서는 열에 포함 된 값의 복제가 허용 될뿐만 아니라 예상 되는 반면 중복 행은 금지 됩니다. 내가 볼 수있는 한, 이전에 노출 된 논리적 레이아웃에 포함 된 모든 테이블에서 중복 행과 다른 종류의 유해 중복성이 방지됩니다. 아마도 이와 관련하여 우려를 분명히하고 싶을 것입니다.
어쨌든, 당신은 확실히 (a) 요구 사항을 충족시키는 지 정의하고 (b) 필요한 경우 수정할 수 있도록 일반 양식을 통해 자신의 구조를 평가할 수 있습니다.
관련 자료
- 이 일련의 게시물 에서는 두 가지 다른 엔티티 유형 의 인스턴스를 상호 연관시킬 수있는 간단한 M : N 연관에 대한 몇 가지 심의를 제시 합니다.
- 에서는 이 다른 하나의 I는 I에 연결하는 방법을 설명하는 "빌 재료"또는 "부분 폭발"구조의 발생을 처리하기위한 방법을 제안 별개 의 인스턴스가 동일한 엔티티의 타입.
3 차 협회
주석을 통해 제기 된 또 다른 중요한 측면이 있습니다 (지금 삭제 된 답변에 게시 됨).
다리를 만들려고 할 때마다 다리의 요소도 다대 다를 갖습니다. 허용되지 않거나 적어도 낙담했습니다.
그러한 상황은 여러분의 관심사 중 하나가 개념적 삼항 협회 와 관련이있는 것으로 보입니다 . 기본적으로 말하자면, 이런 종류의 연관성은 (1) 두 개의 다른 관계를 포함하는 관계, 즉 "관계 사이의 관계"-관계가 그 자체로 실체이기 때문에 전형적인 상황이기도하다. —.
이러한 조치는 적절하게 관리 될 경우 유해한 중복성을 가져 오지 않습니다. 그렇습니다. 그러한 관계가 "실제"엔터티 유형에 존재한다는 것을 식별하는 특정 사용 사례가 있다면, (i) 모델을 만들고 (ii) 논리적 수준에서 정확하게 선언해야합니다.