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 或更多),可以使用第一种方法,因为它简化了数据持久性并降低了不一致的风险。对于性能成为问题的非常大的结构,冗余可能会有所帮助。
我正在为治疗师可以为客户进行测试进行测试的环境开发 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 或更多),可以使用第一种方法,因为它简化了数据持久性并降低了不一致的风险。对于性能成为问题的非常大的结构,冗余可能会有所帮助。