모든 테이블에 ID 열이 있으므로 Rails로 새 앱을 작성하고 있습니다. 외래 키를 사용하여 도메인 제약 조건을 강제 적용하는 가장 좋은 방법은 무엇입니까? 나는 내 생각과 좌절을 설명 할 것이다.서로 게이트 키가있을 때 도메인 제약 조건에 대해 복합 외래 키를 어떻게 정의해야합니까?
다음은 "The Rails Way"라고 생각합니다. 그것은 내가 시작한 것입니다.
Companies:
id: integer, serial
company_code: char, unique, not null
Invoices:
id: integer, serial
company_id: integer, not null
Products:
id: integer, serial
sku: char, unique, not null
company_id: integer, not null
LineItems:
id: integer, serial
invoice_id: integer, not null, references Invoices (id)
product_id: integer, not null, references Products (id)
이 문제는 한 회사의 제품이 다른 회사의 인보이스에 나타날 수 있다는 점입니다. LineItems에 (company_id : 정수, null이 아님)을 추가했습니다. 일종의 자연 키와 연쇄를 사용하고 복합 외래 키를 추가하면됩니다.
LineItems (product_id, company_id) references Products (id, company_id)
LineItems (invoice_id, company_id) references Invoices (id, company_id)
이 제대로 한 회사에 LineItems을 제한하지만 과잉 설계와 잘못된 것 같다. 서로 게이트 외래 키가 이미 외부 테이블에서 고유하기 때문에 LineItems의 company_id는 관계가 없습니다. Postgres는 참조 된 속성에 대한 고유 색인을 추가해야하므로 ID가 단순히 고유하더라도 제품 및 송장의 고유 색인 (id, company_id)을 만듭니다.
자연 키와 이미 고유 인덱스를 가지고 있으므로 참조 된 열은 자연 키가 이미 있기 때문에이 복잡성을 추가하지 않았을 시리얼 송장 번호와 다음 표.
LineItems:
company_code: char, not null
sku: char, not null
invoice_id: integer, not null
LineItems 테이블의 서로 게이트 키를 무시할 수 있지만 잘못된 것으로 보입니다. 왜 데이터베이스에 이미 정수가 있으면 char에 데이터베이스를 조인할까요? 또한 위와 똑같이 수행하면 Products and Invoices에 자연스러운 외래 키인 company_code를 추가해야합니다.
타협 ...
LineItems:
company_id: integer, not null
sku: integer, not null
invoice_id: integer, not null
은 다른 테이블에서 자연 외래 키를 필요로하지 않고 사용할 수있는 정수가있을 때 여전히 문자에 합류한다.
하나님이 의도처럼 외래 키와 도메인 제약 조건을 적용 할 수있는 깨끗한 방법이 있나요하지만 대리의 존재, 복잡한 혼란에 스키마 및 인덱스를 켜지 않고?