복붙노트

[SQL] 어떻게 NULL 열에 고유 인덱스를 만드는 방법?

SQL

어떻게 NULL 열에 고유 인덱스를 만드는 방법?

NULLS를 허용하고있는 동안 나는, SQL 서버 I은 고유하기 위해 열의 값을 제한 할 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)

더 좋은 아이디어?

해결법

  1. ==============================

    1.이 순 목적에 위배로 확신 당신은 그렇게 할 수 없습니다.

    이 순 목적에 위배로 확신 당신은 그렇게 할 수 없습니다.

    그러나이 사람은 주위에 양질의 일자리를 갖고있는 것 같아요 : http://sqlservercodebook.blogspot.com/2008/04/multiple-null-values-in-unique-index-in.html

  2. ==============================

    2.http://msdn.microsoft.com/en-us/library/cc280372.aspx : SQL 서버 2008를 사용하여 필터링 된 인덱스를 만들 수 있습니다. (나는 그러나이 코멘트 쉽게 놓친대로 자신의 대답을 가치가 생각 사이먼은 주석으로이 추가를 참조하십시오.)

    http://msdn.microsoft.com/en-us/library/cc280372.aspx : SQL 서버 2008를 사용하여 필터링 된 인덱스를 만들 수 있습니다. (나는 그러나이 코멘트 쉽게 놓친대로 자신의 대답을 가치가 생각 사이먼은 주석으로이 추가를 참조하십시오.)

    또 다른 옵션은 고유성을 확인하는 트리거입니다, 그러나 이것은 성능에 영향을 미칠 수 있습니다.

  3. ==============================

    3.계산 된 칼럼 트릭 널리 "nullbuster"로 알려져있다; 내 노트 스티브 카스을 제공 :

    계산 된 칼럼 트릭 널리 "nullbuster"로 알려져있다; 내 노트 스티브 카스을 제공 :

    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)
    )
    
  4. ==============================

    4.엄밀히 번 분명히 이상이 고유 제한 조건을 위반 같은 값을 갖는 있기 때문에, 한 번만, 고유 널 (NULL) 열 (또는 열 집합)이 될 수 NULL (또는 널 (NULL)의 기록을) 말하기 (그리고 이것은 NULL 포함).

    엄밀히 번 분명히 이상이 고유 제한 조건을 위반 같은 값을 갖는 있기 때문에, 한 번만, 고유 널 (NULL) 열 (또는 열 집합)이 될 수 NULL (또는 널 (NULL)의 기록을) 말하기 (그리고 이것은 NULL 포함).

    그러나, 유효 "독특한 널 (NULL) 열"의 개념을 의미하지 않는다; 실제로에 엔티티 사이의 관계를 설정하는 별도의 테이블을 우리가 데이터베이스의 종류가 제대로 작동하려면 정규화하기위한 것입니다 것을 명심해야 관계형 데이터베이스에 구현하고 정상화는 일반적으로 몇 가지 (비 기업)의 추가를 포함한다 .

    하자의 작품은 하나의 "고유의 널 (NULL) 컬럼을"고려 기본적인 예를 들어, 그것은 더 같은 열을 확장하기 쉽다.

    우리는이 같은 테이블에 의해 표현 된 정보를 가정 해 봅시다 :

    create table the_entity_incorrect
    (
      id integer,
      uniqnull integer null, /* we want this to be "unique and nullable" */
      primary key (id)
    );
    

    우리는 떨어져 uniqnull 넣고 (오히려 the_entity "내부"uniqnull을하는 것보다) uniqnull 값과 the_entity 사이의 관계를 설정하는 두 번째 테이블을 추가하여 작업을 수행 할 수 있습니다 :

    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)
    );
    

    우리는 또한 the_relation의 행을 추가 할 필요가 the_entity의 행에 uniqnull의 값을 연결합니다.

    the_entity의 행에 대한 uniqnull 값이 관련되지 않은했다 (즉, 우리가 the_entity_incorrect에 NULL을 넣어 것입니다 것들에 대한) 우리는 단순히 the_relation의 행을 추가하지 마십시오.

    참고 uniqnull 값은 모든 the_relation 고유하고의 기본 키와 외래 키이 시행 이후 각 값에 대해 the_entity에, the_relation에서 최대 하나 개의 값이 될 수 있음을 또한 통지 될 것.

    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;
    

    the_entity_incorrect 같은 테이블에 저장할 것 데이터를이 정보를 비정규 및 얻으려면, 우리는해야합니다

    select
      id, uniqnull
    from
      the_entity left outer join the_relation
    on
      the_entity.id = the_relation.the_entity_id
    ;
    

    오퍼레이터가 the_entity 모든 행은 일치 열 the_relation에 존재하지 않을 때 uniqnull 열에 NULL을 가하고, 그 결과로 나타날 것이다 보장 "왼쪽 외부 조인".

    당신에게 고통과 자원 낭비의 년 (또는 수십 년을) 절약 할 몇 가지 일 (또는 몇 주 또는 몇 달) 잘 정규화 데이터베이스 설계 (및 해당 비정규 전망 및 절차)에 대한 지출 어떤 노력을 기억하십시오.

  5. from https://stackoverflow.com/questions/191421/how-to-create-a-unique-index-on-a-null-column by cc-by-sa and MIT license