【问题标题】:Scalable one to many table (MySQL)可扩展的一对多表(MySQL)
【发布时间】:2009-07-12 17:55:07
【问题描述】:

我有一个 MySQL 数据库,该数据库中的特定表需要以一对多的方式自引用。对于可扩展性,我需要找到最有效的解决方案。对我来说最明显的两种方式是:

1) 向表中添加一个文本字段,并在其中存储主键的序列化列表

2) 保留一个链接器表,每一行都是一对一的。

在情况 #1 中,我看到表变得非常非常宽(使用空间类比),但在情况 #2 中,我看到链接器表增长到非常多的行,这会减慢查找速度(通过最常见的操作)。

在 MySQL 中实现这种一对多关系的最有效方式是什么?或者,也许有一个更明智的解决方案,以某种方式将数据全部直接保存在文件系统上,或者其他一些存储引擎上?

【问题讨论】:

  • 查找将是迄今为止最常见的操作。对关系的更新将比新条目更频繁。

标签: mysql scalability one-to-many


【解决方案1】:

只需为“many”保留一个表,为主表保留一个键列。

我保证,在您遇到标准工业级关系 dbms 的效率或容量限制之前,您还有许多其他更重要的问题需要解决。

恕我直言,最有可能的第二种选择(有许多替代产品)是使用 isam。

【讨论】:

  • 根据您的编辑评论:更新应该没问题,因为您将更新值而不是键(因此不会涉及索引。)如果记录很小,插入也不应该太多并且密钥分散良好,通常会自行处理。
  • 想到了一个解释问题的好方法。把它想象成社交网络上的“朋友列表”。每个帐户可以有很多很多被列为“朋友”的帐户(以 accountID 的形式)。将存储迁移到第三个表只是将相同的问题迁移到另一个表 - 在一种情况下,它变得非常宽,而在另一种情况下,它变得很长。当然,除非 MySQL 在使用这两种方法之一处理大量数据时实际上更有效。
【解决方案2】:

如果您需要对数据进行深度/递归遍历,像 Neo4j(我所在的团队)这样的图形数据库是一个不错的选择。您可以在文章Should you go Beyond Relational Databases?this post at High Scalability 中找到一些信息。对于可能与您类似的用例,请阅读此thread on MetaFilter。有关语言绑定和其他信息的信息,您可能还会发现 Neo4j wikimailing list 很有用。

【讨论】:

    【解决方案3】:

    与其说是答案,不如说是几个问题和一种可能的方法......

    如果你想让表格自引用并且只使用一个字段......有一些选项。计算的可屏蔽“连接”字段描述了一种将许多行相互关联的方法。

    最好的解决方案可能会考虑数据和关系的性质? 数据和查找的性质是什么?你试图包含什么样的关系?协会?有关的?父母/孩子?

    【讨论】:

      【解决方案4】:

      我的第一条评论是,除了您已经描述的内容之外,如果您能够描述数据的使用方式(添加/更新与查找的频率、添加与更新等),您将获得更好的回应。话虽这么说,我的第一个想法是使用

      的通用表示
      
      CREATE  TABLE IF NOT EXISTS one_table (
        `one_id` INT UNSIGNED  NOT NULL AUTO_INCREMENT
                 COMMENT 'The The ID of the items in the one table' ,
        ... other data
      )
      
      CREATE  TABLE IF NOT EXISTS many_table (
        `many_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT
                  COMMENT 'the id of the items in the many table',
        `one_id` INT UNSIGNED  NOT NULL
                 COMMENT 'The ID of the item in the one table that this many item belongs to' ,
        ... other data
      )
      

      当然,要确保在两个表中的 one_id 上创建索引。

      【讨论】:

      • 查找将是(到目前为止)最常见的操作。更新将比添加更频繁。我应该编辑这个问题 - 我提出这个问题做得很糟糕。
      • 注意:MySQL 中的无符号 INT 类型最多只支持 4,294,967,295 个值。基于海报 cmets 可能不足以用于“many_table”ID 记录。如果他需要超过 40 亿条记录,他应该使用未签名的 BIGINT。否则这也是我推荐的。不过,索引非常重要。
      • @Dennis Baker - 编辑以反映您的评论,因为您有一个好点。我不适合从我自己的代码中复制/粘贴,因为它更快;)
      猜你喜欢
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 2012-02-22
      • 1970-01-01
      • 2012-12-08
      • 2019-05-21
      • 1970-01-01
      • 2020-06-21
      相关资源
      最近更新 更多