문제

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을 넣습니다.

잘 정규화 된 데이터베이스 (및 해당 비정상적인 견해 및 절차)를 설계하는 데 며칠 (또는 몇 주 또는 몇 달) 동안 소비되는 모든 노력은 수년 (또는 수십 년)의 통증과 낭비 자원을 절약 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top