【问题标题】:How important is database normalization in a very simple database?在一个非常简单的数据库中,数据库规范化有多重要?
【发布时间】:2011-04-14 17:34:44
【问题描述】:

我正在制作一个非常简单的数据库(mysql),其中包含两种类型的数据,始终具有 1 对 1 的关系:

活动

  • 赞助商
  • 时间(可选)
  • 位置(城市、州)
  • 地点(可选)
  • 详情网址

赞助商

  • 姓名
  • 网址


城市会经常重复,但是为这样一个简单的数据库架构创建一个城市表真的有什么价值吗?

数据库是通过对网站进行屏幕抓取来填充的。在这个站点上,城市字段是通过从下拉列表中选择来填充的,因此不会出现输入错误等情况,并且很容易将记录与城市表匹配。即使我的数据库的用户经常按城市搜索,我也不确定这是否有意义。

【问题讨论】:

  • 确定活动和赞助商之间存在一对一的关系吗?你做了什么让每个赞助商都疏远了,以至于他们再也不会赞助活动了?

标签: mysql database database-design database-normalization


【解决方案1】:

我认为您以错误的方式看待事物-除非您有充分的理由不这样做,否则您应该始终正常化。

信任您的应用程序来维护数据完整性是一种不必要的风险。您说数据是统一的,因为它是从下拉列表中选择的。如果有人入侵了表单并修改了数据,或者您的代码无意中允许了同名的查询字符串参数,该怎么办?

【讨论】:

    【解决方案2】:

    现在规范化数据库。

    优化对规范化数据的查询比规范化一堆数据要容易得多。

    你说现在很简单——这些东西有增长的趋势。设计正确,您将获得正确设计的经验和一些未来的证明。

    【讨论】:

    • 不能不同意 - 除非它只是一个练习,否则您的数据库结构几乎肯定会增长。
    • 作为@Broam 所说的警告:规范化后,您可能会遇到必须对数据进行反规范化以加快查询速度的地步。没关系,这是意料之中的。
    【解决方案3】:

    为什么继续规范化?你写的好像标准化的成本超过了收益。在填充之前将其设置为正常形式比稍后尝试对其进行规范化更容易。

    另外,我想知道你们的一对一关系。天真地,我会想象一个活动可能有多个赞助商,或者一个赞助商可能参与多个活动。但是我不知道你的业务逻辑...

    预计到达时间: 我不知道为什么我以前没有注意到这一点,但是如果您真的不喜欢规范化您的数据库,并且您知道您将始终在事件之间保持一对一的关系和赞助商,那么为什么要将赞助商放在单独的表格中?

    听起来你可能对什么是标准化以及为什么要这样做有点困惑。

    【讨论】:

      【解决方案4】:

      为用户填充下拉框的城市数据来自哪里?你不想要一张桌子吗?

      您似乎将位置视为一个属性,包括城市和州。假设您想仅按州而不是按城市和州对事件进行排序或分析?如果您没有状态属性,那可能很难做到。从逻辑上讲,我希望州属于城市表 - 尽管这可能取决于您要如何识别城市。

      【讨论】:

        【解决方案5】:

        直接回答:仅仅因为一个问题相对简单,没有理由不做一些事情来保持简单。用脚走路比用手走路容易得多。我不记得曾经说过,“哦,我只需要走半英里,那是很短的距离,所以我还不如用手走路。”

        更长的答案:如果您除了名称之外没有保留有关城市的任何信息,并且您没有预先设置的城市列表(例如构建下拉列表),那么您的架构已经归一化。除了城市名称之外,City 表中还有什么? (我假设 State 不能依赖于 City,因为你可以在不同的州有两个同名的城市,例如 Dayton OH 和 Dayton TN。)规范化的相关规则是“没有非关键依赖”,也就是说,你不能具有依赖于非键数据的数据。例如,如果您有每个城市的纬度和经度,那么这些数据将在引用同一城市的每条记录中重复。在这种情况下,您肯定会想打破一个单独的城市表来保存纬度和经度。当然,您可以创建一个“城市代码”,它是一个链接到城市表的整数或缩写。但是如果没有关于一个城市的其他数据,我看不出这有什么好处。

        从技术上讲,我认为 City 取决于 Venue。如果场地是“洛克菲勒中心”,那就意味着这个城市一定是纽约。但如果场地是可选的,就会产生问题。一种可能性是有一个列出场地名称、城市和州的 Venue 表,对于未指定场地的情况,每个城市都有一个“未指定”。这将更符合教科书的正确性,但在实践中,如果在大多数情况下你不指定一个地点,它会获得很少。如果您在大多数情况下都指定一个地点,那可能是个好主意。

        哦,还有,活动和赞助商之间真的存在 1:1 的关系吗?我可以相信一个活动不能有多个赞助商。 (在现实生活中,有很多活动有多个赞助商,但也许出于您的目的,您只关心“主要赞助商”之类的。)但是赞助商从不举办多个活动吗?这似乎不太可能。

        【讨论】:

        • 由于数据来自屏幕抓取,因此出于数据验证的目的尝试“规范化”城市和/或州并没有多大意义。只要 City 和 State 之间没有功能依赖关系(即 City -> State 或 State -> City),这里就不存在规范化问题。只要“位置”不是外键,正如您所指出的,就没有什么可以规范化的了。关于可能的场地/城市和活动/赞助商标准化问题的要点。 +1
        【解决方案6】:

        IMO 的答案取决于您是否要防止数据输入过程中的错误。如果这样做,您将需要一个 VENUES 表:

        VENUES
        City
        State
        VenueName
        

        还有一个 CITIES 和 STATES 表。 (注意:我见过同一个城市在同一个州多次出现的情况,通常是较小的城镇,因此 CITY/STATE 不包含唯一的二元组。通常有一个邮政编码来消除歧义。)

        为防止数据输入操作员进入 NY NY 的场所,而该场所实际上位于 SF CA,您需要验证场所条目以查看记录中提供的城市/州是否存在此类场所.

        然后您需要强制 CITY/STATE,并且必须编写代码来回滚事务并处理错误。

        如果您不关心强制执行这种准确性,那么您实际上也不需要 CITY 和 STATES 表。

        【讨论】:

          【解决方案7】:

          如果您有兴趣了解规范化,则应该了解不进行规范化时会发生什么。对于每个范式(超过 1NF),都会出现一个更新异常,该异常会因有害冗余而发生。

          通常可以围绕更新异常进行编程,有时这比始终归一化到最终程度更实用。

          有时,由于无法规范化以及未能对应用程序进行编程以进行补偿,数据库可能会进入不一致状态。

          在您的示例中,我能想到的最好的方法是一种蹩脚的假设。如果一个城市的名字在一行中拼写错误,但在所有其他地方都拼错了怎么办。如果您按城市和赞助商进行汇总呢?您的输出将反映错误,并将一组分为两组。如果这个城市在数据库中只拼写一次,也许会更好或更坏。即使名称拼写错误,至少摘要的分组是正确的。

          这值得规范化吗?嘿,这是你的项目,不是我的。你决定

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-03
            • 2016-07-23
            • 2010-12-16
            • 1970-01-01
            • 2013-01-18
            • 2012-11-18
            • 2016-11-18
            • 2010-09-17
            相关资源
            最近更新 更多