我正在研究ERD,因为治疗师可以为客户进行测试,并且有一个规则,即在创建测试后,治疗师可以在测试完成之前添加项目。由用户。
有一个:
SessionID,
TestID PK,
etc etc
和
TestID
Taken t/f
如果添加了匹配TestID的Session,会有一个触发器将Test.Taken
设置为true。组成员提出Test.Taken
重复且未规范化的情况,因为可以根据需要通过搜索TestSession
来获取特定TestID来近似相同的信息。在这种情况下,归一化为4NF或BCNF。
通过触发器更新Test.Taken
字段或在TestSession
需要时查找相同的信息更有意义吗?
答案 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或更多),可以使用第一种方法,因为它可以简化数据持久性并降低不一致的风险。对于性能成为问题的非常大的结构,冗余可能会有所帮助。