【问题标题】:Violating 1st normal form, is it okay for my purpose?违反第一范式,我的目的可以吗?
【发布时间】:2011-06-02 03:41:56
【问题描述】:

所以我正在制作跑步日志,并将锻炼作为条目存储在表格中。对于每次锻炼,用户可以添加间隔(由时间和距离组成),所以我有一个这样的数组:

[workout] =>
    [description] =>
    [comments] =>
    ...
    [intervals] =>
        [0] =>
            [distance] => 200m
            [time] => 32
        [1] =>
            [distance] => 400m
            [time] => 65
        ...

我真的很想将“intervals”数组放入 serialize() 或 json_encode() 并将其放入表中的“intervals”字段中,但这违反了良好数据库设计的原则(顺便说一下,我几乎一无所知)。

这样做有什么缺点吗?我从不打算根据“间隔”的内容查询我的表。只为区间创建一个单独的表格似乎有很多不必要的复杂性,所以如果有更多经验的人遇到过这样的情况,你采取了什么路线以及效果如何?

【问题讨论】:

  • 顺便问一下你用的是什么关系型数据库?
  • 好吧,我使用 CodeIgniter 的活动记录类来与数据交互,但 MySQL 是 RDBMS。
  • 刚刚阅读atomicity section here。我想最终这一切都归结为一个涉及这些变量的方程(a)您将来可能想要分解它的概率(b)现在不这样做的好处(c)以后改变主意的麻烦。

标签: database arrays serialization normalization


【解决方案1】:

如果您从不打算分解您存储的数据以对其进行搜索或读取/更新/删除/插入单个值,我会将其放入并将其视为单个原子实体以供您使用。

字符串可以分解为单个字符,但没有人声称它们违反了 1NF AFAIK。

【讨论】:

    【解决方案2】:

    这些值是数字的,这表明您最终会发现需要对它们执行某种数学函数,例如平均值或标准偏差。因此,您最好以可以使用 SQL 操作它们的方式存储它们,而不是将其拉回编程语言中。

    现在,这并不一定意味着您必须使用另一张桌子。但这无疑是最简单、最标准化的方法。但是,如果您真的想将它与其他数据一起存储在一个表中(即workout 表),请使用 XML。

    我说 XML 是因为大多数数据库引擎都提供非标准 SQL 来查询这些值。 SQL Server、Oracle 和 MySQL 都有这样做的方法。序列化将您绑定到您正在使用的任何编程语言(例如 Java)。 JSON 没有 SQL 支持 AFAIK,因此您仍然需要将其拉回编程语言中才能以有意义的方式进行操作。

    【讨论】:

    • +1 我想确实很有可能需要进行统计分析。
    • 你知道,我没有考虑对数据做任何统计,但假设我决定在未来做,我想在我要做的工作量之间有一个权衡现在,以及我以后会做的金额..
    【解决方案3】:

    我认为这是一个坏主意。例如,intervals 字段应该有多大?如果你把它分成两个表,因为它看起来像一个一对多的关系,你不需要考虑对间隔数的人为大小限制。

    此外,尽管您说您永远不需要根据时间间隔进行查询,但您以后可能会改变主意并找到您确实想要这样做的情况。为什么要限制你的能力并人为地非规范化这种特殊情况。创建两个表并不是那么复杂。此外,您始终可以将它们连接起来,以便将它们视为用于查询的单个逻辑数据集,并拥有两全其美的优势。

    【讨论】:

    • @Michael Goldshetyn:我将“间隔”想象成一个 CLOB,如果它与锻炼无关,那么对于所有实际意图来说,大小是无限的,你在想什么?
    • 是的,实际上最好将其描述为黑匣子中的用户数据。它不会被处理或分析,只是在用户想要查看时存储和检索。我唯一想知道的是,由于数据的性质是一种数组,将其存储为字符串(性能等)会有一些缺点。
    • 好吧,你说服了我。我想我现在要创建一个单独的表,以防将来需要使用这些值。它确实破坏了我之前的漂亮的小数据库设置......(一张用于用户,一张用于锻炼,一张用于会话 - 现在我有一个称为锻炼间隔哈哈)
    • @Michael Goldshetyn:好的,现在我有一个后续问题。对于第二个表“间隔”,我给它字段:锻炼 ID、距离和时间。但是,由于用户可以添加多个区间,因此该表中的两行可能相同,这也违反了 1NF。我只是给每一行一个间隔ID吗?这似乎有点毫无意义......
    • @Nick:不是给区间它自己的 ID,而是添加一个我称之为“基数”的列,它指示区间相对于锻炼中其他区间发生的顺序。然后对表中的所有列进行唯一约束。
    猜你喜欢
    • 2012-09-22
    • 2015-06-14
    • 2020-08-29
    • 2011-05-21
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 2021-12-07
    相关资源
    最近更新 更多