SQL:这是归一化了吗?实体中的额外字段

SQL: Is this normalized? Extra field in an entity

我正在为治疗师可以为客户进行测试进行测试的环境开发 ERD,并且有一条规则,在创建测试后,治疗师可以向其中添加项目,直到测试完成由用户。

有一个:

TestSession 实体

SessionID, 
TestID PK, 
etc etc

还有一个

测试实体

TestID
Taken t/f

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

拥有一个由触发器更新的 Test.Taken 字段或在需要时从 TestSession 中临时查找相同的信息更有意义吗?

我会尝试从实际角度回答。尽管规范化很重要,但我会从数据的实际使用方式出发进行更多设计。此外,我将提供基于 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 table.

2) 定义Test.Taken。得到和上面一样的信息,查询变得更简单更快:

SELECT T.TestID, T.Taken
FROM Test T

但是一个session的插入会稍微复杂一点(不需要trigger,使用transaction即可):

BEGIN TRAN
SET XACT_ABORT ON

INSERT INTO TestSession (TestID)
VALUES (@TestID)

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

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