0

我正在开发一个最终将拥有数百万用户的系统。系统的每个用户都可以访问系统中的不同“标签”。我正在使用一个名为 usertabs 的表来跟踪它。有两种方法可以处理这个问题。

方式 1:每个用户的单行包含 userid 和 tab1-tab10 作为 int 列。

该系统的优点是通过用户 ID 获取单行的查询非常快,而缺点是“空”列占用空间。另一个缺点是,当我需要添加一个新选项卡时,我必须重新组织整个表,如果有数百万条记录,这可能会很乏味。但这不会经常发生。

方式2:单行包含userid和tabid,仅此而已。每个用户最多可以有 10 行。

该系统的优点是易于分片或其他优化存储的机制,并且不会浪费空间。行仅在必要时存在。缺点是每次访问记录时必须读取多达 10 行。如果这些行是分散的,它们的访问速度可能会更慢或更快,这取决于它们的存储方式?

我的程序员方面倾向于方式 1,而我的大数据方面则倾向于方式 2。

你会选择哪个?为什么?

4

2 回答 2

2

过早的优化,以及所有这些......

选项 1 可能看起来“更简单”,但您已经确定了主要的缺点 - 可扩展性是一个巨大的痛苦。

我也真的怀疑它是否会比选项 2 更快 - 数据库几乎是专门为查找相关数据位而设计的,查找 10 条记录而不是 1 条记录几乎肯定不会产生您可以衡量的差异。

“分散”的记录并不重要,数据库使用索引能够非常快速地检索数据,而不管它们的物理位置如何。

当然,这确实取决于使用外键的索引,正如@Barmar 评论的那样。

于 2012-11-01T17:07:34.990 回答
1

如果这些行是分散的,它们的访问速度可能会更慢或更快,这取决于它们的存储方式?

如果您正确使用聚类,它们不必分散。

InnoDB 表始终是集群的,如果您的子表的 PK 1看起来类似于:{user_id, tab_id}2,这将自动将属于同一用户的选项卡存储在一起,从而在查询“给定用户的选项卡”期间最小化 I/O。

OTOH,如果您的孩子 PK 是:{tab_id, user_id},这将存储连接到同一选项卡的用户物理上靠近在一起,从而非常快速地进行诸如“给我连接到给定选项卡的所有用户”之类的查询。

不幸的是 MySQL 不支持领先的索引压缩(a-la Oracle),因此您仍然需要为在子表中重复所有这些user_ids(或tab_id第二种情况下的 s)支付存储(和缓存)价格,但是尽管如此,为了灵活性和(可能)易于查询,我仍然会选择解决方案 (2)。


1 InnoDB 自动用作集群键。

2即用户的PK在子表的PK的前沿。

于 2012-11-02T01:04:19.737 回答