외래 키에 널 입력 가능 필드를 사용하고 있기 때문에 실제로 예상 한대로 올바르게 작동하는 시스템을 구성 할 수 있습니다. Accounts 테이블에 행을 삽입하려면 null PrimaryContactID를 사용하여 Accounts에 삽입을 허용하지 않는 한 Contacts 테이블에 행이 있어야합니다. 계정 행이없는 상태에서 연락처 행을 만들려면 연락처 테이블의 AccountID 열이 Null을 허용해야합니다. 이를 통해 계정에 연락처가없고 연락처에 계정이 없어도됩니다. 아마도 이것이 바람직하지 않을 수도 있습니다.
내가 개인적으로 선호하는 것은 다음과 같이 설정하는 것입니다.
CREATE TABLE dbo.Accounts
(
AccountID INT NOT NULL
CONSTRAINT PK_Accounts
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, AccountName VARCHAR(255)
);
CREATE TABLE dbo.Contacts
(
ContactID INT NOT NULL
CONSTRAINT PK_Contacts
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, ContactName VARCHAR(255)
);
CREATE TABLE dbo.AccountsContactsXRef
(
AccountsContactsXRefID INT NOT NULL
CONSTRAINT PK_AccountsContactsXRef
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, AccountID INT NOT NULL
CONSTRAINT FK_AccountsContactsXRef_AccountID
FOREIGN KEY REFERENCES dbo.Accounts(AccountID)
, ContactID INT NOT NULL
CONSTRAINT FK_AccountsContactsXRef_ContactID
FOREIGN KEY REFERENCES dbo.Contacts(ContactID)
, IsPrimary BIT NOT NULL
CONSTRAINT DF_AccountsContactsXRef
DEFAULT ((0))
, CONSTRAINT UQ_AccountsContactsXRef_AccountIDContactID
UNIQUE (AccountID, ContactID)
);
CREATE UNIQUE INDEX IX_AccountsContactsXRef_Primary
ON dbo.AccountsContactsXRef(AccountID, IsPrimary)
WHERE IsPrimary = 1;
이것은 다음과 같은 기능을 제공합니다.
- Pieter가 답변에서 권장하는 방식을 상호 참조 표를 통해 연락처와 계정 간의 관계를 명확하게 설명
- 비순환 적으로 건전한 참조 무결성을 유지하십시오.
- 색인을 통해 유지 관리가 용이 한 기본 연락처 목록을 제공하십시오
IX_AccountsContactsXRef_Primary
. 이 인덱스에는 필터가 포함되어 있으므로이를 지원하는 플랫폼에서만 작동합니다. 이 색인은 UNIQUE
옵션 으로 지정되므로 각 계정에 대해 하나의 기본 담당자 만있을 수 있습니다.
예를 들어, "기본"상태를 나타내는 열과 함께 모든 계정 목록을 표시하려면 각 계정의 목록 맨 위에 기본 연락처를 표시하십시오.
SELECT A.AccountName
, C.ContactName
, XR.IsPrimary
FROM dbo.Accounts A
INNER JOIN dbo.AccountsContactsXRef XR ON A.AccountID = XR.AccountID
INNER JOIN dbo.Contacts C ON XR.ContactID = C.ContactID
ORDER BY A.AccountName
, XR.IsPrimary DESC
, C.ContactName;
필터링 된 인덱스는 계정 당 하나 이상의 기본 연락처를 삽입하는 것을 방지하는 동시에 기본 연락처 목록을 신속하게 반환하는 방법을 제공합니다. IsActive
연락처가 더 이상 계정과 연결되지 않은 후에도 계정별로 연락처 기록을 유지하기 위해 고유하지 않은 필터링 된 인덱스를 사용하여 다른 열을 쉽게 상상할 수 있습니다 .
ALTER TABLE dbo.AccountsContactsXRef
ADD IsActive BIT NOT NULL
CONSTRAINT DF_AccountsContactsXRef_IsActive
DEFAULT ((1));
CREATE INDEX IX_AccountsContactsXRef_IsActive
ON dbo.AccountsContactsXRef(IsActive)
WHERE IsActive = 1;