要序列化还是保留一个单独的表?

时间:2011-02-22 12:51:26

标签: php mysql

对于我来说,这个问题在很多不同的场合都有所提升,但如果没有给出具体的例子,很难解释。所以这里:

让我们想象一下,我们正在PHP / MySQL中创建一个问题跟踪器数据库。有一个“任务”表。现在,您需要跟踪与特定任务相关联的人员(已评论或未评论)。当任务发生变化时,这些人将收到一封电子邮件。

有两种方法可以解决这种情况。一种是创建一个单独的表tasks_participants:

CREATE TABLE IF NOT EXISTS `task_participants` (
  `task_id` int(10) unsigned NOT NULL,
  `person_id` int(10) unsigned NOT NULL,
  UNIQUE KEY `task_id_person_id` (`task_id`,`person_id`)
);

并使用SELECT person_id WHERE task_id='XXX'查询此表。

如果有5000个任务,每个任务平均有4个参与者(记者,任务带来的主题,解决者和一个评论者)那么task_participants表将是5000 * 4 = 20 000行。 / p>

还有另一种方法:在tasks表中创建一个字段并存储person_id的序列化数组(JSON或PHP serialize())。然后就不需要这个20 000行表了。

你有什么评论,你会选择哪种方式?

3 个答案:

答案 0 :(得分:6)

使用多条记录。它促进了数据库规范化。规范化非常重要。更新序列化值维护起来并不好玩。通过多条记录,我可以让数据库使用INSERTUPDATEDELETE来完成工作。此外,您通过使用多值列限制未来的连接。

答案 1 :(得分:1)

绝对要做交叉引用表(你列出的第一个选项)。为什么呢?

  • 首先,不要担心交叉引用表的大小。如果无法处理简单的规模,关系数据库几十年前就已经出现了问题。交叉参考表。不要担心20K或200K记录等。事实上,如果你担心这样的事情,最好开始担心为什么你选择了一个关系数据库而不是一个键值数据库。在那之后,只有当它实际上开始出现问题时,您才可以开始担心添加索引或其他调整技术。

  • 其次,如果您序列化关联信息,则可能 opaque-如果您的数据的整个维度只有您的专用JSON应用程序可以查询。< / strong>将数据序列化到表中的单个单元格通常只有在嵌入式结构是(a)不包含您永远不需要在应用程序外部查询的数据的情况下才有意义,(b)不是您需要查询的内容有效的内部(例如,有任务的人的平均数(*)),以及(c)只是你没有时间正确建模或处于原型状态的东西。所以我上面说可能,因为通常情况下值得坚持的数据符合这些标准。

  • 最后,通过序列化您的数据,您现在不得不在代码中解决该序列化数据的任何计算,这只是浪费时间,您可以花费更多的工作效率。 您的数据库已经可以按照您需要的方式对数据进行切片和切块,但由于您的数据不是它理解的格式,您现在需要在代码中执行此操作。现在想象一下当您在V2中更改序列化数据结构时会发生什么。

我不会说没有用于序列化数据的用例(我自己也做过),但根据你的情况,这可能不是其中之一。

答案 2 :(得分:0)

已经有几个很好的答案,但他们用相当理论的术语来解释。这是我的(基本相同)答案,用简单的英语:

1)对于MySQL,20k记录 nothing 。如果它达到了2000万的记录范围,那么你可能想开始担心 - 但它仍然可能不会成为一个问题。

2)好的,我们假设您已将所有参与票证的人员连接到一个字段中。现在......快!告诉我爱丽丝有多少张门票!我有一种感觉,鲍勃正在搞砸事情,查理正在为他报道 - 你能不能给我一张他们同时工作过的门票清单,最后由谁触摸他们分开?

通过一个单独的表格,MySQL本身可以找到各种问题的答案,这些问题是关于谁在哪些票据上工作,它可以快速找到它们 。将所有内容塞入单个字段后,您几乎不得不求助于使用LIKE查询来查找(可能)相关记录,然后对查询结果进行后处理以提取重要数据并自行汇总。