我需要弄清楚一个设计错误的解决方法,现在修复已经太晚了。我基本上希望重复的数据进入一个特定结构的表来避免它:
CREATE TABLE building (
building_id INT IDENTITY(1, 1) NOT NULL,
address_id INT NOT NULL,
company_id INT NOT NULL,
CONSTRAINT building_pk PRIMARY KEY (building_id),
CONSTRAINT building_fk1 FOREIGN KEY (address_id) REFERENCES address (address_id),
CONSTRAINT building_fk2 FOREIGN KEY (company_id) REFERENCES company (company_id)
);
CREATE INDEX building_idx1 ON building (address_id);
CREATE INDEX building_idx2 ON building (company_id);
/* Prevent dupes */
ALTER TABLE building ADD CONSTRAINT building_uk1 UNIQUE (address_id);
(原始本地化名称已更改,以使其更清晰且与问题相关。)
Acme Inc.的 export buildings API将发送共享相同地址的不同建筑物。删除building_uk1
会破坏某些假设唯一性的功能,此时我们无法承担重大的重写。
我想评估仅针对上述公司(building_uk1
)禁用company_id=314
的效果,这可能没有依赖于唯一性的功能。我有哪些选择放松building_uk1
并仅在company_id
不是314时强制执行?
答案 0 :(得分:6)
一个简单的唯一filtered index就足够了:
CREATE UNIQUE NONCLUSTERED INDEX [IX_building_uk1] ON [dbo].[building]
(
[address_id] ASC
)
WHERE (company_id <> 314)
答案 1 :(得分:0)
你可以通过检查收集来实现这一点,让我看看我是否理解你的要求正确
创建一个函数,如果它不是building_id 314那么将检查它是否
CREATE FUNCTION CheckDistinctConstraint ()
RETURNS int
AS
BEGIN
DECLARE @retValue int = 0
DECLARE @cnt int = 0
DECLARE @distcnt int = 0
SELECT
@cnt = COUNT(*),
@distcnt = COUNT(DISTINCT address_id)
FROM building
WHERE company_id <> 314
IF @cnt <> @distcnt
BEGIN
SET @retValue = 1
END
RETURN @retValue
END
通过应用此功能添加约束
ALTER TABLE dbo.Building
ADD CONSTRAINT CheckDistConstraint CHECK (dbo.CheckDistinctConstraint() =0);
创建表脚本
CREATE TABLE building (
building_id INT NOT NULL,
address_id INT NOT NULL,
company_id INT NOT NULL--,
CONSTRAINT building_pk PRIMARY KEY (building_id)--,
--CONSTRAINT building_fk1 FOREIGN KEY (address_id) REFERENCES address (address_id),
--CONSTRAINT building_fk2 FOREIGN KEY (company_id) REFERENCES company (company_id)
);
--inserts successfully
insert into building ( building_id, address_id, company_id) values
(1,11,22)
--insert failed bcos check constraint
insert into building ( building_id, address_id, company_id) values
(5,11,315)
-- insert successfull eventhough duplicate in address_id but building_id is 314
insert into building ( building_id, address_id, company_id) values
(311,11,314)
不确定你是否看起来像这样?