Вопрос о структуре базы данных ... Письма запланированы для доставки? - PullRequest
0 голосов
/ 20 декабря 2009

Я пытаюсь внедрить систему, в которой электронная почта для больших (или небольших) групп людей должна доставляться заданием cron (а не в цикле, пока пользователь ожидает, пока они закончат отправку).

Существует два типа электронных писем, которые пользователь может отправить: электронное письмо всем в таблице подписчиков или электронное письмо только членам группы. Я полагаю, что мне не нужно включать электронное письмо членам группы, так как это будут электронные письма для небольших групп, а не для большой группы (все подписчики).

Я пытаюсь понять, как структурировать мою базу данных, чтобы она имела смысл, но мне трудно даже объяснить, как она должна работать.

Есть ли у вас какой-либо опыт с такими вещами, которыми вы можете поделиться? Как мне структурировать базу данных, чтобы отслеживать электронные письма, ожидающие доставки?

Ответы [ 2 ]

3 голосов
/ 20 декабря 2009

То, что вы хотите реализовать, - это базовая очередь, использующая ваш уровень хранения.

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
);

Вы бы ставили в очередь групповые электронные письма, вводя записи в MailQueue с действительной меткой времени Unix. Вы должны создать группу «Все», к которой вы будете назначать каждого пользователя, чтобы вы все еще могли правильно использовать таблицы. Вы бы запустили свой запрос 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.

0 голосов
/ 20 декабря 2009

Используйте таблицу соединений, чтобы связать ожидающие электронные письма с пользователями. Используйте другую таблицу соединений для управления группами. Когда электронное письмо предназначено для группы, можно использовать хранимую процедуру для заполнения таблицы EmailRecipients идентификаторами всех членов группы.

Таблица:

PendingEmails
  ID
  Subject
  Body

EmailRecipients (join table)
  EmailID
  UserID

Users
  ID

Groups  (join table)
  GroupID
  UserID
...