Null 열에서 고유 한 인덱스를 만드는 방법은 무엇입니까?
-
08-07-2019 - |
문제
SQL Server 2005를 사용하고 있습니다. 널을 허용하면서 열의 값을 고유 한 것으로 제한하고 싶습니다.
내 현재 솔루션에는 다음과 같은 뷰의 고유 한 색인이 포함됩니다.
CREATE VIEW vw_unq WITH SCHEMABINDING AS
SELECT Column1
FROM MyTable
WHERE Column1 IS NOT NULL
CREATE UNIQUE CLUSTERED INDEX unq_idx ON vw_unq (Column1)
더 나은 아이디어가 있습니까?
해결책
독창적 인 목적을 위반하기 때문에 그렇게 할 수 없습니다.
그러나이 사람은 주변에 괜찮은 작업을하는 것 같습니다.http://sqlservercodebook.blogspot.com/2008/04/multiple-null-values-in-unique-index-in.html
다른 팁
SQL Server 2008을 사용하면 필터링 된 색인을 만들 수 있습니다. http://msdn.microsoft.com/en-us/library/cc280372.aspx. (Simon이 이것을 의견으로 추가했지만 의견이 쉽게 놓칠 수 있으므로 자체 대답을받을 자격이 있다고 생각했습니다.)
또 다른 옵션은 고유성을 확인하는 방아쇠이지만 성능에 영향을 줄 수 있습니다.
계산 된 열 트릭은 "널 버스터"로 널리 알려져 있습니다. 내 노트는 Steve Kass를 신용합니다.
CREATE TABLE dupNulls (
pk int identity(1,1) primary key,
X int NULL,
nullbuster as (case when X is null then pk else 0 end),
CONSTRAINT dupNulls_uqX UNIQUE (X,nullbuster)
)
엄격히 말하면, 고유 한 널리 잡을 수있는 열 (또는 열 세트)은 동일한 값 (및 여기에는 널 포함)이 한 번 이상 널 (또는 널 레코드) 일 수 있습니다.
그러나 이것이 "고유 한 무효 열"의 개념이 유효하다는 것을 의미하지는 않습니다. 실제로 모든 관계형 데이터베이스에서이를 구현하려면 이러한 종류의 데이터베이스는 올바르게 작동하도록 정규화되어야하며 정규화는 일반적으로 엔티티 간의 관계를 설정하기 위해 여러 (비 엔티티) 추가 테이블을 추가해야합니다. .
하나의 "고유 한 무효 열"만 고려한 기본 예를 작성해 보겠습니다. 더 많은 열로 확장 할 수 있습니다.
다음과 같은 테이블로 표시되는 정보를 가정 해보십시오.
create table the_entity_incorrect
(
id integer,
uniqnull integer null, /* we want this to be "unique and nullable" */
primary key (id)
);
Uniqnull을 분리하고 두 번째 테이블을 추가하여 Uniqnull 값과 _entity 사이의 관계를 설정하여 ( "the_entity 내부에 Uniqnull"을 갖지 않고) : :
create table the_entity
(
id integer,
primary key(id)
);
create table the_relation
(
the_entity_id integer not null,
uniqnull integer not null,
unique(the_entity_id),
unique(uniqnull),
/* primary key can be both or either of the_entity_id or uniqnull */
primary key (the_entity_id, uniqnull),
foreign key (the_entity_id) references the_entity(id)
);
Uniqnull의 값을 _entity의 행에 연관 시키려면 the_relation에 행을 추가해야합니다.
_entity의 행은 Uniqnull 값이 관련이 없기 때문에 (즉, the_entity_incorrect에 null을 넣을 것)는 단순히 _relation에 행을 추가하지 않습니다.
Uniqnull에 대한 값은 모든 _relation에 대해 고유하며, 또한 각 값에 대해 각 값에 대해 1 차 및 외래 키가이를 시행하기 때문에 최대 하나의 값이있을 수 있습니다.
그런 다음 Uniqnull의 5 값이 3의 the_entity ID와 연관 되려면 다음을 수행해야합니다.
start transaction;
insert into the_entity (id) values (3);
insert into the_relation (the_entity_id, uniqnull) values (3, 5);
commit;
그리고, the_entity에 대해 10의 ID 값에 Uniqnull 상대가없는 경우, 우리는 만 수행합니다.
start transaction;
insert into the_entity (id) values (10);
commit;
이 정보를 정규화하고 데이터를 얻으려면 _entity_incorrect와 같은 테이블을 얻으려면 다음을 수행해야합니다.
select
id, uniqnull
from
the_entity left outer join the_relation
on
the_entity.id = the_relation.the_entity_id
;
"왼쪽 외부 결합"연산자는 결과에 _entity의 모든 행이 나타나고 일치하는 열이 없을 때 Uniqnull 열에 null을 넣습니다.
잘 정규화 된 데이터베이스 (및 해당 비정상적인 견해 및 절차)를 설계하는 데 며칠 (또는 몇 주 또는 몇 달) 동안 소비되는 모든 노력은 수년 (또는 수십 년)의 통증과 낭비 자원을 절약 할 수 있습니다.