我建立一个包含3个表的数据库。
我有潜力将拥有近1亿用户和5000个产品。虽然不是每个用户都对每个产品进行评级,但我认为我的评级表将拥有数十亿条记录仍然是合理的。我对数据库的了解仅限于SQL查询,所以当我想选择一个特定用户的所有评级时,我想知道它会变得超级慢。
由于
更新:关于评分表,如果我将UserID
和ProductID
作为主键,是否有必要或保留ID列?在建模方面,我一次只使用一个用户的评级,即选择所有评级属于user1,对这些记录进行操作,选择user2评级,对这些记录进行操作,等等等等。在方便性和效率方面,还有比多对多表更好的数据库结构?
UPDATE2:
| 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位。
答案 0 :(得分:3)
在许多:多桌上摆脱ID
;你有一个自然的' PRIMARY KEY(UserID, ProductID)
。使用InnoDB使Rating
与PK聚类,从而覆盖'。因此,您不需要戈登建议的3列索引。
你需要走另一条路吗?如果是,则会显示INDEX(ProductID, UserID, Rating)
,以便您可以覆盖'索引那样。
<强>附加物强>
如果你为一个用户SELECT
(最多)5000行,并且你有PRIMARY KEY(UserId, ProductID)
和InnoDB,那么所有这些行都将在几十个块中。因此,即使使用冷缓存,我们谈论的还不到一秒钟。如果您需要UPDATE
所有5000行,那么您正在触摸辅助键(如果它存在)并且大约有5000个磁盘命中 - 大量开销,尽管InnoDB&#39; s&# 39;改变缓冲区&#39;以延迟的方式处理它。
因此,如果您不需要从Prod转到用户(例如查找产品的所有评级),请不要使用二级索引。
答案 1 :(得分:0)
上面描述的数据库模式很好用。只需确保在(UserID和ProductID)上添加复合索引即可。关于性能,由于您提到的数十亿条记录并且考虑到数据库具有相当大的规模,因此可能会受到轻微打击。但是你不能做太多,只是加强数据库机器。
我不会考虑从评级表中删除id。我知道它没有任何直接目的。但是我所看到的是当你最终编写复杂的查询和连接时,ID表非常有用(使事情变得更简单)。