我有一张电子邮件表。然后,我有一张桌子,里面有message parts
.
该Parts
表包含一个
field_id, message_id, and data
Run Code Online (Sandbox Code Playgroud)
当时我使用 Parts 来命名表,但使用 field_id 作为列。仅供参考
例如,a part_id
of 2 将是消息的主题。我有subject
, date
, htmlbody
, 和 的部分textbody
。由于这种结构,与将所有数据推送到消息表中相比,每封电子邮件(一个用于部分,另一个用于与电子邮件关联的电子邮件地址)大约多 2 个查询。我发现这种结构是最好的,但我开始认为它可能是错误的并且对性能不是最好的。
我的问题是,重组数据库是否符合我的最佳利益?我宁愿不。
我正在考虑将htmlbody
andtextbody
和subject
anddate
移到messages table
. 另一种解决方案是在一个查询中从表中获取所有emails
和它们。我可以在一个查询中获取所有 id,然后为第二个查询执行 IN(ids)。data
Parts
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`user_id` int(10) NOT NULL,
`account_folder_id` int(10) NOT NULL,
`hash` varchar(255) NOT NULL,
`uid` int(10) NOT NULL,
`seen` tinyint(1) NOT NULL,
`flagged` tinyint(1) NOT NULL,
`date_created` int(11) NOT NULL DEFAULT '0',
`last_modified` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `hash` (`hash`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `message_parts_data` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`message_id` int(10) NOT NULL,
`field_id` int(10) NOT NULL,
`data` text NOT NULL,
`date_created` int(11) NOT NULL DEFAULT '0',
`last_modified` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `fields` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `fields` (`id`, `name`) VALUES
(1, 'To'),
(2, 'Subject'),
(3, 'Date'),
(4, 'From'),
(5, 'CC'),
(7, 'ReplyTo'),
(8, 'textHtml'),
(9, 'textPlain'),
(11, 'Forward');
Run Code Online (Sandbox Code Playgroud)
谢谢
小智 1
我无法告诉您数据的最佳结构,因为我不知道您的所有需求,但是,我可以告诉您如何为类似项目构建表,该项目必须在可搜索的格式中存储可扩展数量的电子邮件。形式可能分布也可能不分布。这就是我们所做的:
有一个messages
由唯一主键组成的表message_id
,以及一些用于存储消息本身中未包含的信息(来自 SMTP 信封的数据)的字段,例如日期和时间、发件人、发送服务器、一些性能指标此外,还有一个storage_id
, 来指示哪个存储结构包含部件/附件(通常是文件夹路径,但也可以是基于模式的地址,例如sftp://user@host/path/to/folder
)。
接下来是headers
每行存储一个消息标题行的表。它包含一个唯一header_id
的主键,以及一个message_id
链接回表中记录的(索引)messages
。有一个header_name
字段(已索引),其中包含标题名称(例如:“主题”、“发件人”等),还有一个header_text
字段,其中包含标题文本。还有一个sequence
数字(索引)用于指示标头的顺序。由于我们需要搜索这些标头,我们在header_text
.
然后有一个parts_text
表,仅存储消息的文本部分。该表有一个唯一part_id
的主键、 a message_id
、 asequence
和一些用于存储 mime 类型和部分标记的字段,以及part_body
存储整个文本的字段。该字段是全文索引的,但是从长远来看,我们计划通过 lucene 索引过程运行消息的文本部分,并将结果存储在数据库中,而实际的文本部分作为文件存储在消息的storage_id
.
然后有一个parts_binary
表,它存储与表相同的内容parts_text
,但没有part_body。它作为文件存储在消息的storage_id
. 请注意,sequence
此表中的 会与sequence
表中的穿插parts_text
。
我知道这不是对您问题的直接答案,但这种结构对我们有用,所以也许对您有一些帮助。