查询可能会被意外删除,从而产生更多问题。
这就是版本控制软件的用途。此外,如果您可以“意外”删除视图,则可能会意外删除表。
他说第二范式就足够了,就像他在过去的所有系统中所做的那样。
那他的经验还不够。特别是在会计方面。
我因坚持下属在 5NF 中给我高性能设计而闻名(或臭名昭著)。如果他们不能这样做,他们可能要么 a) 不知道 5NF 是什么,要么 b) 认为每一行都应该有一个 ID 号。(每行都有一个 id 号会增加所需的连接数量,通常会导致性能下降,并且与规范化无关。)这两者都是很好的教育机会。
BCNF可能已经足够好了。2NF 通常不是。
如果您输了这场战斗,请坚持使用 CHECK() 约束以确保总数始终正确。
与我们合作的人(没有足够的技术知识)无法从没有足够属性/行的表中进行他们想要的查询。
添加一些视图将在短期内帮助您。您可能需要添加一些可更新的视图。但是,您有权要求将要在生产级注册系统中处理会计数据的人员具备一定水平的技术知识。
其他系统,如会计、工资、库存和采购,计划与注册系统集成。他说,如果是这种情况,最好将每个新系统数据库直接连接到我们的注册系统数据库,而无需访问查询。
视图(查询)和表共享一个命名空间。客户端代码没有说“我想连接到一个表,而不是一个视图,它必须被命名为‘student_payments’。” 客户端代码只是说,“连接到‘student_payments’。”
也就是说,任何有权插入付款表的人都更清楚如何正确插入付款表。如果您最终不得不包含一个作为对其他列的计算结果的列,请坚持使用 CHECK() 约束。
有些系统的设计方式是所有客户端访问都通过存储过程进行,并且客户端代码无法直接访问表。当有效事务必须一次插入多个表时,这种方法很有意义。
他认为,所有相关行,例如每个学生的计算平均成绩也必须包含在表中,因为他说,我们需要的是物理数据,而不是通过视图重新计算。
您需要的是数据库始终为您提供正确的答案。
更重要的是,我猜是他希望每笔交易都输入数据库。就像为了平衡交易而进行的借记和贷记一样。
最后,一些明智的事情。金融交易一般只插入。如果它们不正确,则不会更新或删除它们。相反,您插入一个补偿事务。(而且,我希望,它的原因。)
实际上,我不会在第一个版本中包含计算列。只有当它们的缺席造成实际的性能问题时,我才会添加它们。
话虽如此,我在识别实际性能问题方面有一个相当高的标准。如果 Vinny 副总裁必须等待 5 秒钟才能返回查询,这并不是实际的性能问题。如果一个需要 5 秒的查询每天都在阻塞其他查询并降低整体性能,那么这就是一个实际的性能问题。
不要根据单个 SELECT 语句的行为来确定性能问题。理想情况下,您对性能问题的确定应该基于整个系统的行为。实际上,它基于具有代表性的 SQL 语句样本的行为。在遇到性能问题之前,选择一个具有代表性的 SELECT、INSERT 和 DELETE 语句。用有代表性的样本数据测试它们,并至少存储时间。理想情况下,存储他们的执行计划和时间安排。
我不会仅仅为了在表中包含“真实”数据而包含计算列。
如果我必须通过存储计算结果来解决实际的性能问题,我不会在不首先做这些事情的情况下发布它。
- 如果约束需要对单行进行计算,我会包含一个 CHECK() 约束以保证计算的值始终正确。
- 如果约束需要对多行进行计算,我会包含一个断言或触发器来实现约束。我还会仔细查看 dbms 文档,寻找触发器可能不会触发的实例。(在某些平台上,触发器不会在批量加载期间触发。)
- 如果我不能使用 CHECK() 约束、断言或触发器,我会实现某种管理过程,最好是在存储过程或其等效程序中编码,以定期搜索实际总数不匹配的数据预计总数。如果我不能在 SP 中实现它,我会在 cron 作业下运行的应用程序代码中实现它。有很多方法可以做到这一点,而不会对其他流程产生重大影响。
通常,即使我还使用声明的约束,我也会实施定期管理程序来检查丢失或计算错误的数据。任何拥有足够权限的人都可以出于正当理由、不正当理由或根本没有理由放弃或禁用约束。(拥有高权限的人——包括你自己——是你最危险的用户。)