복합 기본 키는 나쁜 습관입니까? [닫은]


14

복합 기본 키가 나쁜 습관인지 아닌지 알고 싶은 경우 어떤 시나리오를 사용하는 것이 좋습니다.

내 질문은이 기사를 기반으로합니다.

데이터베이스 디자인 실수

복합 기본 키에 대한 부분 :

실습 6 번 : 복합 기본 키

오늘날 많은 데이터베이스 설계자가 정수 ID 자동 생성 필드를 두 개 이상의 필드 조합으로 정의 된 복합 키 대신 기본 키로 사용하는 것에 대해 이야기하고 있기 때문에 이것은 논란의 여지가 있습니다. 이것은 현재 "모범 사례"로 정의되어 있으며 개인적으로 저는 이에 동의하는 경향이 있습니다.

복합 기본 키 이미지

그러나 이것은 단지 컨벤션 일뿐 아니라 DBE를 사용하면 많은 설계자가 피할 수 없다고 생각하는 복합 기본 키를 정의 할 수 있습니다. 따라서 중복성과 마찬가지로 복합 기본 키가 설계 결정입니다.

그러나 복합 기본 키가있는 테이블에 수백만 개의 행이있을 것으로 예상되면 복합 키를 제어하는 ​​인덱스가 CRUD 조작 성능이 매우 저하 될 정도로 커질 수 있습니다. 이 경우 인덱스가 충분히 간결하고 고유성을 유지하기 위해 필요한 DBE 제한 조건을 설정하는 간단한 정수 ID 기본 키를 사용하는 것이 훨씬 좋습니다.


4
이것은 "좋은"또는 "나쁜"연습이 아닙니다. 모든 디자인 결정은 목적에 부합해야합니다. 복합 PK가 필요한 이유를 (자신과 다른 사람들에게) 설명 할 수 있다면 잘 가십시오. 반대로, 왜 필요하지 않은지 설명 할 수 있다면 잘 가십시오. 당신이 연결하는 기사는 내 견해로는 설명이 매우 좋지 않습니다.
mustaccio

이 기사에서는 요점을 알 수 있지만 "모범 사례"에서 인기있는 프레임 워크 (예 : 레일)를 보면이 유형의 기본 키를 지원하지 않으므로 그 이유를 물었습니다. 그것은 기술적 인 어려움이나 다른 것을위한 것입니다.
hackvan

프레임 워크 디자인은 "단순한"단일 열 정수 기본 키만 지원하는 것이 더 쉽습니다. 그리고 대부분의 개발자는 (적어도 개인적인 경험으로는) 데이터베이스 기술 측면에서 (이 사이트의 사용자와 관련하여) 많은 것을 가지고 있지 않기 때문에 대부분의 소프트웨어 사용자에게 충분합니다. 대부분의 소프트웨어 사용자는 복합 키가 필요하지 않으며 (또는 최소한 시작시에는 필요하다고 생각하지 않기 때문에) 복합 키에 대한 (좋은) 지원을 제공하지 않아도됩니다.
Willem Renzema

1
INTEGER보다 GUID가 더 좋은 방법 [Serial | 자동 증분 | 정체성 | <whatever_integer_you_like>]?
Vérace

4
나는 그 저자를 고용하지 않을 것이다
paparazzo

답변:


31

말의 사용 "Composite keys as PRIMARY KEY is bad practice"은 전혀 말도 안된다!

합성물 PRIMARY KEY은 종종 매우 "좋은 것"이며 일상 생활에서 발생하는 자연 상황을 모델링하는 유일한 방법입니다!

학생들과 과정의 많은 전형적인 과정 인 Databases-101 교육 예제와 많은 학생들이 수강 한 많은 과정을 생각해보십시오!

테이블 코스와 학생 만들기 :

CREATE TABLE course
(
  course_id SERIAL,
  course_year SMALLINT NOT NULL,
  course_name VARCHAR (100) NOT NULL,
  CONSTRAINT course_pk PRIMARY KEY (course_id)
);


CREATE TABLE student
(
  student_id SERIAL,
  student_name VARCHAR (50),
  CONSTRAINT student_pk PRIMARY KEY (student_id)
);

PostgreSQL 방언 (및 MySQL ) 의 예 를 들겠습니다. 약간의 조정이 필요한 모든 서버에서 작동해야합니다.

지금, 당신은 분명 학생이 어떤 과정 복용하는 추적 할 - 당신이 불리는 것을 그래서 joining table(또한 linking, many-to-many또는 m-to-n테이블). 그들은 또한 associative entities더 전문적인 전문 용어 로 알려져 있습니다 !

1 코스에는 많은 학생들 이있을 있습니다.
1 명의 학생이 많은 코스를 수강 할 수 있습니다 .

따라서 조인 테이블을 만듭니다.

CREATE TABLE course_student
(
  cs_course_id INTEGER NOT NULL,
  cs_student_id INTEGER NOT NULL,

  -- now for FK constraints - have to ensure that the student
  -- actually exists, ditto for the course.

  CREATE CONSTRAINT cs_course_fk FOREIGN KEY (cs_course_id) REFERENCES course (course_id),
  CREATE CONSTRAINT cs_student_fk FOREIGN KEY (cs_student_id) REFERENCES student (student_id)
);

이제이 표를 현명하게 줄 수 있는 유일한 방법 은 코스와 학생의 조합 PRIMARY KEY을 만드는 것입니다 KEY. 그렇게하면 얻을 수 없습니다 :

  • 학생과 코스 조합의 사본

    • 코스는 같은 학생을 한 번만 등록 할 수 있으며

    • 학생은 같은 코스에 한 번만 등록 할 수 있습니다

  • 당신은 또한 기성품 검색이 KEY일명 - 학생 당 과정에 포함하는 인덱스를 ,

  • 학생들과 과정을 수강하지 않는 학생들이없는 과정을 찾는 것은 사소한 일입니다!

    -db-fiddle 예제 에는 PK 제약 조건이 CREATE TABLE로 접혀져 있습니다. 어느 쪽이든 수행 할 수 있습니다. CREATE TABLE 문에 모든 것을 포함하고 싶습니다.


ALTER TABLE course_student 
ADD CONSTRAINT course_student_pk 
PRIMARY KEY (cs_course_id, cs_student_id);

이제 코스 별 학생 검색이 느리다는 것을 발견 한 경우 UNIQUE INDEXon (sc_student_id, sc_course_id)을 사용할 수 있습니다.

ALTER TABLE course_student 
ADD CONSTRAINT course_student_sc_uq  
UNIQUE (cs_student_id, cs_course_id);

없습니다 에는 그들이 - 인덱스를 추가하기위한 묘책이 됩니다 만들 INSERT들과 UPDATE느린이야,하지만 상당히의 큰 이익의 감소SELECT 배! 지식과 경험을 바탕으로 색인을 생성하기로 결정하는 것은 개발자의 몫입니다. 그러나 합성물 PRIMARY KEY항상 나쁘다는 것은 명백한 잘못입니다.

테이블을 조인하는 경우 일반적으로 유일 PRIMARY KEY 하게 의미가 있습니다! 또한 조인 테이블은 비즈니스 나 자연 또는 내가 생각할 수있는 거의 모든 분야에서 일어나는 일을 모델링하는 유일한 방법입니다.

이 PK는 covering index검색 속도를 높이는데도 유용 합니다. 이 경우, 정기적으로 검색하는 경우 (course_id, student_id) 종종 유용 할 수 있습니다.

이것은 컴포지트 PRIMARY KEY가 아주 좋은 아이디어가 될 수 있는 작은 예이며 현실을 모델링하는 유일한 방법입니다! 머리 꼭대기에서 더 많은 것을 생각할 수 있습니다 .

내 작품의 예!

flight_id, 출발 및 도착 공항 목록 및 관련 시간이 포함 된 비행 테이블과 승무원이있는 cabin_crew 테이블을 고려하십시오!

이 모델링 할 수 있습니다 제정신 방법은 flight_id 및 attibutes로 crew_id 유일한 제정신으로 flight_crew 테이블을 갖는 것은 PRIMARY KEY두 분야의 복합 키를 사용하는 것입니다!


2
과정과 학생의 예에서 course_student가 id기본 키와 고유 색인을 cs_student_id cs_course_id가지고 동일한 결과를 가질 수 있습니까?
hackvan

2
왜 자원을 낭비합니까? PK (course_id, student_id)를 사용하면 정의 에 따라 해당 필드에 대한 고유 색인이 이미 있습니다! (student_id, course_id)에 대한 고유 색인은 검색 속도를 높이는 데 사용될 수 있습니다. 코스를 수강하지 않은 학생을 찾고 있었지만 그 결정이 운영적일 수 있지만 현재는 비교적 저렴한 저장 용량, 특히 테이블이 자주 업데이트되지 않을 것이라고 생각하기 때문에 다시 권장합니다.
Vérace

1
링크 테이블에 대해 완전히 동의하십시오-지금 여러 가지 작업을하고 있습니다. 그러나 C # 모자를 착용하면 reversepoco generator로 작업하고 다음 계층에 유용한 클래스 (찾기, 저장 등)를 작성하고 있습니다. 나는 중요한 문제에 봉착했다-복합 키는 일반적인 저장 / 찾기 코드를 갖는 PITA가된다. 예, 아마도 EDMX 파일로 돌아갈 수는 있지만 여전히 특수 사례 코드 (Pkey 열 수?)를 해결하거나 인공 대리 키를 추가해야합니다 (추가 고유성 제약 조건이 마음에 들지 않고 필요합니다 :()). 합성물을 좋아하지 않는 사람들은 앱 레이어 코드
Richard Griffiths

인서트 빈도와 인덱스 조각 모음 빈도 vs 유지 보수 기간에 따라이 방법이 더 좋습니다. 그러나 일부 디자인 선택은 즉시 보이지 않을 수있는 요구 사항으로 인해 타협됩니다. 그러나 한 의견에서 언급했듯이 두 시나리오의 장단점을 식별하고 설계를 선택하십시오.
Jonathan Fite

학생이 과정을 반복하면 어떻게됩니까? 그런 다음 시간으로 분리 된 코스가 다른 ID를 얻지 않으면 다른 매핑 테이블이 있습니다. 또는 코스 날짜 필드를 추가하여 키에 추가해야합니다.
iheanyi

3

반 교육을받은 테이크 : "기본 키"는 테이블에서 데이터를 조회하는 데 사용되는 유일한 고유 키일 필요는 없지만 데이터 관리 도구는 기본 선택으로 제공합니다. 따라서 두 열의 복합 또는 테이블 키로 임의의 (아마도 일련의) 생성 된 숫자를 가질 지 여부를 선택하기 위해 한 번에 두 개의 다른 키를 가질 수 있습니다.

데이터 값에 행을 나타낼 수있는 적절한 고유 용어가 포함 된 경우 복합적인 경우에도 "합성"키를 사용하는 것보다 "기본 키"로 선언하고 싶습니다. 합성 키는 기술적 인 이유로 더 나은 성능을 발휘할 수 있지만 서비스를 작동시키기 위해 다른 방법으로 갈 필요가없는 한 실제 용어를 기본 키로 지정하고 사용하는 것이 기본 선택입니다.

Microsoft SQL Server에는 "클러스터형 인덱스"의 고유하지만 관련 기능이있어 인덱스 순서로 데이터의 물리적 저장소를 제어하며 다른 인덱스 내부에서도 사용됩니다. 기본적으로 기본 키는 클러스터형 인덱스로 만들어 지지만 클러스터형 인덱스를 만든 후에 클러스터되지 않은 것을 선택할 수 있습니다. 따라서 정수 ID 생성 열을 클러스터형 인덱스로, 파일 이름 nvarchar (128 자)를 기본 키로 사용할 수 있습니다. 파일 이름을 다른 테이블에 외래 키 용어로 저장하더라도 클러스터 된 인덱스 키가 좁기 때문에이 방법이 더 나을 수 있습니다.이 예제도 그렇게하지 않는 것이 좋습니다.

설계에 관련 데이터를 식별하기 위해 불편한 기본 키가 포함 된 데이터 테이블을 가져 오는 것이 포함되어 있다면 그 문제에 거의 얽매이지 않습니다.

https://www.techopedia.com/definition/5547/primary-key 는 고객의 소셜 시큐리티 번호가있는 데이터를 모든 데이터 테이블에 고객 키로 저장할지 또는 사용자가 임의의 customer_id를 생성 할 것인지 선택하는 예를 설명합니다. 등록하십시오. 실제로 이것은 작동 여부에 관계없이 SSN을 심각하게 남용합니다. 개인 및 기밀 데이터 가치입니다.

따라서 실제 사실을 핵심으로 사용하면 "고객"테이블에 다시 연결하지 않고도 다른 테이블에서 정보를 검색 할 수 있지만 데이터 보안 문제이기도합니다.

또한 SSN 또는 기타 데이터 키가 잘못 기록 된 경우 문제가 발생하므로 "고객"이 아닌 20 개의 제한된 테이블에 잘못된 값이 있습니다. 합성 customer_id는 외부 의미가 없으므로 잘못된 값이 될 수 없습니다.


1
특히 고객 데이터에 따라 키, 알려진 고유 고객 데이터 (여기서는 SSN)가 해당 데이터를 수정해야하는 경우 고장이났다는 관찰에 감사드립니다.
ToolmakerSteve
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.