1

모든 테이블에 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 

은 다른 테이블에서 자연 외래 키를 필요로하지 않고 사용할 수있는 정수가있을 때 여전히 문자에 합류한다.

하나님이 의도처럼 외래 키와 도메인 제약 조건을 적용 할 수있는 깨끗한 방법이 있나요하지만 대리의 존재, 복잡한 혼란에 스키마 및 인덱스를 켜지 않고?

답변

1

id는 이미 고유하지만 id, company_id는 고유 항목 1 개만 참조하고 다른 항목은 참조하지 않아야하는 FK 참조에서 사용하기 때문에 고유 ID를 사용해야합니다.

난 당신이 데이터를 '보호'하려는 이해하지만이이 과도하게 설계되었습니다 말을 당신과 함께 동의 할 것입니다. 이 데이터를 사용하고 제대로 작동하지 않는 시스템 (회사에 맞는 올바른 제품을 가져 오는 시스템)은 즉시 눈에.니다. 프로그래밍 할 때 더 많은 데이터를 처리해야 할 부담이 있으며 일을 혼란스럽게 만들 수 있습니다.

나는 데이터를 보호하기위한 노력을 좋아하지만, 비용은 더 많은 데이터를 얻을하고보다 복잡한 데이터 모델의 추가 부담이 확실히 존재하는 한 방법으로 높은 것으로 성장할 수 있습니다.

데이터가 응용 프로그램에서 '자연스러운'사용을 통해 충분히 보호되고 있다고 생각합니다. 새 인보이스를 만들고 인보이스에 넣을 제품을 찾고있을 때 인보이스 작성과 동일한 회사 ID를 사용하여 제품을 검색하게됩니다. 어떻게 든 잘못된 ID를 얻으면 (나쁜 코드, DB에 직접있는 사용자) 나쁜 결과가 즉시 눈에 띄게됩니다.

게시물의 두 번째 부분을 이해하지 못합니다. 간단하고 표준화 된 스키마를 만드는 대신 복잡한 경로를 따라 내려가는 것처럼 보입니다.

왜 비 감각 키를 넣을 까 걱정합니까? 사용자가 비표준 방식으로이 데이터에 액세스하게 하시겠습니까?