设计一个存储5亿域名全文检索的数据库

Designing a database for storing 500 million domain names with full text search

我即将构建一个可存储多达 5 亿条域名记录的应用程序。 我将索引 '.net' 或 '.com' 部分并在开头去除 'www' 。 所以我相信 table 看起来像这样:

domain_id | domain_name  | domain_ext
----------+--------------+-----------
1         | dropbox      | 2
2         | digitalocean | 2

domain_ext = 2 表示它是一个“.com”域。

我将要执行的查询:

  1. 我需要能够轻松插入新域。
  2. 我还需要确保我没有插入重复项(每个域应该只有 1 条记录),所以我想将 domain_name + domain_ext 作为 UNIQUE 索引(使用 MySQL - InnoDB ).
  3. 批量查询域名。例如:SELECT * FROM tbl_domains LIMIT 300000, 600;

你怎么看? table 会保存数亿条记录吗? 按域名首字母分区好不好? 让我知道你的建议,我是开放的。

  • 分区不太可能提供任何好处。当然,如果你在第一个字母上进行分区。

  • 不要使用 OFFSETLIMIT 进行批处理。相反 "remember where you left off"。有关详细信息,请参阅 my blog

  • 如果你把domain_ext声明为INT,那我问为什么? INT 占用 4 个字节。 .com 也是如此。就算你反SMALLINT.uk,我也会反"The small difference does not justify the complexity."

编辑(在 UNIQUE 上)

非分区 table 可以有一个 UNIQUE 索引。 (注意:PRIMARY KEY 一个 UNIQUE 索引。)当你有一个 UNIQUE 索引时,检查唯一性几乎是即时的,即使是 500M行。 (向下钻取大约 5 层 BTree 非常 快。)

对于 PARTITIONing,每个 UNIQUE 键必须包含 "partition key"。如果域拆分,则不能使用PARTITION BY RANGE。将扩展名(顶级域)拆分为 INT,您可以使用 BY RANGEBY LISTUNIQUE 是可能的,因为 TLD 既是分区键又是域的一部分。但它不会获得任何性能。查找将 (1) 选择分区 ("partition pruning"),然后 (2) 深入 BTree 的 4-5 层以到达要检查的行。

结论:虽然在这种情况下可以进行唯一性检查,但 PARTITIONing 不会更快。