programing

SQL Server 2008의 고유 키 대 고유 인덱스

oldcodes 2023. 7. 13. 21:06
반응형

SQL Server 2008의 고유 키 대 고유 인덱스

라는 테이블이 있습니다.countries그리고 나는 정의합니다.country_nameSQL Server 2008 R2에서 "Inique Key" 유형의 "Index/Key"를 만들어 고유한 열을 생성합니다.

하지만 다음과 같은 질문이 있습니다.

  1. 고유 키 유형의 "Index/Key"를 만들면 이 열에 비클러스터된 인덱스가 자동으로 생성됩니까?
  2. 유형을 "고유 키"에서 "색인"으로 변경하고 다음을 유지하는 경우IsUnique값은 "예"... 그렇다면 차이가 있을까요?
  3. 그렇다면 왜 "고유키"와 "인덱스" 두 가지 옵션이 있다고 생각합니까?

고유한 제약 조건은 고유한 인덱스로 백그라운드에서 구현되므로 이를 지정하는 방법은 중요하지 않습니다.단순하게 다음과 같이 구현하는 경향이 있습니다.

ALTER TABLE dbo.foo ADD CONSTRAINT UQ_bar UNIQUE(bar);

어떤 사람들은 대신 고유한 인덱스를 만듭니다.

CREATE UNIQUE INDEX IX_UQ_Bar ON dbo.foo(bar);

차이점은 의도에 있습니다. 고유성/비즈니스 규칙을 적용하기 위해 제약 조건을 작성하는 경우 제약 조건을 작성하고 쿼리 성능을 지원하기 위해 제약 조건을 작성하는 경우 고유 인덱스를 작성하는 것이 더 논리적일 수 있습니다.다시 말씀드리지만, 이는 동일한 구현이지만, 이를 위해 가는 길은 의도를 문서화하는 데 도움이 될 수 있습니다.

이전 Sybase 기능과 ANSI 표준을 모두 준수할 수 있는 여러 옵션이 있다고 생각합니다(단, 고유한 제약 조건이 표준 100%를 준수하지 않더라도). 하나의 NULL 값만 허용하기 때문에 - 반면 고유한 인덱스는 다음을 추가하여 이 문제를 해결할 수 있습니다.WHERE조항 (WHERE col IS NOT NULL)을(를) 참조하십시오.

한 가지 추가적으로 언급해야 할 것은 인덱스를 생성할 경우 포함된 열을 지정할 수 있다는 것입니다. 이는 country_name으로 검색하는 경우 SQL 코드가 더 빨리 작동하도록 도와줍니다.

CREATE UNIQUE NONCLUSTERED INDEX IX_UQ_Bar
ON dbo.foo (
    bar
)
INCLUDE (foo_other_column)
GO

SELECT foo_other_column FROM Foo WHERE bar = 'test'

SQL 서버는 "foo_other_column"을 인덱스 자체에 저장합니다.고유 제약 조건의 경우 먼저 'test'의 인덱스를 찾은 다음 footable에서 행을 검색하고 "foo_other_column"만 사용합니다.

위의 훌륭한 답변을 제외하고, 저는 여기에 제 2센트를 추가하겠습니다.

고유 키는 제약 조건이며 고유 인덱스를 사용하여 자체를 시행합니다.기본 키가 일반적으로 클러스터된 고유 인덱스에 의해 적용되는 것과 같습니다.논리적으로 말해서, 제약과 색인은 서로 다른 것입니다.그러나 RDBMS에서 제약 조건은 인덱스를 통해 물리적으로 구현될 수 있습니다.

SQL Server에서 고유한 제약 조건을 사용하여 테이블을 만들면 제약 조건 개체와 고유한 인덱스가 모두 표시됩니다.

create table dbo.t (id  int constraint my_unique_constraint unique (id));

select [Constraint]=name from sys.key_constraints 
where parent_object_id = object_id('dbo.t');

select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t')
and index_id > 0;

우리는 다음과 같은 것을 얻을 것입니다(제약과 지수).

enter image description here

그러나, 만약 우리가 다음과 같이 제약조건을 만들지 않고 단지 고유한 색인을 만든다면,

create table dbo.t2 (id int );
create unique index my_unique_constraint on dbo.t2 (id);

select [Constraint]=name from sys.key_constraints 
where parent_object_id = object_id('dbo.t2');

select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t2')
and index_id > 0

제약 조건 개체는 생성되지 않았습니다(인덱스만 생성됨).

enter image description here

"이론적" 관점에서 SQL Server에서 제약 조건은 object_id 값을 가진 객체이고 스키마 바운드인 반면 인덱스는 객체가 아니며 object_id 값도 없고 스키마와 관련이 없습니다.

고유 인덱스 또는 고유 제약 조건 간에는 차이가 없으며 성능에도 차이가 없습니다.그러나 고유한 제약 조건에 대해 일부 인덱스 작성 옵션을 사용할 수 없는 경우에는 작성에 대한 몇 가지 차이점이 있습니다.

SqlMetal을 사용하는 경우.exe를 사용하여 DBML 또는 LinqToSq 엔티티를 출력합니다.

  • 외부 키가 고유한 키를 사용하는 경우 예상대로 연결됩니다.
  • 외부 키가 고유 인덱스를 사용하면 표시되지 않습니다.

그 이유는 SqlMetal 구현에 있습니다.데이터베이스 정보 스키마, 특히 키 열 사용에 대해 쿼리합니다.고유한 키는 표시되지만 고유한 인덱스는 표시되지 않습니다.

SELECT TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;

고유성을 적용하기 위한 세 번째 옵션은 필터링된 고유 인덱스를 사용하여 Nullable 고유 인덱스를 허용하는 것입니다.
고유 제약 조건에서는 작동하지 않습니다.
를 들어,.
하지만 여전히 다수를 지원하기를 원합니다.NULL값이 존재하지 않는 경우.
필터링된 고유 인덱스만 작동합니다.

CREATE UNIQUE NONCLUSTERED INDEX [UF_Employee_UserID] ON [dbo].[Employee]
(
    [UserID] ASC--Not all Employees have a UserID to log into the System.
)
WHERE ([UserID] IS NOT NULL)--Enforce Uniqueness when not null.

현재 GUI를 사용하여 테이블을 편집하는 동안 SSMS에서 필터링된 인덱스를 생성할 수 없습니다.
그러나 열려 있는 테이블 디자이너를 모두 닫은 다음 인덱스 자체의 속성을 개체 탐색기에서 열 수 있습니다(위와 같이). 수동으로 인덱스를 만드는 대신 GUI를 사용하려는 경우.

가장 중요한 점 중 하나는 고유한 키 제약 조건으로는 할 수 없는 고유성을 유지하면서 열 값을 null로 유지하고 싶지만 고유한 키 인덱스를 사용하면 고유성을 유지하면서 열 값을 null로 유지할 수 있다는 것입니다.따라서 Null-able 유형의 고유한 열이 필요한 경우에는 고유한 인덱스가 필요합니다. 그렇지 않은 경우에는 고유한 키 제약 조건이 필요합니다.

언급URL : https://stackoverflow.com/questions/10263760/unique-key-vs-unique-index-on-sql-server-2008

반응형