SQL:这是规范化的吗?实体中的额外字段

时间:2016-04-10 04:13:15

标签: sql entity-relationship database-normalization erd

我正在研究ERD,因为治疗师可以为客户进行测试,并且有一个规则,即在创建测试后,治疗师可以在测试完成之前添加项目。由用户。

有一个:

TestSession实体

SessionID, 
TestID PK, 
etc etc

测试实体

TestID
Taken t/f

如果添加了匹配TestID的Session,会有一个触发器将Test.Taken设置为true。组成员提出Test.Taken重复且未规范化的情况,因为可以根据需要通过搜索TestSession来获取特定TestID来近似相同的信息。在这种情况下,归一化为4NF或BCNF。

通过触发器更新Test.Taken字段或在TestSession需要时查找相同的信息更有意义吗?

1 个答案:

答案 0 :(得分:1)

我会从实际角度尝试答案。虽然规范化很重要,但我会从数据的实际使用方式开始设计更多。另外,我将提供基于T-SQL的示例,但它们可以轻松转换为任何SQL风格。

1)未定义Test.Taken 。要获取实体信息及其用法,您应该编写如下查询:

SELECT T.TestID, CAST((WHEN TS.TestID IS NOT NULL THEN 1 ELSE 0 END) AS BIT) AS Taken
FROM Test T
    LEFT JOIN TestSession TS ON TS.TestID = T.TestID

如果在多个地方使用它,可以将其体现为视图。

要在您的结构中插入数据,只需在INSERT表中创建TestSession

2)定义Test.Taken 。要获得与上述相同的信息,查询将变得更简单,更快捷:

SELECT T.TestID, T.Taken
FROM Test T

但是,会话插入会稍微复杂(不需要触发,只需使用事务):

BEGIN TRAN
SET XACT_ABORT ON

INSERT INTO TestSession (TestID)
VALUES (@TestID)

UPDATE Test SET Taken = 1 WHERE TestID = @TestID
COMMIT

如果您不处理大量记录(约10-100M或更多),可以使用第一种方法,因为它可以简化数据持久性并降低不一致的风险。对于性能成为问题的非常大的结构,冗余可能会有所帮助。