我有以下表格: 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,每个组每个部分只强制执行一个活动系统,并通过添加更多表来继续构建复杂约束。
有没有更好的方法来处理复杂的检查约束?
答案 0 :(得分:2)
您可以通过两种方式强制执行“单一活动记录”模式:
您建议的解决方案,即创建一个表,该表仅包含多个记录允许表中活动记录的主键值。这些值也可用作活动记录表中的主键。
将列添加到另一个表中,该表表示每个只能包含一个活动记录的对象。在这种情况下,这意味着将一列active_group_name添加到系统。此列将是允许多个记录的表的外键。
哪个更好,部分取决于每个部分是否必需才能拥有一个活动组,无论是 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
这种方法有几个优点: