[sql] 기본 키 또는 고유 인덱스?

직장에서 우리는 기본 키 대신 고유 인덱스가있는 큰 데이터베이스를 가지고 있으며 모두 잘 작동합니다.

새 프로젝트를 위해 새 데이터베이스를 디자인하고 있는데 딜레마가 있습니다.

DB 이론에서 기본 키는 기본 요소이지만 괜찮습니다. 그러나 REAL 프로젝트에서는 두 가지 장점과 단점이 무엇입니까?

프로젝트에서 무엇을 사용하십니까?

편집 : … 그리고 MS SQL 서버의 기본 키 및 복제는 어떻습니까?



답변

고유 인덱스 란 무엇입니까?

열의 고유 인덱스는 해당 열의 인덱스로, 두 열에서 동일한 열에 두 개의 동일한 값을 가질 수 없다는 제약 조건을 적용합니다. 예:

CREATE TABLE table1 (foo int, bar int);
고유 인덱스 생성 ux_table1_foo ON table1 (foo); -foo에 고유 인덱스를 만듭니다.

INSERT INTO table1 (foo, bar) 값 (1, 2); -- 확인
INSERT INTO table1 (foo, bar) 값 (2, 2); -- 확인
INSERT INTO table1 (foo, bar) 값 (3, 1); -- 확인
INSERT INTO table1 (foo, bar) 값 (1, 4); -실패!

'ux_table1_foo'키에 대한 중복 항목 '1'

마지막 삽입 foo은 값 1을이 열에 두 번째로 삽입하려고 할 때 열의 고유 인덱스를 위반하므로 실패합니다 .

MySQL에서 고유 제한 조건은 여러 NULL을 허용합니다.

여러 열에서 고유 한 인덱스를 만들 수 있습니다.

기본 키와 고유 인덱스

같은 것 :

  • 기본 키는 고유 인덱스를 의미합니다.

다른 것들 :

  • 기본 키는 NOT NULL을 의미하지만 고유 인덱스는 널 입력 가능할 수 있습니다.
  • 기본 키는 하나만있을 수 있지만 고유 인덱스는 여러 개있을 수 있습니다.
  • 클러스터 된 인덱스가 정의되지 않은 경우 기본 키는 클러스터 된 인덱스입니다.

답변

다음과 같이 볼 수 있습니다.

기본 키는 고유합니다

고유 한 값이 요소의 표현 일 필요는 없습니다

의미?; “개인”이있는 경우 기본 키를 사용하여 요소를 식별하고 개인의 기본 개인 식별 번호 (SSN 등)를 갖고 싶습니다.

다른 한편으로, 그 사람은 고유하지만 그 사람을 식별하지 못하는 전자 메일을 가질 수 있습니다.

관계 테이블 (중간 테이블 / 연결 테이블)에서도 기본 키가 항상 있습니다. 왜? 코딩 할 때 표준을 따르고 싶습니다. “개인”에 식별자가 있고 자동차에 식별자가 있다면 Person-> Car에도 식별자가 있어야합니다!


답변

외래 키는 기본 키뿐만 아니라 고유 제약 조건으로 작동합니다. 온라인 설명서에서 :

FOREIGN KEY 제약 조건은 다른 테이블의 PRIMARY KEY 제약 조건에만 연결될 필요는 없습니다. 다른 테이블에서 UNIQUE 제약 조건의 열을 참조하도록 정의 할 수도 있습니다.

트랜잭션 복제의 경우 기본 키가 필요합니다. 온라인 설명서에서 :

트랜잭션 복제를 위해 게시 된 테이블에는 기본 키가 있어야합니다. 테이블이 트랜잭션 복제 게시에 있으면 기본 키 열과 관련된 인덱스를 비활성화 할 수 없습니다. 이러한 인덱스는 복제에 필요합니다. 인덱스를 비활성화하려면 먼저 게시에서 테이블을 삭제해야합니다.

두 가지 답변 모두 SQL Server 2005에 대한 것입니다.


답변

자연 키가 아닌 대리 기본 키를 사용할시기를 선택하는 것은 까다 롭습니다. 항상 또는 결코 같은 답은 거의 유용하지 않습니다. 상황에 따라 다릅니다.

예를 들어 다음 표가 있습니다.

CREATE TABLE toll_booths (
    id            INTEGER       NOT NULL PRIMARY KEY,
    name          VARCHAR(255)  NOT NULL,
    ...
    UNIQUE(name)
)

CREATE TABLE cars (
    vin           VARCHAR(17)   NOT NULL PRIMARY KEY,
    license_plate VARCHAR(10)   NOT NULL,
    ...
    UNIQUE(license_plate)
)

CREATE TABLE drive_through (
    id            INTEGER       NOT NULL PRIMARY KEY,
    toll_booth_id INTEGER       NOT NULL REFERENCES toll_booths(id),
    vin           VARCHAR(17)   NOT NULL REFERENCES cars(vin),
    at            TIMESTAMP     DEFAULT CURRENT_TIMESTAMP NOT NULL,
    amount        NUMERIC(10,4) NOT NULL,
    ...
    UNIQUE(toll_booth_id, vin)
)

두 개의 엔티티 테이블 ( toll_boothscars)과 트랜잭션 테이블 ( drive_through)이 있습니다. toll_booth는 변경이 보장되지는 자연적인 속성이 없기 때문에 테이블이 대리 키를 사용 (이름을 쉽게 변경할 수 있습니다). cars이 아닌 변경 고유 식별자를 가지고 있기 때문에 테이블 천연 차 키를 사용한다 ( vin). drive_through트랜잭션 테이블은 쉽게 식별 할 수 있도록 서로 게이트 키를 사용뿐만 아니라 레코드가 삽입 될 때 고유성을 보장받을 수 있습니다 속성에 고유 제한 조건이 있습니다.

http://database-programmer.blogspot.com 에는이 특정 주제에 대한 훌륭한 기사가 있습니다.


답변

기본 키의 단점은 없습니다.

@MrWiggles 및 @Peter Parker 답변에 정보를 추가하기 위해 테이블에 기본 키가없는 경우 일부 응용 프로그램에서 데이터를 편집 할 수 없습니다 (예 : 기본 키). Postgresql은 여러 NULL 값을 UNIQUE 열에 허용하고 PRIMARY KEY는 NULL을 허용하지 않습니다. 또한 코드를 생성하는 일부 ORM은 기본 키가없는 테이블에 일부 문제가있을 수 있습니다.

최신 정보:

내가 아는 한 적어도 문제 (없이, MSSQL에서 기본 키없이 테이블을 복제 할 수 없습니다 세부 사항 ).


답변

어떤 것이 기본 키인 경우 DB 엔진에 따라 전체 테이블이 기본 키로 정렬됩니다. 이는 다른 종류의 인덱스와 관련하여 참조 해제를 수행 할 필요가 없기 때문에 기본 키에서 조회 속도가 훨씬 빠르다는 것을 의미합니다. 게다가, 그것은 단지 이론 일뿐입니다.


답변

다른 답변에서 말한 것 외에도 일부 데이터베이스 및 시스템 에는 기본 데이터베이스가 있어야 할 수도 있습니다. 한 가지 상황이 떠 오릅니다. Informix와 함께 엔터프라이즈 복제를 사용할 때 테이블이 복제에 참여하려면 PK가 있어야합니다.