복합 기본 키를 올바르게 작성하는 방법-MYSQL


182

여기에 내가 작업하고있는 강렬한 설정이 지나치게 단순화되었습니다. table_1그리고 table_2모두는 ID로 자동 증가 대리 기본 키를 가지고있다. 및 info에 대한 정보가 포함 된 테이블입니다 .table_1table_2

table_1 (id, field)  
table_2 (id, field, field)
info ( ???, field)

난의 기본 키해야하는 경우 결정하려고 info에서 ID의 합성을 table_1하고 table_2. 이 작업을 수행 할 경우이 중 가장 적합한 것은 무엇입니까?
(이 예에서는 ID 11209와 ID 437을 결합하고 있습니다)

INT(9)11209437 (이것이 왜 나쁜지 상상할 수 있습니다)
VARCHAR (10) 11209-437
DECIMAL (10,4)11209.437

또는 다른 것?

이것을 MYSQL MYISAM DB의 기본 키로 사용하는 것이 좋습니까?


답변:


343

복합 (다열) 키를 사용합니다.

CREATE TABLE INFO (
    t1ID INT,
    t2ID INT,
    PRIMARY KEY (t1ID, t2ID)
) 

이 방법으로 t1ID 및 t2ID를 해당 테이블을 가리키는 외래 키로 사용할 수 있습니다.


2
와우 그래서 그것은 당신이 복합 키를 만드는 방법입니다! 내가 개념을 완전히 오해 한 것 같습니다. 감사합니다!! 따라서 이와 같은 것은 전적으로 색인 작성을위한 것이며 맞습니까? 이 컴포지트를 사용하여 레코드를 참조 할 수 없으므로 여전히 그렇게해야 UPDATE info ... WHERE t1ID=11209 AND t2ID=437합니까?
filip

2
옳은. 두 열이 모두 고유해야하지만 t1ID = 11209이면 충분합니다.
AlexCuse

39
@AlexCuse 두 열의 조합 은 고유하지만 t1ID = 11209의 경우 여러 t2ID가있을 수 있습니다.
e18r

21

"info"테이블의 기본 키를 다른 테이블의 두 값을 합성하지 않습니다.

다른 사람들은 그 이유를 더 잘 설명 할 수 있지만 실제로 두 가지 정보로 구성된 열을 갖는 것은 잘못된 느낌입니다. 어떤 이유로 두 번째 테이블의 ID를 정렬하려면 어떻게합니까? 두 테이블의 값이 존재하는 횟수를 세려면 어떻게해야합니까?

나는 항상 이것을 두 개의 별개의 열로 유지합니다. mysql ... PRIMARY KEY (id_a, id_b)에서 2 열 primay 키를 사용할 수 있지만 2 열 고유 인덱스를 사용하고 자동 증가 기본 키 필드를 선호합니다.


1
별개의 열을 유지하는 것은 절대적으로 옳습니다. 나는 당신이 2 열의 고유 인덱스를 가질 수 있다는 것을 알지 못했고 그것이 실제로 나에게 좋은 옵션이라고 생각합니다. 기본 키를 자동 증분으로 유지하는 것을 선호하는 이유는 무엇입니까?
filip

3
나는 정말로 설득력있는 이유가 없으며, 이것이 적은 열을 갖는 것이 더 경제적이기 때문에 이것이 나와 내 동료들 사이의 논쟁의 포인트라고 생각합니다. 단일 외래 키에 조인을 작성하는 것이 더 쉽다는 것을 알았습니다. 때때로 이러한 테이블 "두 테이블 간 매핑"의 중요성이 원래 테이블만큼 중요 해지고 기본 키는 다른 테이블에서 외래 키 열이됩니다.
wmorse

감사합니다. 나는 당신의 말이 많은 의미가 있다고 생각하며 2 열의 고유 인덱스 + 자동 증가 기본 키로 시도 할 것입니다.
Filip

1
내 머리 꼭대기에서 당신이 관계 테이블을 만들고 싶기 때문이라고 생각합니다. 마켓 플레이스, 통화 및 제공자와 같은 세 개의 테이블이 있으며, 제공자는 마켓 플레이스 ONCE에만 존재할 수 있으므로 관계 테이블은 단일 통화 만 제공 할 수 있으므로 합성 (id_market, id_provider) 만 가능합니다. 같은 시장과 공급자를 다시 추가하려고 시도하면 연결이 실패합니다. 즉, 고유하다는 의미입니다. 그러면 두 번째 열이 있습니다. id_currency는 통화가 전체 테이블에서 단수임을 의미합니까?
Christopher Thomas

1
이 스레드를 나중에 본 사람에게는 이것이 나쁜 습관 인 이유는 데이터베이스 디자인의 매우 기본적인 원칙을 위반하기 때문입니다. 첫 번째 정규 양식에는 모든 정보에 고유 한 열이 있어야합니다. 이를 위반할 이유가 없으며 데이터베이스 구조를 정상화 할 때 여러 가지 이점이 있습니다.
smcjones

15

구문은 CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)예를 들어 ::

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

위의 예제는 테이블을 만드는 동안 작성하는 경우 작동합니다.

CREATE TABLE person (
   P_Id int ,
   ............,
   ............,
   CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);

기존 테이블에이 제한 조건을 추가하려면 다음 구문을 따라야합니다.

ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)

8

이미 테이블을 생성했다고 가정하면이 쿼리를 사용하여 복합 기본 키를 만들 수 있습니다

alter table employee add primary key(emp_id,emp_name);

5

개인 디자인 환경 설정 외에도 복합 기본 키를 사용하려는 경우가 있습니다. 테이블에는 고유 한 조합을 제공하는 두 개 이상의 필드가있을 수 있으며 반드시 외래 키를 사용할 필요는 없습니다.

예를 들어, 각 미국 주에는 고유 한 의회 지구가 있습니다. 많은 주에서 개별적으로 CD-5가있을 수 있지만 50 개 주 중 하나에 CD-5가 두 개 이상 존재하지 않으며 그 반대도 마찬가지입니다. 따라서 매사추세츠 CD-5에 대한 자동 번호 필드를 만드는 것은 중복됩니다.

데이터베이스가 동적 웹 페이지를 구동하는 경우 두 필드 조합에서 쿼리 할 코드를 작성하는 것이 자동 번호 매기기 키를 추출 / 다시 제출하는 것보다 훨씬 간단 할 수 있습니다.

따라서 원래의 질문에 대답하지는 않지만 Adam의 직접적인 답변에 감사드립니다.


4

복합 기본 키는 팩트 테이블과 다 대 다 관계를 작성하려는 위치입니다. 예를 들어, 여러 속성이 포함 된 휴가 용 렌탈 패키지가있을 수 있습니다. 반면에, 본 숙소는 단독으로 또는 다른 숙박 시설과 함께 여러 임대 패키지의 일부로 이용 가능합니다. 이 시나리오에서는 속성 / 패키지 팩트 테이블을 사용하여 속성과 임대 패키지 간의 관계를 설정합니다. 속성과 패키지 간의 연결은 고유하며 property_id를 속성 테이블과 함께 사용하거나 package_id를 패키지 테이블과 함께 사용하여 조인 할 수 있습니다. 각 관계는 고유하며 auto_increment 키는 다른 테이블에 표시되지 않으므로 중복됩니다. 따라서 복합 키를 정의하는 것이 답입니다.


1
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);

1

@AlexCuse 나는 이것을 당신의 답변에 주석으로 추가하고 싶었지만 주석에 줄 바꿈을 추가하려고 여러 번 실패한 후에 포기했습니다.

즉, t1ID는 table_1에서 고유하지만 INFO 테이블에서도 고유하지 않습니다.

예를 들면 다음과 같습니다.

된 table_1을 가지고
이드 필드
1 A
2 B

Table_2 has :
ID 필드
1 X
2 Y

INFO는 다음을 가질 수 있습니다.
t1ID t2ID 필드
1 1 some
1 2 data
2 1 in-each
2 2 row

따라서 INFO 테이블에서 행을 고유하게 식별하려면 t1ID와 t2ID가 모두 필요합니다.


그것의 복합 키
Pavel P

1
@PavelP 내 대답은 Alex의 의견입니다. "t1ID = 11209이면 충분할 것입니다. ... 복합 키를 사용하는 것이 정확하지만 정확한 일치를 식별하려면 t1ID와 t2ID가 모두 필요하다는 데 동의합니다 ... 지금 명확 해지기를 바랍니다.
sactiw
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.