두 열에서 중복 값을 방지하기 위해 테이블 ​​제약 조건을 만드는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/626609

  •  06-07-2019
  •  | 
  •  

문제

다음 표가 있습니다.

CREATE TABLE [dbo].[EntityAttributeRelship](
    [IdNmb] [int] IDENTITY(1,1) NOT NULL,
    [EntityIdNmb] [int] NOT NULL,
    [AttributeIdNmb] [int] NOT NULL,
    [IsActive] [bit] NOT NULL CONSTRAINT [DF_EntityAttributeRelship_IsActive]  DEFAULT ((0)),
CONSTRAINT [PK_EntityAttributeRelship] PRIMARY KEY CLUSTERED 
([IdNmb] ASC) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]

테이블의 데이터의 일부는 다음과 같습니다.

IdNmb    EntityIdNmb    AttributeIdNmb  IsActive
1        22             7               0
2        22             8               0
3        22             9               0
4        22             10              1

EntityIDNMB에 대한 레코드가 이미있는 경우 아무도 isactive = 1을 갖도록 레코드를 추가하거나 업데이트하지 않도록 제약을 추가하고 싶습니다.

어떻게해야합니까?

도움이 되었습니까?

해결책

SQLServer를 사용하는 경우 클러스터 된 인덱스보기를 만들 수 있습니다.

CREATE VIEW dbo.VIEW_EntityAttributeRelship WITH SCHEMABINDING AS
SELECT EntityIdNmb 
FROM dbo.EntityAttributeRelship
WHERE IsActive = 1
GO

CREATE UNIQUE CLUSTERED INDEX UIX_VIEW_ENTITYATTRIBUTERELSHIP 
  ON dbo.VIEW_EntityAttributeRelship (EntityIdNmb)

이렇게하면 테이블에 isactive = 1이있는 EntityIdnmb가 하나뿐입니다.

다른 팁

트리거를 구현 해야하는 것처럼 들립니다 (DB 제품이 지원한다고 가정). 하나의 활성화와 하나의 비활성 항목 만 원한다면 고유 한 색인이 작동합니다. 그렇지 않으면, 둘 다 활성화 된 동일한 ID가있는 2 개의 레코드가 없는지 확인하는 일종의 사용자 정의 제약 또는 트리거 (아마도 2- 인서트 용, 업데이트 용)를 작성해야합니다.

MSSQL을 사용하는 경우 (구문이 보이는 것 같아요) IsActive = 1 인 행 만 포함하여보기를 작성한 다음 entityIDNMB에 고유 한 인덱스를 뷰에 넣으십시오.

최근에 더 많은 작업을했던 PostgreSQL에서는 부분 색인을 만들 수 있습니다.http://www.postgresql.org/docs/8.3/interactive/indexes-partial.html

트리거를 작성하는 것은 레코드를 거부할지 여부를 결정하고, 하나 대신 0으로 값을 변경하거나 이전 레코드를 0으로 업데이트 하고이 하나를 하나로 두는 것입니다. 1의 값으로 레코드를 삭제하는 경우 다른 레코드를 활성으로 변경해야합니까? 트리거 내에서하려는 waht를 정의 할 수 있으면 프로세스를 설계하는 데 더 잘 도움이 될 수 있습니다.

우리는 후자의 두 단계를 수행하여 데이터베이스의 메인 메일 링 주소를 만들기 위해 두 단계를 수행합니다. 우리의 비즈니스 규칙은 하나의 주소가 주요 주소 일 수 있으며 주소가 있으면 주소가 주소로 표시되어야합니다. 이런 종류의 트리거의 핵심은 인서트/업데이트/삭제가 배치로 (표준이 아닌 경우에도) 발생할 수 있고 트리거가 세트 기반 방식으로 작동하는지 확인하는 것입니다. 내가 여기에 도착했을 때, 우리는 커서를 통해 멀티 로우 처리를 구현했는데, 이는 수입에서 20 만 주소를 업데이트해야 할 때 나쁜 일이되었습니다. (경험이없는 사람들에게 주목 - 트리거에서 커서를 사용하지 마십시오!)

비활성 기록은 무엇을 사용합니까? 그들은 사용하지 않고 단순히 이전에 활성화 된 기록을 추적하기 위해 거기에 있습니까? 그렇다면 데이터를 여러 테이블로 분할 할 수 있습니까? ... 같은 ...

EntityAttributerelship (idnmb, entityIdnmb, attributeIdnmb)

EntityAttributerelshiphistory (idnmb, entityIdnmb, attributeIdnmb)

EntityAttributerelship 테이블에 있으면 활성화됩니다. 그것이 역사 테이블에 있다면 어느 시점에서 활성화되어 이후 비활성화 되었습니까?

하나의 테이블에 모든 것이 필요하면 Todd.run의 트리거 사용 제안과 함께 갈 것입니다.

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