实现复杂的检查约束

时间:2011-09-23 17:22:35

标签: sql

我有以下表格: CREATE TABLE group_systems ( 团队名字, 系统名称, SECTION_NAME, 创建日期, decom_date, 状态(活动,取消激活) )

CREATE TABLE系统 (   系统名称,   SECTION_NAME )

系统由密钥(system_name,section_name)标识。可以有重复的系统名称,但没有重复的部分名称。

在groups表中,我想强制执行约束,即组中某个部分中只有一个系统可以处于活动状态。但是,因为groups表也是历史表,所以我不能只使用唯一约束(group_name,section_name,system_name)。我必须使用运行子查询的检查约束。还有一些额外的约束是子查询。

问题是插入100k记录的基准测试需要很长时间(由于子查询)。

构建另一个引用回group_systems表的表active_systems_for_groups是否更好?这样,我可以将唯一约束添加到active_systems_for_groups,每个组每个部分只强制执行一个活动系统,并通过添加更多表来继续构建复杂约束。

有没有更好的方法来处理复杂的检查约束?

2 个答案:

答案 0 :(得分:2)

您可以通过两种方式强制执行“单一活动记录”模式:

  1. 您建议的解决方案,即创建一个表,该表仅包含多个记录允许表中活动记录的主键值。这些值也可用作活动记录表中的主键。

  2. 将列添加到另一个表中,该表表示每个只能包含一个活动记录的对象。在这种情况下,这意味着将一列active_group_name添加到系统。此列将是允许多个记录的表的外键。

  3. 哪个更好,部分取决于每个部分是否必需才能拥有一个活动组,无论是 common (但不是必需的)某个部分都有一个活跃的群体,或者某个群体是否只是偶尔会有一个活跃群体。

    在第一种情况(必需)中,您将使用选项(2)并且该列可以声明为NOT NULL,从而保持完全规范化。在第二种情况(常见)中,您需要使列成为NULLable,但我可能仍然使用该技术来方便JOIN。在第三种情况下(偶尔),我可能会使用选项(1),因为它可能会在JOINing获取活动记录时提高性能。

答案 1 :(得分:1)

由于您从未回答过您正在使用哪种RDBMS,因此我会将其抛弃给那些可能对在SQL Server(2008或更高版本)中轻松处理此约束的其他方式感兴趣的其他人。

您可以使用筛选的唯一索引有效地对给定类型的“活动”行数量设置约束。举个例子:

CREATE UNIQUE INDEX My_Table_active_IDX ON My_Table (some_pk) WHERE active = 1

这种方法有几个优点:

  1. 这是陈述性的
  2. 它在单个表中是独立的(没有 FK,没有其他需要保持更新的对象等。)