【问题标题】:Database Designing: An art or headache (Managing relationships)数据库设计:艺术或头痛(管理关系)
【发布时间】:2011-03-19 08:53:14
【问题描述】:

我在过去的经验中看到,大多数人不会在表格中使用物理关系,他们会尝试记住它们并仅通过编码来应用它们。

这里的“物理关系”指的是主键外键检查约束等。

在设计数据库时,人们会尝试在纸上规范化数据库并将事情记录在案。比如,如果我必须为一家营销公司创建一个数据库,我会尝试了解它的要求。 例如,哪些字段是必填的,哪些字段将只包含(a 或 b 或 c)等。

当一切都清楚了,为什么大多数人都害怕束缚?

  1. 他们不想管理事情吗?
  2. 他们是否缺乏知识 (我不这么认为)?
  3. 他们对未来没有信心吗 有问题吗?
  4. 管理所有这些实体真的很难吗?

您认为原因是什么?

【问题讨论】:

  • 我猜有些团队先创建数据模式,然后为它创建一个或多个用户界面;其他一些人首先创建应用程序,然后在需要存储信息时随时修改他们的数据库......

标签: sql-server database database-design normalization


【解决方案1】:

嗯,我的意思是,我想每个人都有权拥有自己的意见和发展战略,但在我看来,这些人几乎肯定是错误的 :)

然而,有人可能希望避免约束的原因是效率。不是因为约束很慢,而是因为存储冗余数据(即缓存)是加速(嗯,避免)昂贵计算的一种非常有效的方法。这是一种可接受的方法,如果实施得当(即缓存定期/适当的间隔更新,通常我使用触发器来执行此操作)。

至于没有缓存动机而不是我们 FK 的动机,我无法想象。也许他们的目标是在他们的数据库结构中“灵活”。如果是这样,那很好,但是不要使用关系数据库,因为它没有意义。非关系型数据库 (OO dbs) 肯定有自己的位置,甚至可以说更好(颇有争议,但争论起来很有趣),但使用关系型数据库而不使用它的核心属性是错误的。

【讨论】:

  • 这是否意味着对数据库应用约束会使它们难以管理,如果管理不当可能会产生大问题。
  • @Shantanu:不,不是那个意思。而事实并非如此(事实上,反之亦然)。
【解决方案2】:

我总是让 DBMS 强制执行主键和外键约束;我也经常添加检查约束。就我而言,数据太重要了,不能冒存储不准确数据的风险。

如果您将数据库视为一系列存储的真实逻辑命题,您会发现如果数据库包含错误命题(错误),那么您可以争论任何您想要的结论。给定一个错误的前提,任何结论都是正确的。

为什么其他人不使用PK和FK约束等?

有些人没有意识到它们的重要性(因此缺乏知识绝对是一个因素,甚至是一个主要因素)。其他人害怕他们会在性能上花费太多,忘记了一个必须修复的错误可能很容易用完不让 DBMS 为您进行检查所节省的所有时间。我认为如果当前的 DBMS 不能很好地处理它们,那么可能(可能是)改变 DBMS 的时候了。

【讨论】:

  • 如果我将 42 存储到一个名为 Answer 的字段中,我不知道是否应该对其进行约束,因为它可能需要 750 万年......
【解决方案3】:

不按重要性降序执行关系有几个原因:

  1. 人性化的错误处理。 您的程序应该检查约束并向用户发送可理解的消息。出于某种原因,普通人不喜欢“SQL异常代码-100013 goble rule违反了table gook”。

  2. 操作灵活性。 您真的不希望您的操作员试图弄清楚您必须在凌晨 3 点加载表格的顺序,也不希望您的测试人员因为无法将数据库重置回其起始位置而拉扯他们的头发。

  3. 效率。 检查约束确实会消耗 IO 和 CPU。

  4. 功能。 这是一种节省详细信息以供以后恢复的廉价方法。例如,在在线订单系统中,当用户终止父订单时,您可以将详细项目行留在表中,如果他稍后恢复订单,详细信息会像奇迹一样重新出现 - 您可以通过以下方式实现此额外功能删除代码行。 (当然你需要一些整理过程,但这很简单!)

【讨论】:

  • 如果您将您的第一句话从不强制执行约束的“原因”更改为不使用约束的“借口”,我会赞成您的答案而不是反对它。
  • +1 为 ObiWanKenobi,-1 为 James Anderson。将孤立行视为一项功能并将其清理视为“微不足道”的内务处理过程需要一种罕见的视角。
【解决方案4】:

我总是会定义 PK 和 FK 约束。特别是在使用 ORM 时。让 ORM 对数据库进行逆向工程,而不是手动配置它以使用一些 PK 和 FK,这真的让每个人的生活都变得轻松

【讨论】:

    【解决方案5】:

    许多开发人员会在实际执行操作之前检查数据库上方代码中的约束。有时,这是由用户体验考虑驱动的(我们不想向无法保存到数据库的用户提供选择/选项)。在其他情况下,它可能是由与执行语句相关的痛苦驱动的,确定它失败的原因,然后采取纠正措施。大多数人会认为代码更易于维护,如果它预先进行检查,以及其他可能在起作用的业务逻辑,而不是通过异常处理程序采取纠正措施。 (并不是说这一定是一种理想的思路,但它是一种普遍的思路。)无论如何,如果您在发布声明之前进行检查,并且没有特别意识到数据库可能会被触及的事实如果应用程序/用户没有通过您的完整性强制代码进入,那么您可能会得出结论,数据库约束是不必要的,尤其是在使用它们可能会导致性能下降的情况下。此外,如果您在数据库上方的应用程序代码中检查完整性,则可能会认为在数据库本身中执行逻辑等效检查违反了 DRY(不要重复自己)。如果不小心管理,完整性规则的两种表现形式(数据库约束中的和数据库上方应用程序代码中的)原则上可能会变得不同步。

    另外,我不会低估选项 2,因为许多开发人员不太了解数据库约束,太容易了。

    【讨论】:

    • 我必须同意,开发人员倾向于考虑他们的应用程序是否需要这个,而不是考虑其他应用程序或进程是否也可能访问数据库。完整性检查属于数据库。如果有人想在插入之前检查它们,我可以,但它们首先属于数据库。您必须在所有数据插入/更新发生的唯一地方 - 数据库中保护数据的完整性。
    【解决方案6】:

    随着事情变得越来越复杂,数据库中需要更多的表和关系,您如何确保数据库开发人员记得检查所有这些?当您对添加新“非正式”关系的模式进行更改时,如何确保所有可能受影响的应用程序代码都被更改?

    您可能会突然删除应该保留的记录,因为它们具有开发人员在编写删除过程时忘记检查的相关数据,或者因为该过程在最后十个相关表添加到架构之前就已经到位。

    不正式建立PK/FK关系,实在是太鲁莽了。我处理从许多不同供应商和数据库收到的数据。您可以判断哪些存在数据完整性问题,这很可能是由于数据质量差而无法明确定义关系而导致的。

    【讨论】:

      猜你喜欢
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      相关资源
      最近更新 更多