【问题标题】:One multi-dimensional array vs. multiple tables with joined rows一个多维数组与具有连接行的多个表
【发布时间】:2017-10-19 18:02:12
【问题描述】:

我正在建立一个列表网站(没什么特别的,人们可以创建列表,例如“要观看的电影”或“要做的事情”,但学习东西很好)。

现状: 人们注册,我在users 表中为他们创建一行。在该行中,我有一个名为Lists 的列。在本专栏中,我存储了一个serialized array,其结构如下:

$lists = array(
            "To Do" => array(
                                "List Info" => array(
                                                    "add date" => 20170503,
                                                    "add time" => 130530
                                                    ),
                                array(
                                                    "item" => "Go to the supermarket",
                                                    "add date" => 20170503,
                                                    "add time" => 140503,
                                                    "completed" => false
                                                    ),
                                array(
                                                    "item" => "Clean my room",
                                                    "add date" => 20170503,
                                                    "add time" => 180503,
                                                    "completed" => false
                                                    ),
                                array(
                                                    "item" => "Go jogging",
                                                    "add date" => 20170503,
                                                    "add time" => 200503,
                                                    "completed" => true
                                                    )
                            ),
            "Movies To Watch" => array(
                                "List Info" => array(
                                                    "add date" => 20170504,
                                                    "add time" => 130530
                                                    ),
                                array(
                                                    "item" => "Zootopia",
                                                    "add date" => 20170504,
                                                    "add time" => 150503,
                                                    "completed" => true
                                                    ),
                                array(
                                                    "item" => "Anne The Series",
                                                    "add date" => 20170504,
                                                    "add time" => 190503,
                                                    "completed" => false
                                                    ),
                                array(
                                                    "item" => "Upside Down",
                                                    "add date" => 20170505,
                                                    "add time" => 230503,
                                                    "completed" => false
                                                    )
                            )
         );

这很好用,但我想知道这是否是正确的方法。特别是因为我想存储有关每个列表和项目的一些信息(add dateadd time,最终还有更多......)

创建多个表会更好吗:userslistslist items,然后通过用户 ID 进行内部连接?

我也有点想知道大型社交媒体网站是如何做到这一点的……例如 Twitter。他们是为每条推文添加一个新行,还是将一条新推文推送到数组中……或其他什么?

任何建议将不胜感激,

内森

【问题讨论】:

  • 简短回答:当然最好是制作多个表格。看看任何数据库入门,一定有成千上万的你可以谷歌。您的方法确实无法扩展。 (例如,您将如何搜索推文?)
  • 是的,我实际上有一个搜索功能,我会反序列化所有用户数组并获取匹配的列表项......这并不慢,但我可以想象它有超过 1000 个用户。 ;-) 谢谢

标签: php mysql arrays serialization multidimensional-array


【解决方案1】:

推荐的方法是像您提到的那样创建单独的表。 (users, lists, list_items)

你们的关系应该是这样的:

users -> lists = 由两个表中的user_id 列链接

lists -> list_items= 由两个表中的list_id 列链接

这也使您能够让用户拥有多个列表,而无需在您的用户表中添加额外的列。

如果您要继续将列表项添加到序列化数组中,那么一旦数组开始增长到一定大小,您将遇到性能问题,因为您有一个巨大的列条目需要排序。

如今,数据库在及时查看数百万甚至数十亿行时表现非常出色。只要记住在表连接的所有字段上都有索引。

您可能会争论 LONGBLOB 字段允许 4GB 的文本,但加载单个记录需要很长时间。将它们存储为行使您可以灵活地仅检索当时需要的行。而不是每次您都需要时都使用它们,甚至只需要一个

要回答您关于 twitter 的问题,是的,每条推文都会有一个新行。

来自 alexis 的 cmets 引用我觉得很有价值:

谷歌“规范化”,你会看到第一步(“第一 normal form") 是在每个单元格中只存储一个值。如果可以 想象一下您想要查询数据库的任何场景 单一设置,给他们都自己列。如果内容 设置对数据库完全透明,尤其是如果 它们是半结构化的(例如,一组不同的键值对), 那么可能有理由让数据库不知道什么是 设置是(即做你现在正在做的事情)。

一些关于数据库规范化的有用链接

【讨论】:

  • 感谢您的建议,我知道这样会更方便,但我认为浏览所有这些行比遍历一个数组需要更多时间。
  • 大小似乎不是问题,对吧?如果我只使用 LONGBLOB 数据类型?最多 4GB 的文本。
  • 如今,数据库在及时查看数百万甚至数十亿行时表现非常出色。只要记住在表连接的所有字段上都有索引。你可以争论允许 4GB 的文本,但是加载那条记录需要很长时间。将它们存储为行使您可以灵活地仅检索当时需要的行。而不是每次您都需要时都使用它们,甚至只需要一个
  • 好吧,我很高兴我得到了答案,但同时我很恼火我不得不重构我的整个网站哈哈。 :P
  • @Nathan 很高兴你想问,即使在这个后期阶段。现在比网站实际上大量使用大量数据时要好......
【解决方案2】:

简短的回答是,使用不同的表会更好。 否则,您将列表/内容的数量限制为字段的大小。

【讨论】:

  • 外部文件可以容纳更多,但我认为您的问题是在关系数据库的上下文中。看来您的计划是使用 mysql 作为 mongo db。
猜你喜欢
  • 2019-10-25
  • 2020-01-04
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 2016-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多