0

如需更多说明,请在此处查看我的旧帖子 数据库规范化 - 谁是对的?

我很欣赏这些好的答案,但我想强调的是,我们正在制作的这个系统不仅仅是为了学习。这是我们学校真正的招生制度。我们大约四个月前开始工作,除了对非规范化的困惑之外,系统一切正常。

就像我说的,他的原因是: 1.查询可能会被意外删除,从而产生更多问题。

  1. 他说第二范式就足够了,就像他在过去的所有系统中所做的那样。

  2. 与我们合作的人(没有足够的技术知识)无法从没有足够属性/行的表中进行他们想要的查询。(在我的例子中,我决定删除总单位,因为可以很容易地从其他属性中计算出来。 )

  3. 其他系统,如会计、工资、库存和采购,计划与注册系统集成。他说,如果是这种情况,最好将每个新系统数据库直接连接到我们的注册系统数据库,而无需访问查询。

  4. 他认为,所有相关行,例如每个学生的计算平均成绩也必须包含在表中,因为他说,我们需要的是物理数据,而不是通过视图重新计算。

  5. 更重要的是,我猜是他希望每笔交易都输入数据库。就像为了平衡交易而进行的借记和贷记一样。

就我而言,根据我从他那里听到的消息,除了从查询中进行查询(我相信这是我们需要非规范化的主要原因)之外,他没有提到任何关于速度的事情。他只是想要数据库中记录的所有内容。

我的立场与所有这些相反。如果准确性是我们对速度的关注,那么规范化是完美的,顺便说一下我们使用的是 microsoft sql server。

最后一件事,我记得他想在 students_info 表中包含 full_name 列。他的理由?他说“从表中读取比进行另一个查询更好。只要确保程序可以控制用户输入的全名”。

在我决定停止制作这个系统之前,请让我知道你,更有经验的人。

4

3 回答 3

3

查询可能会被意外删除,从而产生更多问题。

这就是版本控制软件的用途。此外,如果您可以“意外”删除视图,则可能会意外删除表。

他说第二范式就足够了,就像他在过去的所有系统中所做的那样。

那他的经验还不够。特别是在会计方面。

我因坚持下属在 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 作业下运行的应用程序代码中实现它。有很多方法可以做到这一点,而不会对其他流程产生重大影响。

通常,即使我还使用声明的约束,我也会实施定期管理程序来检查丢失或计算错误的数据。任何拥有足够权限的人都可以出于正当理由、不正当理由或根本没有理由放弃或禁用约束。(拥有高权限的人——包括你自己——是你最危险的用户。)

于 2012-05-27T11:45:52.673 回答
0

如果您正在创建一个可以更新所有数据的数据库,那么规范化是正确的方法。您希望确保当数据项发生更改时,结果会传播到各处。您可能不需要深奥的规范化范围(例如,如果您知道所有地址都在美国,则可以使用两个字符的州代码)。

要解决“查询被删除”等问题,请使用视图。这些允许您将数据的报告视图连接到基础数据结构。毕竟,最适合保持数据一致性的方法可能不适合报告。

最终,根据我的经验,您将走向数据集市解决方案。您将拥有操作应用程序的标准化形式的基础数据。您将有另一组表,从这些表派生出来,用于报告目的。这些表格将是非规范化的、冗余的,并且对于不同的组看起来会有所不同——有些可以通过 Web 访问,有些可以通过 Excel 访问,有些可以提供给其他应用程序(例如预算预测)。但是,在您到达那里之前,视图应该可以很好地满足查询需求。

于 2012-05-27T14:35:57.320 回答
0

是的,如果您正在创建数据仓库。而不是规范化并拥有数百甚至数千个表。您可以非规范化并拥有更少的表。少加入。它将更好地优化,因为查询仓库的人会更少。

于 2016-08-06T04:54:32.267 回答