首页 > 解决方案 > 如何优化设置 MYSQL 表模式的多项选择?

问题描述

我目前正在为我的新应用程序设计数据库。用户可以在应用程序中选择是否要接收有关特定主题的电子邮件。在系统发送邮件之前,它必须检查哪个用户订阅了哪个主题。您可以在下面看到我当前的表架构。

由于您可以在应用程序中订阅超过 70 个主题,并且数据库中有很多用户(超过 10,000 个),我担心“User_Settings”表会随着时间的推移变得太大。

有没有更优雅的解决方案?

单击下面的数字以查看当前的表架构或检查下面的代码

1
2

让我们假设以下用例:

有超过 70 个主题和 10,000 名用户。每个用户默认订阅每个主题。用户偶尔会取消订阅特定主题。



CREATE TABLE `users`
(
 `id`    int unsigned NOT NULL AUTO_INCREMENT ,
 `email` varchar(45) NOT NULL ,

PRIMARY KEY (`id`)
);


CREATE TABLE `Newsletter Settings`
(
 `id`   int unsigned NOT NULL AUTO_INCREMENT ,
 `topic_name` varchar(45) NOT NULL ,

PRIMARY KEY (`id`)
);


CREATE TABLE `user_newsletter_settings`
(
 `id`          int unsigned NOT NULL AUTO_INCREMENT ,
 `settings_id` int unsigned NOT NULL ,
 `user_id`     int unsigned NOT NULL ,
 `status`      tinyint(1) NULL ,

PRIMARY KEY (`id`),
KEY `to_newsletter settings` (`settings_id`),
CONSTRAINT `FK_89` FOREIGN KEY `to_newsletter settings` (`settings_id`) REFERENCES `Newsletter Settings` (`id`),
KEY `to_users` (`user_id`),
CONSTRAINT `FK_95` FOREIGN KEY `to_users` (`user_id`) REFERENCES `users` (`id`)
);

标签: mysqldatabase-design

解决方案


用于表示订阅的用户和主题之间的 mysql 连接表是一种表示关系的高效且高性能的机制。如果您的系统中有数十万或数百万个订阅,他们必须去某个地方。Mysql 用简单可靠的一致性机制为您提供了一个事实来源,以表示此类订阅的存在。

在某些时候,拥有一个巨大的订阅表将成为一个限制因素。对这些订阅列表进行分区、分片或缓存将是提高此数据可伸缩性的一种合乎逻辑的方法。但订阅关系如果建模得当,在很长一段时间内都不会成为瓶颈。

请记住,从模板渲染数千封电子邮件比简单地获取数千个预期收件人的列表要昂贵得多。就此而言,发送电子邮件(无论是直接 SMTP 还是邮件 API)都会产生足够的延迟,如果串行执行,则该过程会非常缓慢。因此,当您在这里考虑性能和效率时,不要过度担心订阅连接表,直到它比电子邮件传递引擎慢。


推荐阅读