2014-02-25 134 views
0

是否有可能具有复杂的检查约束?SQL扩展检查约束

例如我有一个客户表,其中每个记录都分配了一个客户类型。

因此,我可以有几个相同类型的客户。

我想为每种类型设置一个客户作为该类型的“主要”帐户,但每种类型只有一个客户可以是主要客户。

是否可以在IsPrimary字段上添加检查约束条件,检查所有相同类型的客户是否已经有一个标记为主要的客户?

我可以在C#代码中做到这一点,但我希望这是一个额外的检查。

我也可以使用触发器,但我想坚持约束,以便我可以以同样的方式处理所有错误的错误。

谢谢

+0

'CHECK'约束只能约束单列(列检查约束)或单列中的所有列(表检查约束)。标准SQL也描述了'ASSERTION',它可以应用于表中的所有行,但我并不认为已经有很多研究探讨如何使ASSERTION有效地执行,因此大多数数据库系统实际上并不实际执行它们。 –

回答

4

这不完全是一个检查约束问题。这是一个过滤的唯一索引问题。

create unique index customers_type_isprimary on customers(type) 
    where isPrimary = 1; 

这将保证最多只有一个客户有每种类型的isPrimary标志设置。

编辑:

筛选索引是一个有趣的创作。除了documentation之外,还有各种资源解释它们(如this)。

这个想法是只在与索引创建步骤中的where子句相匹配的行上构建索引。这样做的一个原因是减小索引的大小。

以下是您的数据结构用例。您可能有一堆查询在isPrimary = 1上进行过滤。你永远不会在isPrimary = 0上过滤 - 你只需从where条款中删除。为什么用所有不必要的值来混淆索引?如果谓词在查询中,则可以使用索引。

unique指数的情况更具说服力。已筛选的唯一索引完全符合您的要求 - 确保为每种类型设置至多一个值为IsPrimary。它通过在type上创建索引来执行此操作,仅适用于设置了IsPrimary的客户。索引中的“独特”部分保证每种类型只在索引中出现一次,并且只有一个客户可以为type设置IsPrimary

+0

请原谅我是一个白痴,但你能否进一步解释一下这是如何工作的?从我对索引的理解来看,这没有任何意义。 –

+0

谢谢你的工作就像一个梦想 –