programing

기본 키를 한 테이블에 여러 개 넣을 수 있습니까?

telecom 2023. 10. 17. 20:01
반응형

기본 키를 한 테이블에 여러 개 넣을 수 있습니까?

기본 키를 한 테이블에 여러 개 넣을 수 있습니까?

표에는 두 개 이상의 열로 만든 기본 키인 복합 기본 키가 있을 수 있습니다.예를 들어,

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

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

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

테이블에 유니크 인덱스가 있을 수도 있습니다. 유니크 인덱스는 유니크한 값을 강제하고 해당 값을 쿼리하는 속도를 높인다는 점에서 기본 키와 같이 작동합니다.

테이블에는 여러 개의 후보 키가 있을 수 있습니다.각 후보 키는 UNIQUE이고 함께 수집되며 NULL이 아닌 열 또는 집합입니다.따라서 후보 키의 모든 열에 대해 값을 지정하면 기준을 충족하는 행이 하나 있거나 행이 전혀 없다고 판단할 수 있습니다.

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

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

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

이것은 주요 질문에 대한 답이자 @Kalmi의 질문에 대한 답입니다.

자동 생성 열이 여러 개인 것은 무슨 의미가 있습니까?

아래 코드에는 복합 기본 키가 있습니다.열 중 하나가 자동 증분됩니다.이것은 My ISAM에서만 작동합니다.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개 이상의 열.

  • 여러 개의 후보 키가 테이블에 존재할 수 있습니다.
    • Primary KEY - 당사가 선택한 후보 키 중 하나만 해당
    • 대체 키 - 다른 모든 후보 키
      • Primary Key와 Alternate Key 모두 Compound Key가 될 수 있습니다.

출처:



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

예:

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

사이에 기능적 종속성이 있을 수 있습니다.id -> name,email, street, zip_code and area하지만 종종 A.zip_codeA와 연관되어 있습니다.area따라서 내부적인 기능적 의존성이 있습니다.zip_code -> area.

따라서 다른 테이블로 분할하는 것을 고려해 볼 수 있습니다.

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

번째 정규 형태와 일치하도록 합니다.

Primary Key는 매우 유감스러운 표기법인데, 이는 "Primary"의 의미와 논리적 모델에 따른 잠재의식적 연관성 때문입니다.그래서 사용을 피합니다.대신 물리적 모델의 대리 키와 논리적 모델의 자연 키를 참조합니다.

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

그러나 표의 물리적 모델은 대리 키가 없으면 비효율적인 경우가 많습니다.클러스터되지 않은 인덱스에 대한 비가림 열은 클러스터된 인덱스에 대한 키 룩업(Key Lookup)을 통해서만 찾을 수 있습니다(잠시 동안 힙으로 구현된 테이블은 무시).사용 가능한 Natural Key가 넓을 경우 (1) 비클러스터 리프 노드의 폭을 넓혀 스토리지 요구사항과 해당 비클러스터 인덱스 검색 및 검색에 대한 읽기 액세스를 증가시키고 (2) 클러스터된 인덱스에서 팬아웃을 줄여 인덱스 높이와 인덱스 크기를 증가시킵니다.(3) 클러스터된 인덱스에 대한 읽기 및 스토리지 요구사항이 다시 증가하고 (3) 클러스터된 인덱스에 대한 캐시 요구사항이 증가합니다.다른 인덱스 및 데이터를 캐시에서 쫓아냅니다.

여기서 RDBMS에 "기본 키"로 지정된 작은 대리 키가 유익함을 입증합니다.클러스터링 키로 설정하면 비클러스터 인덱스에서 클러스터 인덱스로 키를 검색하고 관련 테이블에서 외부 키를 검색하는 데 사용할 수 있습니다.클러스터링된 인덱스 팬아웃은 다시 증가하여 클러스터링된 인덱스 높이 및 크기를 줄이고, 클러스터링된 인덱스의 캐시 로드를 줄이며, 모든 메커니즘을 통해 데이터에 액세스할 때 읽기를 줄입니다(인덱스 스캔, 인덱스 검색, 데이터 액세스 등).clustered 이외의 키 조회 또는 외부 키 조회)를 통해 표의 클러스터 인덱스와 비클러스터 인덱스 모두에 대한 스토리지 요구사항을 줄일 수 있습니다.

이러한 이점은 대리 키가 작고 클러스터링 키가 둘 다일 때만 발생합니다.GUID를 클러스터링 키로 사용할 경우 사용 가능한 가장 작은 자연 키를 사용한 경우보다 상황이 더 악화되는 경우가 많습니다.테이블이 힙(heap)으로 구성되어 있으면 8바이트(heap) 행ID는 키 조회에 사용됩니다. 키 조회는 16바이트 GUID보다 우수하지만 성능은 4바이트 정수보다 낮습니다.

비즈니스 제약으로 인해 GUID를 사용해야 한다면 더 나은 클러스터링 키를 찾을 가치가 있습니다.예를 들어 작은 사이트 식별자와 4바이트의 "site-sequence-number"가 가능하다면, 그 설계는 대리 키로서 GUID보다 더 나은 성능을 제공할 수 있습니다.

힙(해시 조인)의 결과로 선호 스토리지가 생성될 경우, 더 넓은 클러스터링 키의 비용을 절충 분석에 균형을 맞출 필요가 있습니다.

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

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

튜플 ("P_Id,LastName)"에 고유성 제약 조건이 필요하고 긴 유니코드 성(Unicode LastName)과 4바이트 정수가 포함될 수 있는 경우, (1) 이 제약 조건을 "ADD CONSTRETT Pk_Person"으로 선언적으로 적용하는 것이 바람직할 것입니다.ID UNIQUE NONCLUSTED(P_Id,LastName)" 및 (2)는 별도로 작은 대리 키를 클러스터된 인덱스의 "기본 키"로 선언합니다.Anita는 이 제약 조건에 성(Last Name)만 추가하여 적용 필드로 만들기를 원할 수 있으며, 이는 클러스터된 인덱스에서는 모든 필드가 적용되므로 불필요합니다.

SQL Server에서 Primary Key를 비클러스터로 지정할 수 있는 기능은 (논리 모델의) "기본 자연 키 또는 후보 키"라는 의미와 물리적 모델의 "스토리지의 조회 키"라는 의미가 서로 결합되어 있기 때문에 불행한 과거 상황입니다.원래 SYBASE SQL Server는 항상 4바이트 행을 사용한 것으로 알고 있습니다.힙 또는 클러스터 인덱스에 포함된 ID를 물리적 모델에서 "스토리지의 룩업 키"로 지정합니다.

기본 키는 레코드를 고유하게 식별하는 키로 모든 인덱스에서 사용됩니다.이것이 여러분이 하나 이상 가질 수 없는 이유입니다.또한 일반적으로 하위 테이블에 연결할 때 사용되는 키이지만 필수 사항은 아닙니다.PK의 진짜 목적은 데이터 변경이 올바른 레코드에 영향을 미치고 인덱스를 생성할 수 있도록 레코드를 고유하게 식별할 수 있도록 하는 것입니다.

그러나 하나의 기본 키(복합 PK)에 여러 필드를 넣을 수 있습니다.이렇게 하면 조인 속도가 느려지고(특히 문자열 유형 필드가 더 큰 경우) 인덱스가 커지지만 일부 하위 테이블에서 조인을 수행할 필요가 없어지므로 성능과 설계에 관한 한 사례별로 조인을 수행할 수 있습니다.이렇게 하면 각 필드 자체가 고유한 것이 아니라 이들의 조합이 고유한 것입니다.복합 키의 필드 중 하나 이상도 고유해야 하는 경우, 해당 필드에 고유한 인덱스가 필요합니다.한 필드가 고유한 경우 PK에 더 적합한 후보가 될 수 있습니다.

이제 PK 후보가 한 명 이상일 때가 있습니다.이 경우 PK로 하나를 선택하거나 대리 키를 사용합니다(개인적으로는 이 인스턴스의 경우 대리 키를 선호합니다).PK로 선택되지 않은 각 후보 키에 고유 인덱스를 추가합니다.데이터가 고유해야 하는 경우 PK인지 여부에 관계없이 고유한 인덱스가 필요합니다.이것은 데이터 무결성 문제입니다.(이것은 대리 키를 사용할 때에도 적용됩니다. 사람들은 후보 키에 고유한 인덱스를 만드는 것을 잊어버리기 때문에 대리 키로 인해 문제가 발생합니다.)

두 개 이상의 대리 키를 원할 때가 있습니다(이 키가 있으면 대개 PK가 됩니다).이 경우 원하는 것은 더 많은 PK가 아니라 자동 생성된 키를 가진 더 많은 필드입니다.대부분의 DB는 이를 허용하지 않지만, 이를 극복하는 방법이 있습니다.첫 번째로 두 번째 필드가 첫 번째 자동 생성된 키(예를 들어 Field1 * -1)를 기반으로 계산될 수 있는지, 아니면 두 번째 자동 생성된 키의 필요성이 실제로는 관련 테이블을 만들어야 한다는 것을 의미하는지를 고려합니다.관련 테이블은 일대일 관계일 수 있습니다.상위 테이블의 PK를 하위 테이블에 추가한 다음 새 자동 생성 필드를 테이블에 추가하고 이 테이블에 적합한 필드를 추가하여 이를 적용할 수 있습니다.그런 다음 두 키 중 하나를 PK로 선택하고 다른 키에 고유 인덱스를 지정합니다(자동 생성 필드가 PK일 필요는 없음).그리고 FK를 부모 테이블에 있는 필드에 추가해야 합니다.일반적으로 하위 테이블에 대한 추가 필드가 없는 경우 두 개의 자동 생성 필드가 필요하다고 생각하는 이유를 조사해야 합니다.

어떤 사람들은 "기본 키"라는 용어를 어떤 자동 메커니즘에 의해 값이 생성되는 정수 열을 정확하게 의미하기 위해 사용합니다.예를들면AUTO_INCREMENTMySQL 또는IDENTITY마이크로소프트 SQL 서버에 설치할 수 있습니다.이런 의미로 프라이머리 키를 사용하고 있습니까?

그렇다면 사용 중인 데이터베이스의 브랜드에 따라 정답이 달라집니다.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)
);

그러나 관계형 데이터베이스에서 '슈퍼 키'는 테이블의 튜플이나 행을 고유하게 식별하는 속성의 하위 집합입니다.'키'는 키에서 속성을 제거하면 해당 키가 더 이상 '슈퍼 키'(또는 단순히 '키'는 최소 슈퍼 키)가 되지 않는 추가 속성을 가진 '슈퍼 키'입니다.키가 더 많으면 모두 후보 키입니다.후보 키 중 하나를 기본 키로 선택합니다.그렇기 때문에 하나의 관계나 테이블에 대해 여러 개의 기본 키를 이야기하는 것이 갈등이 되고 있습니다.

좋은 기술적인 답변이 저보다 더 좋은 방법으로 주어졌습니다.이 항목에 추가할 수 있는 것은 다음과 같습니다.

만약 당신이 허용되지 않는/허용되지 않는 것을 원한다면 한발 물러서는 것이 좋은 이유입니다.

  1. 왜 그것이 허용되지 않는지 핵심을 이해하세요.
  2. 문서/저널 기사/웹 등에 대해 자세히 알아봅니다.
  3. 현재 설계를 분석/검토하고 주요 결함을 지적합니다.
  4. 새 설계 시 모든 단계를 고려하고 테스트합니다.
  5. 항상 기대하고 적응형 솔루션을 만들기 위해 노력해야 합니다.

누군가에게 도움이 되길 바랍니다.

예, SQL에서는 가능하지만 MsAccess에서는 기본 키를 둘 이상 설정할 수 없습니다.그럼, 다른 데이터베이스들에 대해서는 잘 모르겠네요.

CREATE TABLE CHAPTER (
    BOOK_ISBN VARCHAR(50) NOT NULL,
    IDX INT NOT NULL,
    TITLE VARCHAR(100) NOT NULL,
    NUM_OF_PAGES INT,
    PRIMARY KEY (BOOK_ISBN, IDX)
);

언급URL : https://stackoverflow.com/questions/217945/can-i-have-multiple-primary-keys-in-a-single-table

반응형