2009-12-20 48 views
0

我试图实现一个系统,通过cron作业(而不是在循环中,而用户正在等待它们完成发送时)计划将大量(或小)人群发送到电子邮件。数据库结构问题...计划发送的电子邮件?

用户可以发送两种类型的电子邮件:向订户表中的每个人发送电子邮件,或者仅向组中的成员发送电子邮件。我想我并不需要将这封电子邮件包含给小组成员,因为他们会将电子邮件发送给小组而不是大(全部用户)小组。

我想弄清楚如何构建我的数据库,所以它是有道理的,但我很难解释它应该如何工作。

你有什么经验可以分享这种东西吗?我应该如何构建数据库以跟踪等待交付的电子邮件?

+0

标题写着“调度”,但我读的是关于支持1+收件人。请记住,电子邮件服务器可以对电子邮件进行排队,并且只能以指定的时间间隔发送。 – 2009-12-20 17:39:41

回答

0

使用联接表将未决电子邮件链接到用户。使用另一个连接表来管理组。当电子邮件发往某个组时,可以使用存储过程来使用组中所有成员的ID填充EmailRecipients表。

表:

PendingEmails 
    ID 
    Subject 
    Body 

EmailRecipients (join table) 
    EmailID 
    UserID 

Users 
    ID 

Groups (join table) 
    GroupID 
    UserID 
3

你想实现什么是您使用的存储层上的基本队列。

User (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    email VARCHAR(125) NOT NULL 
); 

User_Group (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    user_id INTEGER UNSIGNED NOT NULL, 
    group_id INTEGER UNSIGNED NOT NULL 
); 

Group (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(75) NOT NULL, 
    description VARCHAR(255) 
) 

MailingList (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    user_id INTEGER UNSIGNED NOT NULL, 

); 

# mails to be sent out to groups/all 
MailQueue (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    group_id INTEGER UNSIGNED, 
    time_to_send DATETIME DEFAULT CURRENT_TIMESTAMP 
); 

你会排队组电子邮件与有效的UNIX时间戳进入在MailQueue条目。您应该创建一个“全部”组,您将分配每个用户,以便您仍然可以正确使用这些表。你会执行您的Cron查询像这样:

SELECT User.email 
FROM MailQueue 
INNER JOIN User_Group ON (MailQueue.group_id = User_Group.id) 
INNER JOIN User ON (User_Group.user_id = User.id) 
WHERE MailQueue.time_to_send < NOW(); 

你需要确保你删除的结果集你作为你不向其发送重复的电子邮件条目之后他们。如果你想保留日志发送的电子邮件,只需添加另一个TINYINT(1) UNSIGNED字段,表示sent_email = 1并解决您SELECT查询只抢的结果,如果值是0