2014-12-02 4 views
0

몇 가지 열이있는 표가 있습니다. A, B & C 및 DeletedDate라는 마지막 열. 그것의 nullable datetime.여기에 where 절을 추가하는 것이 좋은 생각입니까?

A, B & C에 고유 제한을 추가했습니다. 문제가 발견 될 때까지 제대로 작동했습니다. 삭제 된 날짜를 추가 한 후. 동일한 A, B & C 값에 대해 새 레코드를 추가 할 수 있어야합니다. 그러나 나는 고유 한 제약으로 인해 질 수 없습니다.

나는 두 가지 옵션이

  1. Where DeletedDate is not NULL

내 질문에 말을

  • 이 제약에 where 절을 추가 제약의 DeletedDate 열 포함 여기 참조 : 옵션은 더 나은를 & 이유는 무엇입니까?

  • +1

    제약 조건에 where 절을 추가 할 수 없습니다. 그건 말이 안되요. 실행중인 작업은 소프트 삭제 작업 중 하나입니다. –

    +0

    'A, B, C, '이 여러 개 있지만 'A, B, C, NULL'은 하나만 가질 수 있습니까? – Andrew

    +0

    @SeanLange True이지만 인덱스에 where 절을 추가 할 수 있습니다. 그러면 where 절이 필터링됩니다. –

    답변

    2

    옵션 2 : 고유 제한 조건에 WHERE 절을 사용할 수 없습니다. ,

    • 작은 :

      CREATE UNIQUE INDEX a_b_c_UQ_when_DeletedDate_is_null 
      ON TableName 
          (a, b, c) 
      WHERE DeletedDate IS NULL ; 
      
      옵션 1

      가 : 당신은 단순히 고유 제한 조건에 DeletedDate을 포함 할 경우, 다음이 문제가있는 그러나 당신은 filtered index 대신 사용할 수 있습니다 SQL-Server가 sql-Standard 에서처럼 고유 한 제약 조건을 구현하면 동일한 a, b, c 조합과 null 삭제 날짜가있는 2 개 이상의 행을 가질 수 있으므로 2 개 이상의 삭제되지 않은 행이 공존 할 수 있으며, 어느 쪽 요구 사항과 일치하지 않습니다. 물론 현재 구현에서는 문제가되지 않습니다. SQL Server가 향후 표준을 준수하기 위해 구현을 변경하기로 결정하면 이는 하나가 될 수 있습니다.

    • 이보다 더 중요한 문제는 같은 a, b, c 조합과 동일한 정확한 삭제 날짜가있는 2 개 이상의 행을 허용하지 않는다는 것입니다. 귀하의 경우에는 DeletedDatedatetime이고 date이 아니기 때문에 심각한 문제는 아닙니다. 동일한 명령문/트랜잭션으로 여러 행을 삭제하려고하면 약간의 어려움이있을 수 있습니다.

    +0

    나는이 옵션을 너무 좋아한다. 그런데 왜 옵션 1보다 더 좋다고 생각하니? –

    +0

    그 대답을 편집했습니다. –

    +0

    나는 그것이 사실이라고 생각하지 않는다. 제약 조건에 삭제 된 날짜를 포함하는 경우. 모든 고유 한 조합을 갖게되며 삭제 된 날짜는 한 번만 null이됩니다. 그것은 한 번 이상 존재할 수 없습니다. 그것은 제약 조건을 위반할 것입니다. –

    0

    날짜가 유한 해상도가 포함되어 있으며 항상 고유 한 값을 보장하지 않으므로 일괄 삭제 기능을 추가해야하는 경우 날짜를 포함하는 것이 좋습니다. 한 번에 열 가지를 지우는 길 아래로? 그들은 모두 동일한 삭제 날짜를 갖습니다.

    불행히도, 문제는 null 문제에 초점을 맞추기 위해 (적절하게) 추상적이어서, 나는 제약 조건에 대한 유스 케이스가 무엇인지 모르기 때문에 다른 접근법을 추천 할 수 없습니다. 그러나 Null 문제는 고유 한 날짜 값이있는 많은 문제 중 첫 번째 문제 일 뿐이므로 실제 질문에 대한 대답으로 "아니오"라고 대답합니다.

    1

    고유 인덱스에 대해 계산 된 열을 사용할 수 있습니다. DeletedDate을 사용할 수있는 경우 1과 같은 정적 값을 반환하고 그렇지 않은 경우 기본 키의 음수 카운터를 반환합니다.

    CREATE TABLE [dbo].[Test](
        [ID] [int] IDENTITY(1,1) NOT NULL, 
        [A] [int] NOT NULL, 
        [B] [int] NOT NULL, 
        [C] [int] NOT NULL, 
        [DeletedDate] [datetime] NULL, 
        [IsDeleted] AS (case when [DeletedDate] IS NULL then (1) else -(1)*[ID] end), 
    CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] 
    

    이제 A, B, C 및 IsDeleted에 고유 색인을 만들 수 있습니다.

    +0

    이것은 나에게 유용한 2 가지 옵션과 매우 다른 것 같습니다. 나는 정말로 감사 할 것입니다. 만약 당신이 어떤 옵션이 더 낫다는 것을 말할 수 있고 그 두 옵션에서 왜 ... –

    +0

    제 3의 옵션을 주셔서 감사합니다 :) –

    관련 문제