[database] 단일 테이블에 여러 개의 기본 키를 가질 수 있습니까?

단일 테이블에 여러 개의 기본 키를 가질 수 있습니까?



답변

테이블에는 두 개 이상의 열로 만들어진 기본 키인 복합 기본 키 가있을 수 있습니다 . 예를 들면 다음과 같습니다.

CREATE TABLE userdata (
  userid INT,
  userdataid INT,
  info char(200),
  primary key (userid, userdataid)
);

업데이트 : 복합 기본 키에 대한 자세한 설명 이있는 링크 가 있습니다.


답변

기본 키는 하나만 가질 수 있지만 기본 키에는 여러 열이있을 수 있습니다.

테이블에 고유 인덱스를 가질 수도 있습니다. 고유 인덱스는 고유 값을 적용하고 해당 값을 빠르게 쿼리 할 수 ​​있다는 점에서 기본 키와 약간 비슷합니다.


답변

테이블에는 여러 개의 후보 키가있을 수 있습니다. 각 후보 키는 UNIQUE이며 함께 사용되며 NOT NULL 인 열 또는 열 집합입니다. 따라서 후보 키의 모든 열에 대한 값을 지정하면 기준을 충족하는 행이 하나 있거나 전혀 행이 없음을 판별하기에 충분합니다.

후보 키는 관계형 데이터 모델의 기본 개념입니다.

하나의 테이블에 여러 키가있는 경우 후보 키 중 하나를 기본 키로 지정하는 것이 일반적입니다. 또한 테이블의 외래 키가 다른 후보 키가 아닌 기본 키를 참조하도록하는 것이 일반적입니다.

이러한 방법을 권장하지만 관계형 모델에는 후보 키 중에서 기본 키를 선택해야하는 것은 없습니다.


답변

이것은 주요 질문과 @ 칼미의 질문에 대한 답입니다.

여러 개의 자동 생성 열이있는 점은 무엇입니까?

아래 코드에는 복합 기본 키가 있습니다. 해당 열 중 하나가 자동 증분됩니다. 이것은 MyISAM에서만 작동합니다. InnoDB는 ” ERROR 1075 (42000) : 테이블 정의가 잘못되었습니다. 하나의 자동 열만있을 수 있으며 키로 정의되어야합니다 “라는 오류 가 발생합니다 .

DROP TABLE IF EXISTS `test`.`animals`;
CREATE TABLE  `test`.`animals` (
  `grp` char(30) NOT NULL,
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `name` char(30) NOT NULL,
  PRIMARY KEY (`grp`,`id`)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');

SELECT * FROM animals ORDER BY grp,id;

Which returns:

+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+


답변

(이걸 많이 공부 했어)

후보 키 -테이블 행을 고유하게 식별하는 데 필요한 최소 열 조합입니다.
복합 키 -2 개 이상의 열.

  • 테이블에 여러 개의 후보 키 가 존재할 수 있습니다.
    • 기본 키 – 우리 가 선택한 후보 키 중 하나만
    • 대체 키다른 모든 후보 키
      • 기본 키 및 대체 키는 복합 키일 수 있습니다.

출처 :
https://en.wikipedia.org/wiki/Superkey
https://en.wikipedia.org/wiki/Candidate_key
https://en.wikipedia.org/wiki/Primary_key
https://en.wikipedia.org / wiki / Compound_key


답변

다른 사람들이 지적했듯이 다중 열 기본 키를 가질 수 있습니다. 그러나 키에 의해 도입되지 않은 기능적 종속성 이있는 경우 관계를 정상화하는 것을 고려해야 합니다.

예:

Person(id, name, email, street, zip_code, area)

사이에 기능적 의존성이있을 수 있지만 id -> name,email, street, zip_code and area
종종 a zip_code는 a area와 연관 되므로 내부적 으로 기능적 의존성이 있습니다 zip_code -> area.

따라서 다른 테이블로 나누는 것을 고려할 수 있습니다.

Person(id, name, email, street, zip_code)
Area(zip_code, name)

따라서 세 번째 정규형 과 일치 합니다 .


답변

기본 키는 “기본”이라는 의미와 논리적 모델과 관련된 잠재 의식적 연관성으로 인해 매우 유감스러운 표기법입니다. 따라서 사용하지 마십시오. 대신 물리적 모델의 대리 키와 논리 모델의 자연 키를 참조합니다.

모든 엔터티에 대한 논리적 모델에는 엔터티에 대한 키를 구성하는 “비즈니스 속성”집합이 하나 이상 있어야합니다. Boyce, Codd, Date 등은 관계형 모델에서 후보 키로 이것을 참조합니다. 그런 다음 이러한 엔티티에 대한 테이블을 작성하면 해당 테이블에서 후보 키가 자연 키가됩니다. 사용자는 테이블에서 행을 고유하게 식별 할 수있는 것은 자연 키를 통해서만 가능합니다. 서로 게이트 키는 항상 사용자에게 숨겨져 야합니다. 대리 키에는 비즈니스 의미가 없기 때문입니다.

그러나 테이블의 실제 모델은 대리 키가 없으면 비효율적입니다. 비 클러스터형 인덱스에 대해 커버되지 않은 열은 일반적으로 키 조회를 통해 클러스터형 인덱스로만 찾을 수 있음을 기억하십시오 (테이블은 잠시 힙으로 구현 됨). 사용 가능한 자연 키가 넓 으면이 (1) 비 클러스터형 리프 노드의 너비가 넓어 져 비 클러스터형 인덱스의 검색 및 스캔에 대한 스토리지 요구 사항과 읽기 액세스가 증가합니다. (2) 클러스터 된 인덱스에서 팬 아웃을 감소시켜 인덱스 높이와 인덱스 크기를 증가시켜 클러스터 된 인덱스에 대한 읽기 및 스토리지 요구 사항을 다시 증가시킵니다. (3) 클러스터형 인덱스에 대한 캐시 요구 사항을 증가시킵니다. 캐시에서 다른 인덱스와 데이터를 추적합니다.

여기서는 “기본 키”로 RDBMS에 지정된 작은 대리 키가 도움이됩니다. 비 클러스터형 인덱스에서 클러스터 된 인덱스로 키를 조회하고 관련 테이블에서 외래 키를 검색하기 위해 클러스터링 키로 설정하면 이러한 모든 단점이 사라집니다. 클러스터형 인덱스 팬 아웃이 다시 증가하여 클러스터형 인덱스 높이 및 크기를 줄이고 클러스터형 인덱스의 캐시로드를 줄이며 모든 메커니즘 (인덱스 스캔, 인덱스 검색, 비 클러스터 키 조회 또는 외래 키 조회)을 통해 데이터에 액세스 할 때 읽기를 줄입니다. 테이블의 클러스터 및 비 클러스터형 인덱스에 대한 스토리지 요구 사항을 줄입니다.

이러한 이점은 서로 게이트 키가 작고 클러스터링 키 모두 인 경우에만 발생합니다. GUID가 클러스터링 키로 사용되는 경우 사용 가능한 가장 작은 자연 키를 사용하는 것보다 상황이 더 나빠질 수 있습니다. 테이블이 힙으로 구성된 경우 8 바이트 (힙) RowID가 키 조회에 사용되며 이는 16 바이트 GUID보다 우수하지만 4 바이트 정수보다 성능이 떨어집니다.

비즈니스 제약으로 인해 GUID를 사용해야하는 경우 더 나은 클러스터링 키를 찾는 것이 좋습니다. 예를 들어 작은 사이트 식별자와 4 바이트 “site-sequence-number”가 실현 가능한 경우 해당 디자인은 Surrogate Key로서 GUID보다 더 나은 성능을 제공 할 수 있습니다.

힙의 결과 (해시 조인)가 선호하는 스토리지를 만들면 더 넓은 클러스터링 키의 비용을 균형 분석에 균형을 맞춰야합니다.

이 예제를 고려하십시오 ::

ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

튜플 ” (P_Id, LastName) “에 고유성 제약 조건이 필요하고 긴 유니 코드 LastName에 4 바이트 정수를 더한 경우 (1)이 제약 조건을 ” ADD CONSTRAINT pk_PersonID UNIQUE NONCLUSTERED (P_Id )로 선언적으로 적용하는 것이 바람직합니다. , LastName) “및 (2)는 작은 Surrogate Key를 클러스터형 인덱스 의” 기본 키 “로 별도로 선언합니다 . Anita는 해당 필드를 만들기 위해이 제약 조건에 LastName 만 추가하기를 원할 것입니다.이 필드는 모든 필드가 포함되므로 클러스터형 인덱스에서는 필요하지 않습니다.

SQL Server에서 기본 키를 비 클러스터형으로 지정하는 기능은 “물리적 기본 또는 후보 키”(논리적 모델)의 의미와 실제의 “저장소의 검색 키”라는 의미로 인해 불행한 역사적 상황입니다. 모델. 필자의 이해는 원래 SYBASE SQL Server가 실제 모델의 “저장소의 조회 키”로 힙 또는 클러스터형 인덱스에 상관없이 항상 4 바이트 RowID를 사용했다는 것입니다.