복합 기본 키가 여전히 존재하는 이유는 무엇입니까?
저는 데이터베이스를 중급 ERP로 마이그레이션하도록 지정되었습니다. 새로운 시스템은 여기저기서 복합 기본 키를 사용하며 실용적인 관점에서 볼 때 그 이유는 무엇입니까?
자동 생성 된 ID에 비해 부정적인 측면 만 볼 수 있습니다.
- 외래 키가 흐릿 해짐
- 더 어려운 마이그레이션 또는 DB 재 설계
- 비즈니스 변화에 따라 유연하지 않습니다. (내 차에는 등록 번호판이 없습니다 ..)
- 제약 조건을 통해 동일한 무결성을 더 잘 얻을 수 있습니다.
그것은 후보 키의 디자인 컨셉으로 되돌아 가고 있습니다.
플로피 시대 (공간 / 인덱스 최소화)의 습관 / 유물입니까? 아니면 뭔가 빠졌습니까?
// edit // 방금 좋은 SO-post를 찾았습니다 : 복합 기본 키 대 고유 개체 ID 필드 //
개인적으로 저는 대리 키 사용을 선호합니다. 그러나 (다 대다 관계를 만들기 위해) 다른 두 테이블의 ID로만 구성된 테이블을 조인 할 때 복합 키가 사용되기 때문에 제거하기가 더 어려워집니다.
대리 키는 항상 나쁘고 자연 키를 사용하여 기록 할 고유성이 없으면 디자인이 나쁘다는 생각이 많이 있습니다. 나는 이것에 강하게 동의하지 않는다 (SSN이나 다른 고유 한 값을 저장하지 않는 경우, 예를 들어 사람 테이블에 대한 자연 키를 제시하는 것을 거부합니다.) 그러나 많은 사람들은 적절한 정규화에 필요하다고 생각합니다.
때때로 복합 키가 있으면 다른 테이블에 조인 할 필요가 줄어 듭니다. 때로는 그렇지 않습니다. 따라서 복합 키가 성능을 향상시킬 수있을뿐만 아니라 성능을 저하시킬 수있는 경우도 있습니다. 키가 상대적으로 안정적인 경우 선택 쿼리에서 더 빠른 성능을 사용할 수 있습니다. 그러나 회사 이름처럼 변경 될 수있는 것이면 회사 A가 이름을 변경하고 백만 개의 관련 레코드를 업데이트해야 할 때 상처를 입을 수 있습니다.
데이터베이스 디자인에 모두 맞는 하나의 크기는 없습니다. 복합 키가 도움이 될 때와 끔찍할 때가 있습니다. 서로 게이트 키가 도움이되는 경우가 있고 그렇지 않은 경우가 있습니다.
복합 키는 기본 키가 대리가 아니고 본질적으로 복합, 즉 여러 비 관련 부분으로 분리 될 수있는 경우에 필요합니다.
실제 사례 :
기본 키가 관련된 엔터티의 키로 구성된 다 대다 링크 테이블.
다중 테넌트 응용 프로그램
tenant_id
은 각 엔터티의 기본 키의 일부이고 엔터티는 동일한 테넌트 내에서만 연결될 수 있습니다 (외래 키로 제한됨).타사 데이터를 처리하는 애플리케이션 (이미 제공된 기본 키 사용)
논리적으로이 모든 작업은 UNIQUE
제약 조건 (대리자에 추가)을 사용하여 달성 할 수 있습니다 PRIMARY KEY
.
그러나 구현과 관련된 몇 가지 사항이 있습니다.
일부 시스템은이 못하게
FOREIGN KEY
하지 않은 아무것도를 참조하십시오PRIMARY KEY
.일부 시스템은에서 테이블 만 클러스터링
PRIMARY KEY
하므로 복합을 만들면 복합에PRIMARY KEY
조인하는 쿼리의 성능이 향상됩니다.
복합 기본 키 는 다른 테이블에서 외래 키로 사용되는 경우 더 나은 성능을 제공 하고 테이블 읽기를 줄 입니다. 때로는 생명을 구할 수 있습니다. 대리 키를 사용하는 경우 해당 테이블로 이동하여 자연 키 정보를 가져와야합니다.
예를 들어 (순수한 예-여기서는 DB 디자인에 대해 이야기하지 않습니다) ORDER
테이블과 ORDER_ITEM
. 당신이 사용하는 경우 ProductId
와 LineNumber
( UPDATE : 페드로가 언급 한 바와 같이 OrderId
또는 더 나은 OrderNumber
) 복합 기본 키로 ORDER_ITEM
대한 교차 표에 다음 SHIPPING
, 당신은에 제품 ID를 가질 수있을 것입니다 SHIPPING_ORDERITEM
. 예를 들어 해당 제품이 부족 ProductId
하여 가입 할 필요없이 배송해야하는 모든 제품을 찾아야하는 경우 이렇게하면 성능이 크게 향상 될 수 있습니다.
반면에 서로 게이트 키를 사용하는 경우 조인해야 하고 여러 인덱스에 대한 책갈피 조회 를 수행해야하는 매우 비효율적 인 SQL 실행 계획이 생깁니다.
참조 더 에 책갈피 조회 대용 키를 사용하는 것은 큰 문제가된다.
자연적인 기본 키는 깨지기 쉽습니다.
(CountryCode, PhoneNumber)에 대한 자연 PK를 중심으로 시스템을 구축하고 몇 년 후에 Extension을 추가하거나 PK를 하나의 열인 Email로 변경해야한다고 가정 해 보겠습니다. 이러한 PK 열이 모든 하위 테이블에 전파되면 비용이 많이 듭니다.
몇 년 전 소셜 시큐리티 번호가 자연적인 PK라고 가정하고 SSN이 고유하지 않고 무효화 될 때 신원을 사용하도록 재 설계해야하는 일부 시스템이있었습니다.
우리는 미래를 예측할 수 없기 때문에 나중에 어떤 변화가 완벽하게 정확하고 완전한 모델이었던 것을 쓸모 없게 만들지 알지 못합니다.
매우 간단한 대답은 데이터 무결성입니다. 데이터가 유용하고 정확하려면 키가 필요합니다. "자동 생성 된 ID"가 있다고해서 다른 키에 대한 요구 사항도 제거되지는 않습니다. 대안은 고유성을 강요하지 않고 데이터가 복제되고 거의 불가피하게 이상을 포함하고 결과적으로 오류를 초래할 것이라는 점을 받아들이는 것입니다. 왜 그걸 원 하겠어요?
간단히 말해서 복합 키의 목적은 데이터베이스를 사용하여 하나 이상의 비즈니스 규칙을 적용하는 것입니다. 즉, 데이터의 무결성을 보호하십시오.
전의. 공급 업체로부터 구매 한 부품 목록이 있습니다. 다음과 같이 공급 업체 및 부품 테이블을 만들 수 있습니다.
SUPPLIER
SupplierId
SupplierName
PART
PartId
PartName
SupplierId
어 오. 부품 테이블은 중복 데이터를 허용합니다. 자동 생성 된 대리 키를 사용했기 때문에 공급 업체의 부품을 한 번만 입력해야한다는 사실을 적용하지 않습니다. 대신 다음과 같이 PART 테이블을 만들어야합니다.
PART
SupplierId
SupplierPartId
PartName
이 예에서 부품은 특정 공급 업체에서 제공되며 PARTS 테이블에서 "단일 공급 업체는 단일 부품을 한 번만 공급할 수 있습니다"라는 규칙을 적용하려고합니다. 따라서 복합 키입니다. 복합 키는 실수로 부품을 중복 입력하는 것을 방지합니다.
비즈니스 규칙은 항상 데이터베이스에서 제외하고 애플리케이션에 남겨 둘 수 있지만, 데이터베이스에 규칙을 유지하면 (복합 키를 통해) 비즈니스 규칙이 모든 곳에서 적용됩니다. 특히 허용하기로 결정해야하는 경우 더욱 그렇습니다. 데이터에 액세스하는 여러 응용 프로그램.
Just as functions encapsulate a set of instructions, or database views abstract base table connections, so to do surrogate keys abstract the meaning of the entity they are placed on.
If, for example, you have a table that holds vehicle data, applying a surrogate VehicleId abstracts what it means to be a vehicle from a data point of view. When you reference VehicleId = 1, you are most surely talking about a vehicle of some sort, but do we know if it is a 2008 Chevy Impala, or a 1991 Ford F-150? No. Can the underlying data of whatever Vehicle #1 is change at any time? Yes.
Short answer: Multi-column foreign keys naturally refer to multi column primary keys. There can still be an autogenerated id column that is part of the primary key.
Philosophical answer: Primary key is the identity of the row. If there there is a bit of information that is an intrinsic part of the identity of the row (such as which customer the article belongs to.. in a multi customer wiki) - The information should be part of the primary key.
An example: System for organizing LAN parties
The system supports several LAN parties with the same people and organizers attending thus:
CREATE TABLE users ( users_id serial PRIMARY KEY, ... );
And there are several parties:
CREATE TABLE parties ( parties_id serial PRIMARY KEY, ... );
But most of the other stuff needs to carry the information about which party it is linked to:
CREATE TABLE ticket_types (
ticket_types_id serial,
parties_id integer REFERENCES parties,
name text,
....
PRIMARY KEY(ticket_types_id, parties_id)
);
...this is because we want to refer to primary keys. Foreign key on table attendances points to table ticket_types.
CREATE TABLE attendances (
attendances_id serial,
parties_id integer REFERENCES parties,
ticket_types_id integer,
PRIMARY KEY (attendances_id, parties_id),
FOREIGN KEY (ticket_types_id, parties_id) REFERENCES parties
);
While I prefer surrogate keys, I use composite cases in a few cases. The composite key may consist entirely or partially of surrogate key fields.
- Many to many join tables. These usually require a unique key on the key pair anyway. In some cases additional columns may be included in the key.
- Weak child tables. Things like order lines do not stand on their own. In this case I use the parent (orders) tables primary key in the composite table.
When there are multiple weak tables related to an entity, it may be possible to eliminate a table from the join set when querying child data. In the case of grandchild tables, it is possible to join the grandparent to grandchild without involving the table in the middle.
참고URL : https://stackoverflow.com/questions/5406037/why-are-composite-primary-keys-still-around
'Programing' 카테고리의 다른 글
C #의 정적 메서드에서 비 정적 메서드를 호출하려면 어떻게해야합니까? (0) | 2020.12.10 |
---|---|
DateTime.Parse가 UTC 날짜를 구문 분석 할 수없는 이유 (0) | 2020.12.10 |
$ _GET이 있는지 확인하는 방법은 무엇입니까? (0) | 2020.12.10 |
조각 관리자에서 오래된 조각 제거 (0) | 2020.12.10 |
Swift를 사용하여 하나의 ViewController에서 강제 가로 모드 (0) | 2020.12.10 |