问题描述
我目前正在为新应用程序设计数据库。用户可以在应用程序中选择是否要获取有关特定主题的电子邮件。在系统发送电子邮件之前,它必须检查哪个用户订阅了哪个主题。在下面,您可以看到我当前的表架构。
由于您可以在应用程序中预订70多个主题,并且数据库中有很多用户(超过10,000个),因此恐怕“ User_Settings”表可能随着时间的推移而变得太大。
有没有更优雅的解决方案?
单击下面的数字以查看当前表架构或检查下面的代码
让我们假设以下用例:
有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`)
);
解决方法
用户和主题之间的mysql联接表用来表示订阅是一种高效且高效的机制来表示关系。如果您的系统中有成千上万的订阅,则必须某个地方。 Mysql通过简单可靠的一致性机制为您提供了一个真理来源,以表示这种订阅的存在。
在某个时刻,拥有一张庞大的订阅表将成为限制因素。对这些订阅列表进行分区,分片或缓存将是提高此数据可伸缩性的一种逻辑方法。但是,如果建模良好,则订阅关系在很长一段时间内不会成为瓶颈。
请记住,从模板渲染成千上万的电子邮件比仅获取成千上万的预期收件人列表要昂贵得多。为此,发送电子邮件(无论是直接SMTP还是邮件API)将导致足够的延迟,从而导致如果串行执行该过程会相当慢。因此,在这里考虑性能和效率时,请不要过分担心订阅连接表,直到它比电子邮件传递引擎慢为止。