数据库重组 - 有益吗?

som*_*ser 6 mysql

我有一张电子邮件表。然后,我有一张桌子,里面有message parts.

Parts表包含一个

   field_id,  message_id, and data 
Run Code Online (Sandbox Code Playgroud)

当时我使用 Parts 来命名表,但使用 field_id 作为列。仅供参考

例如,a part_idof 2 将是消息的主题。我有subject, date, htmlbody, 和 的部分textbody。由于这种结构,与将所有数据推送到消息表中相比,每封电子邮件(一个用于部分,另一个用于与电子邮件关联的电子邮件地址)大约多 2 个查询。我发现这种结构是最好的,但我开始认为它可能是错误的并且对性能不是最好的。

我的问题是,重组数据库是否符合我的最佳利益?我宁愿不。

我正在考虑将htmlbodyandtextbodysubjectanddate移到messages table. 另一种解决方案是在一个查询中从表中获取所有emails和它们。我可以在一个查询中获取所有 id,然后为第二个查询执行 IN(ids)。dataParts

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

我知道这不是对您问题的直接答案,但这种结构对我们有用,所以也许对您有一些帮助。