답변:
테이블에는 두 개 이상의 열로 만들어진 기본 키인 복합 기본 키 가있을 수 있습니다 . 예를 들면 다음과 같습니다.
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를 사용했다는 것입니다.
어떤 사람들은 "기본 키"라는 용어를 사용하여 자동 메커니즘에 의해 생성 된 값을 가져 오는 정수 열을 정확하게 의미합니다. 예를 들어 AUTO_INCREMENT
MySQL 또는 IDENTITY
Microsoft SQL Server에서. 이런 의미에서 기본 키를 사용하고 있습니까?
그렇다면 대답은 사용중인 데이터베이스 브랜드에 따라 다릅니다. MySQL에서는이를 수행 할 수 없으며 오류가 발생합니다.
mysql> create table foo (
id int primary key auto_increment,
id2 int auto_increment
);
ERROR 1075 (42000): Incorrect table definition;
there can be only one auto column and it must be defined as a key
일부 다른 브랜드의 데이터베이스에서는 테이블에 둘 이상의 자동 생성 열을 정의 할 수 있습니다.
두 개의 기본 키를 동시에 가질 수는 없습니다. 그러나 (복합 키로 사건을 망쳐 놓지 않았다고 가정하면) 하나의 속성을 고유하게 만드는 것이 필요할 수 있습니다.
CREATE t1(
c1 int NOT NULL,
c2 int NOT NULL UNIQUE,
...,
PRIMARY KEY (c1)
);
그러나 관계형 데이터베이스에서 '슈퍼 키'는 테이블에서 튜플 또는 행을 고유하게 식별하는 속성의 하위 집합입니다. '키'는 키에서 속성을 제거하고 해당 키를 더 이상 '슈퍼 키'로 만들지 않는 추가 속성이있는 '슈퍼 키'입니다 (또는 간단히 '키'는 최소 슈퍼 키입니다). 더 많은 키가 있으면 모두 후보 키입니다. 후보 키 중 하나를 기본 키로 선택합니다. 그렇기 때문에 하나의 관계 또는 테이블에 대한 여러 기본 키에 대해 말하는 것이 충돌하는 이유입니다.
기본 키는 레코드를 고유하게 식별하고 모든 색인에 사용되는 키입니다. 이것이 하나 이상 가질 수없는 이유입니다. 또한 일반적으로 자식 테이블에 조인하는 데 사용되는 키이지만 필수 사항은 아닙니다. PK의 실제 목적은 데이터 변경 사항이 올바른 레코드에 영향을 미치고 인덱스를 작성할 수 있도록 레코드를 고유하게 식별 할 수 있도록하는 것입니다.
그러나 하나의 기본 키 (복합 PK)에 여러 필드를 넣을 수 있습니다. 이렇게하면 조인 속도가 느려지고 (특히 큰 문자열 유형 필드 인 경우) 인덱스가 커지지 만 일부 자식 테이블에서 조인을 수행 할 필요가 없어 질 수 있습니다. 사례 기준. 이 작업을 수행 할 때 각 필드 자체는 고유하지 않지만 그 조합은 고유합니다. 복합 키의 필드 중 하나 이상이 고유해야하는 경우 고유 한 색인이 필요합니다. 하나의 필드가 고유 한 경우 PK에 더 적합한 후보 일 수 있습니다.
이제는 때때로 PK 후보가 둘 이상 있습니다. 이 경우 PK로 하나를 선택하거나 대리 키를 사용합니다 (개인적으로 대리 키를 선호합니다). 그리고 (이것은 중요합니다!) PK로 선택되지 않은 각 후보 키에 고유 인덱스를 추가합니다. 데이터가 고유해야하는 경우 PK 여부에 관계없이 고유 인덱스가 필요합니다. 이것은 데이터 무결성 문제입니다. (대리 키를 사용하는 경우에도 마찬가지입니다. 사람들은 후보 키에 고유 인덱스를 작성하는 것을 잊어 버리므로 대리 키에 문제가 생깁니다.)
때로는 둘 이상의 대리 키를 원할 때가 있습니다 (보통 PK가있는 경우). 이 경우 원하는 것은 더 많은 PK가 아니며 자동 생성 키가있는 더 많은 필드입니다. 대부분의 DB는 이것을 허용하지 않지만 해결할 수있는 방법이 있습니다. 첫 번째 자동 생성 키 (예 : Field1 * -1)를 기반으로 두 번째 필드를 계산할 수 있는지 또는 두 번째 자동 생성 키가 필요하다는 것은 실제로 관련 테이블을 작성해야한다는 의미입니다. 관련 테이블은 일대일 관계 일 수 있습니다. 상위 테이블에서 하위 테이블로 PK를 추가 한 다음 새 자동 생성 필드를 테이블에 추가 한 다음이 테이블에 적합한 필드를 추가하여이를 적용합니다. 그런 다음 두 키 중 하나를 PK로 선택하고 다른 하나에 고유 인덱스를 넣으십시오 (자동 생성 필드는 PK 일 필요는 없습니다). 부모 테이블에있는 필드에 FK를 추가해야합니다. 일반적으로 하위 테이블에 대한 추가 필드가없는 경우 두 개의 자동 생성 필드가 필요한 이유를 조사해야합니다.
내가 할 수있는 것보다 더 좋은 방법으로 좋은 기술 답변을 받았습니다. 이 주제에만 추가 할 수 있습니다.
허용 / 허용되지 않는 것을 원한다면 물러서야합니다.
누군가에게 도움이되기를 바랍니다.