2013-05-01 4 views
0

SQL Server에서 고유 인덱스는 NULL에 대한 비교가 NULL을 반환하는 나머지 SQL에서와 같이 NULL을 '다른 값'으로 처리하는 것으로 보입니다. 고유 인덱스 만들기 하나/유일한/단일 NULL

당신이 널 (NULL) 컬럼 K에 고유 인덱스가있는 테이블 ( t)를 가지고 말 : 좋은

K  V 
0  32 
1  12 
3  45 

모두.

그러나 그것은 또한

K  V 
0  32 
1  12 
3  45 
NULL 89  <-- Baaad 

그리고 그 반대로, 그것은 또한 다음과 같은 수 있도록 :

K  V 
NULL 89 
0  32 <-- not good 

나는 이것이 내가 널 (null)을 사용하고 같은 잠재적 인 재앙이 될 수 있습니다 볼 수 있습니다 더 이상 고장이없는 값을 나타내는 키 값 - 합계 및 내역이 중복 계산 또는 불일치로 연결됩니다.

사람들이 어디에서 반대쪽 (다중 NULL 허용)을하고 싶은지 궁금한 점은 수천 가지이지만 NULLs는 NULL을 NULL로 처리하고 싶지 않습니다. 널 (NULL)이 (만 허용 한 NULL 또는 열의 고유 값의 수)로


어떻게 SQL Server가 널 (null)을 치료하기 위해 얻을 수있는 고유 인덱스에?

+2

당신이 실제로 어떤 행동을하는지 명확하지 않습니다. "NULLs를 NULLs로 취급하십시오"라는 문구는 마치 문구에서 명백하게 보여야하는 것처럼 사용하지만, 나에게는 그렇지 않습니다. 또한 두 번째 예제가 불분명하다는 것을 알았습니다. –

+2

SQL-Server는 고유 제한 조건이있는 열에서 최대 하나의 'NULL'을 허용합니다. 다른 DBMS (이 경우 표준과 함께 사용)는 둘 이상의 Null을 허용합니다. 고유 한 부분 색인을 만들어이를 우회 할 수는 있지만 이것이 당신의 목표라고 생각하지 않습니다.목표가 실제로 무엇인지는 분명하지 않습니다. –

+0

글쎄, 내 생각에'NULL'과의 비교는'NULL'을 가져야합니다. 따라서 한 컬럼이 하나의'NULL'을 포함하고 있다면 다른 값 (NULL을 포함해서)에 대한 모든 비교는 실패해야합니다. 나는 그것이 '낙천적'인 것이 유용 할 수 있으며, 'NULL'은 고유하지 않은 미지를 나타낼 것이라고 가정 할 수 있지만, 내 경우 엔 비관적이며 데이터베이스의 무결성을 보장합니다. – Fowl

답변

1

당신이 원하는 것을 Andomar의 해석이 맞다면, 당신이 이미 가능한 모든 K 값을 포함하는 테이블이 경우 행할 수 있습니다 :

create table dbo.T (
    K int null, 
    V int not null, 
) 
go 
create table dbo.PossibleKs (
    K int not null 
) 
insert into dbo.PossibleKs (K) values (0),(1),(2) 
go 
create view dbo.TV 
with schemabinding 
as 
    select pk.K 
    from 
     dbo.T t 
      inner join 
     dbo.PossibleKs pk 
      on 
       t.K = pk.K or 
       t.K is null 
GO 
create unique clustered index IX_TV on dbo.TV (K) 

그리고 테스트의 경우 :

insert into dbo.T(K,V) values 
(0,  32), 
(1,  12), 
(3,  45) 
go 
insert into dbo.T(K,V) values 
(NULL,89) 
--Msg 2601, Level 14, State 1, Line 1 
--Cannot insert duplicate key row in object 'dbo.TV' with unique index 'IX_TV'. The duplicate key value is (0). 
--The statement has been terminated. 
go 
delete from dbo.T 
go 
insert into dbo.T(K,V) values 
(NULL,89) 
go 
insert into dbo.T(K,V) values 
(0,  32) 
--Msg 2601, Level 14, State 1, Line 1 
--Cannot insert duplicate key row in object 'dbo.TV' with unique index 'IX_TV'. The duplicate key value is (0). 
--The statement has been terminated. 
+0

인덱스 된 뷰를 매우 흥미롭게 창의적으로 사용합니다. 이것은 효과가있는 것처럼 보입니다. 고맙습니다! – Fowl

0

null 또는 고유 한 숫자가 필요합니다. 나는 그것이 제약 조건을 사용하여 확실하게 집행 될 수 있다고 생각하지 않는다.

트리거를 사용할 수 있습니다. 트리거는 다음과 같은 질문에 응답해야합니다. 행을 null으로 업데이트하고 있습니까? 이미 null 행이 있습니까? 이미 null 인 행을 업데이트하고 있습니까? 그 방아쇠는 복잡하고 유지하기가 어려울 것입니다.

저장 프로 시저를 사용하여 테이블을 조작 할 수 있습니다. 저장 프로시 저는 트랜잭션에서 갱신/삽입/삭제 작업을 수행 할 수 있습니다. 커밋하기 전에 테이블이 null 또는 다른 값으로 구성되어 있는지 확인할 수 있습니다. 당신은 합리적으로 그것을 유지할 수 있습니다.

디자인이 끝나면 구현하기 어려운 비정상적인 제약이 부과됩니다. 아마도 당신은 디자인을 다시 방문 할 수 있습니다.

+0

예 트리거가 차선입니다. :) 내 디자인이 실제로 그렇게 특이한 것 같지는 않습니다. 단지 모든 경우에 올바르게 처리 할 수 ​​있도록 쿼리의 복잡성을 크게 증가시킬 수있는 작은 유연성을 제거하는 것입니다. 이렇게하면 "사소한"쿼리가 올바르게 작동합니다. – Fowl