拥有数十亿条记录的多对多 table 会导致性能问题吗?

Will a many-to-many table with billions of records cause performance issue?

我正在构建一个包含 3 tables 的数据库。

  1. 用户 table、(ID、用户名)
  2. 产品table,(ID,产品名称)
  3. 评分table,(ID、UserID、ProductID、评分)

我的潜力将有近1亿用户和5000种产品。虽然不是每个用户都对每个产品进行评分,但假设我的评分 table 将有数十亿条记录仍然是合理的。我对数据库的了解仅限于 SQL 查询,所以我想知道当我希望 select 一个特定用户的所有评分时它会变得超级慢。

谢谢

更新:关于评级 table,如果我将 UserIDProductID 作为主键,是否有必要或有任何好处保留 ID 列?在建模方面,我一次只使用一个用户的评分,即 select 所有评分都属于用户 1,在这些记录上做一些事情,select 用户 2 评分,在这些记录上做一些事情,等等等等。在方便和效率方面,还有比多对多更好的数据库结构吗table?

更新2:

| time_spent | CREATE TABLE `time_spent` (
  `product_id` mediumint(9) NOT NULL,
  `user_id` bigint(20) unsigned NOT NULL,
  `minutes_spent` int(10) unsigned NOT NULL,
  PRIMARY KEY (`user_id`,`product_id`),
  KEY `index_product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

其中product_id是6位数字,但以后可能会更长; user_id 是 17 位数字。

上面描述的数据库模式很好。只需确保在(UserID 和 ProductID)上添加复合索引即可。关于性能,由于您提到的数十亿条记录并且考虑到数据库的规模很大,因此可能会造成很小的影响。但是你不能做太多,只是加强数据库机器。

我不会考虑从评分中删除 id table。我知道它没有任何直接目的。但我看到的是,当您最终编写复杂的查询和连接时,ID table 非常有用(让事情变得更简单)。

去掉 many:many 上的 ID table;你有一个 'natural' PRIMARY KEY(UserID, ProductID)。使用 InnoDB 以便 Rating 将与 PK 聚类,因此 'covering'。所以你不需要 Gordon 建议的 3 列索引。

你需要走另一条路吗?如果是这样,则会指示 INDEX(ProductID, UserID, Rating),这样您也可以通过这种方式获得 'covering' 索引。

7 tips on many:many tables.

附录

如果您 SELECT 一个用户的(最多)5000 行,并且您有 PRIMARY KEY(UserId, ProductID) 和 InnoDB,所有这些行将在几十个块中。因此,即使使用冷缓存,我们也谈论不到一秒钟。如果您需要 UPDATE 所有 5000 行,那么您正在触及辅助键(如果它存在)并且这是 5000 次磁盘命中的顺序——很多开销,尽管 InnoDB 的 'Change buffer' 交易以延迟的方式使用它。

因此,如果您不需要从 Prod 转到 User(例如查找产品的所有评级),请不要使用二级索引。