고유 인덱스 대신 고유 제약 조건을 언제 사용해야합니까?


194

열에 고유 한 값을 가지려면 제약 조건을 사용할 수 있습니다

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

또는 고유 색인을 사용할 수 있습니다

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

고유 제약 조건이있는 열은 고유 인덱스에 적합한 후보 인 것 같습니다.

고유 제한 조건을 사용하고 대신 고유 색인을 사용하지 않는 알려진 이유가 있습니까?


9
그들은 실제로 다른가? postgresql과 같은 일부 데이터베이스에서는 고유 제약 조건이 단순히 고유 인덱스를 생성한다고 생각합니다. SQL Server에 대해 아무것도 모르기 때문에 응답하지 않습니다.
xenoterracide

6
postgresql에서는 고유 제한 조건이 아닌 고유 인덱스에서 표현식을 사용할 수 있습니다.
Neil McGuigan

1
MS SQL에서는 동일하게 구현됩니다. 동일한 데이터를 갖는 두 개의 테이블을 작성하십시오. 하나는 고유 제한 조건이고 다른 하나는 고유 색인입니다. 그들은 같은 양의 인덱스 공간을 사용할 것이며, 둘 다 (실제로) 어떤 방식 으로든 생성 된 고유 인덱스에 대해 검색 할 수 있습니다.
모든 거래의 존

답변:


153

후드 아래에서 고유 제한 조건은 고유 색인과 동일한 방식으로 구현됩니다. 제한 조건을 시행하기위한 요구 사항을 효율적으로 충족하려면 색인이 필요합니다. 인덱스가 UNIQUE 제약 조건의 결과로 생성 된 경우에도 쿼리 플래너는 지정된 쿼리에 접근하는 가장 좋은 방법으로 볼 경우 다른 인덱스처럼 사용할 수 있습니다.

따라서 두 기능을 모두 지원하는 데이터베이스의 경우 사용할 스타일을 선호하는 스타일과 일관성으로 선택합니다.

색인을 색인으로 사용하려는 경우 (즉, 코드가 해당 필드에서 빠른 검색 / 정렬 / 필터링에 의존 할 수 있음) 제약 조건 대신 명시 적으로 고유 색인을 사용하고 소스를 주석 처리합니다. clear-응용 프로그램의 이후 개정에서 고유성 요구 사항이 변경되면 고유 한 인덱스 대신 고유하지 않은 인덱스가 있는지 확인하는 고유 한 제약 조건을 제거하면 제거됩니다. 색인). 또한 특정 색인은 색인 힌트 (예 : WITH (INDEX (ix_index_name))에서 명명 될 수 있습니다.이 색인은 이름을 알지 못할 때 고유성을 관리하기 위해 배후에서 생성 된 색인의 경우라고 생각하지 않습니다.

마찬가지로 필드를 검색하거나 정렬하는 데 필요한 필드가 아닌 비즈니스 규칙으로 고유성을 적용 해야하는 경우 다른 사람이 테이블 정의를 볼 때 의도 한 사용을보다 명확하게하기 위해 제약 조건을 사용합니다.

동일한 필드에서 고유 제한 조건과 고유 인덱스를 모두 사용하는 경우 데이터베이스는 중복을 볼 수있을만큼 밝지 않으므로 추가 공간을 소비하고 행 삽입 / 업데이트 속도를 늦추는 두 개의 인덱스로 끝납니다.


1
"데이터베이스가 충분히 밝지 않을 것"이 궁금합니다. 모든 RDBMS에 해당 되는가? SQL 표준에 의해 규정되어 있습니까? 그리고 그것이 (그리고 왜 그래야하는지 궁금 할지라도) 모든 구현이 그런 식으로 구현합니까? 또는 : 왜 DB가 충분히 밝을 수 없습니까?
Jürgen A. Erhard

4
@jae : DBMS에 확실히 할 수 충분히 밝은, 그러나 당신이 있는지 확인하기 위해 각 DBMS 확인해야 할 것이다. MSSQL에 두 개의 동일한 인덱스를 만들도록 요청하면 두 개의 이름으로 참조되는 하나가 아닌 두 개가 생성됩니다 (적어도 이것이 마지막 상황이었습니다 (사본의 복사 + 붙여 넣기 오류로 인해)). 따라서 제약 조건으로 인해 인덱스 중 하나가 존재하는 경우에도 마찬가지입니다.
David Spillett

3
+1 @David Spillett 저는 기본적으로 DBMS가 여러분이하고있는 일을 알고 있다고 가정합니다. 같은 인덱스를 두 번 만드는 느낌이 든다면 그것에 대해 의문의 여지가 없습니다.
Andrew Barber

2
매우 통찰력. 이 동작이 MySQL 및 Apache Derby에서도 발생하는지 알고 있습니까?
corsiKa

5
제약 조건의 이름을 지정하고 인덱스 힌트에 사용할 수 있습니다 . CREATE TABLE #T(X INT CONSTRAINT PK PRIMARY KEY NONCLUSTERED);SELECT * FROM #T WITH(INDEX(PK)) WHERE X = 1. 제약 조건이 INCLUDEd 열 또는 필터링 된 인덱스 와 같은 모든 인덱스 옵션을 지원하지는 않지만 인덱스는 더 유연 할 수 있습니다 .
Martin Smith

101

다른 답변의 요점 외에도 두 가지의 주요 차이점이 있습니다.

참고 : 오류 메시지는 SQL Server 2012에서 온 것입니다.

오류

고유 제한 조건을 위반하면 오류 2627이 리턴됩니다.

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

고유 인덱스를 위반하면 오류 2601이 반환됩니다.

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

비활성화

고유 제한 조건을 비활성화 할 수 없습니다.

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

그러나 기본 키 제약 조건 또는 고유 제약 조건 뒤에있는 고유 인덱스는 다른 고유 인덱스와 마찬가지로 비활성화 할 수 있습니다. 모자 팁 Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

클러스터형 인덱스를 비활성화하면 데이터에 액세스 할 수 없게된다는 일반적인 경고에 유의하십시오.

옵션

고유 제약 조건은 FILLFACTORand과 같은 인덱싱 옵션을 지원 IGNORE_DUP_KEY하지만 모든 버전의 SQL Server에는 해당되지 않습니다.

포함 된 열

비 클러스터형 인덱스는 인덱싱되지 않은 열을 포함 할 수 있습니다 (커버링 인덱스라고 함, 이것은 주요 성능 향상입니다). PRIMARY KEY 및 UNIQUE 제약 조건 뒤에있는 인덱스는 열을 포함 할 수 없습니다. 모자 팁 @ypercube.

필터링

고유 제한 조건을 필터링 할 수 없습니다.

고유 인덱스를 필터링 할 수 있습니다.

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

외래 키 제약

외래 키 제약 조건은 필터링 된 고유 인덱스를 참조 할 수 없지만 필터링되지 않은 고유 인덱스를 참조 할 수 있습니다 (SQL Server 2005에서 추가 된 것 같습니다).

명명

구속 조건을 작성할 때 구속 조건 이름을 지정하는 것은 선택 사항입니다 (5 가지 유형의 구속 조건 모두). 이름을 지정하지 않으면 MSSQL이 이름을 생성합니다.

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

색인을 작성할 때 이름을 지정해야합니다.

모자 팁 @ i-one.

연결

http://technet.microsoft.com/en-us/library/aa224827(v=SQL.80).aspx

http://technet.microsoft.com/en-us/library/ms177456.aspx


인덱스와 동일한 방법으로 고유 제약 조건을 비활성화 및 활성화 할 수 있습니다. ALTER INDEX tbl ON uconstraint DISABLE, ALTER INDEX tbl ON uconstraint REBUILD
Brain2000

@ Brain2000에게 감사합니다. 우연히도, 나는이 의견을 읽기 직전에 오늘 아침 색인 비활성화에 관한 섹션을 가르쳤다.
Greenstone Walker 1

10

MSDN을 신뢰할 수있는 출처로 인용하려면 :

UNIQUE 제약 조건을 만드는 것과 제약 조건과 독립적 인 고유 인덱스를 만드는 것 사이에는 큰 차이가 없습니다 . 데이터 유효성 검사는 동일한 방식으로 발생하며 쿼리 최적화 프로그램은 제약 조건에 의해 생성되거나 수동으로 생성 된 고유 인덱스를 구별하지 않습니다. 그러나 열에 UNIQUE 제약 조건을 만들면 인덱스의 목표가 명확 해집니다. 자세한 내용은 여기를 참조하십시오.

과...

데이터베이스 엔진은 UNIQUE 제약 조건의 고유성 요구 사항을 적용하기 위해 UNIQUE 인덱스를 자동으로 만듭니다. 따라서 중복 행을 삽입하려고하면 데이터베이스 엔진은 UNIQUE 제약 조건을 위반하고 행을 테이블에 추가하지 않는다는 오류 메시지를 반환합니다. 클러스터 된 인덱스가 명시 적으로 지정하지 않는 한, 고유 한 클러스터되지 않은 인덱스는 UNIQUE 제약 조건을 적용하는 기본 ...에 의해 만들어 여기에 대한 추가 정보

다른 : https://technet.microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx


6

고유 제한 조건과 고유 인덱스의 주요 차이점 중 하나는 다른 테이블의 외래 키 제한 조건이 고유 제한 조건을 구성하는 열을 참조 할 수 있다는 것입니다. 고유 인덱스에는 해당되지 않습니다. 또한 고유 제약 조건은 ANSI 표준의 일부로 정의되지만 인덱스는 그렇지 않습니다. 마지막으로, 인덱스는 물리적 측면이지만 논리적 데이터베이스 디자인 영역 (다른 DB 엔진에 의해 다르게 구현 될 수 있음)의 영역에 존재하는 것으로 간주되는 고유 제약 조건입니다. 따라서 고유 제한 조건이 더 선언적입니다. 거의 모든 경우에 고유 한 제약 조건을 선호합니다.


8
-1 SQL Server에서 다음이 잘못되었습니다. "다른 테이블의 외래 키 제약 조건은 고유 제약 조건을 구성하는 열을 참조 할 수 있습니다. 고유 인덱스에는 해당되지 않습니다." SQL Server에서는 FK 제약 조건을 고유 인덱스로 참조 할 수 있습니다.
AK

4
외래 키 제약 조건으로 고유 인덱스를 참조하는 기능은 SQL Server 2005에 추가되었다고 생각합니다. BOL의 일부 페이지를 포함하여 많은 소스가 변경 사항을 반영하도록 업데이트되지 않았으므로 Dmitry의 대답은 아닙니다. 다운 보트가 필요합니다. 그의 대답의 나머지 부분은 자리에 있습니다. 제약은 ANSI 표준이며 색인은 아닙니다.
Greenstone Walker

이것들에도 불구하고 내가 가장 좋아하는 대답을 공감합니다.
기적 173

표준이 중요합니다. Ansi 표준이 고유 구속 조건을 사용하는 경우 고유 구속 조건을 사용해야합니다.
Rhyous

1

Oracle의 주요 차이점은 고유 한 제약 조건으로는 불가능한 함수 고유 인덱스를 만들 수 있다는 것입니다.

예를 들어

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

따라서 fk_xyz기록이있는 경우에만 고유합니다 amount != 0.


7
SQL Server (질문의 태그)에서 인덱스를 WHERE절로 필터링 할 수 있습니다 . CREATE UNIQUE NONCLUSTERED INDEX P4_U ON DBO.P4 ( PID ) WHERE TXT = 'qwert' ;
Greenstone Walker

-3

UNIQUE 제약 조건은 UNIQUE 인덱스보다 선호됩니다. 제약 조건이 고유하지 않은 경우 일반 또는 비 고유 인덱스를 사용해야합니다. 제약 조건은 또 다른 유형의 색인입니다. 더 빠른 액세스를 위해 인덱스가 사용됩니다.

고유 인덱스에는 where 절이있을 수 있습니다. 예를 들어 날짜 열을 기준으로 매년 인덱스를 만들 수 있습니다.

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'

where 절의 이점을 언급 한 것이 좋습니다.
crokusek

3
"제약은 또 다른 유형의 색인입니다." 아닙니다. 일부 제약 조건 (PK, UQ, FK)은 색인을 사용하여 적용 할 수 있으며 종종 적용됩니다. 모든 DBMS에서 반드시 그런 것은 아니며 기본적으로는 아닙니다.
ypercubeᵀᴹ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.