【问题标题】:Designing a database for storing 500 million domain names with full text search设计一个存储5亿个域名的数据库,全文检索
【发布时间】:2015-06-28 08:12:14
【问题描述】:

我即将构建一个存储多达 5 亿条域名记录的应用程序。 我将索引“.net”或“.com”部分并在开头去掉“www”。 所以我相信表格应该是这样的:

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

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

我将要执行的查询::

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

你怎么看?该表会保存数亿条记录吗? 按域名的第一个字母分区怎么样,这样好吗? 让我知道你的建议,我很开放。

【问题讨论】:

  • 您是否考虑过使用更好的数据库来使用“全文搜索”?看看“cassandra db”、“solr”或其他性能良好的数据库,如“orient db”。
  • 就像我说的,我思想开放。经过一番思考,我认为我不需要全文搜索,因为我可以使用 MySQL 的唯一索引。
  • 那么,我推荐你orientdb,因为你每秒可以做很多操作,非常快:orientdb.com
  • 所以 mail.somedomain.com 和 www.somedomain.com 是否满足您的需求?像 co.uk 或 tv 这样的扩展呢?另外,.net 指向与 .com 扩展名相同的网站的地址呢?是否应该将它们视为 2 个不同的域?
  • @ZoharPeled ,我确实关心子域 (mail.somedomain.com)。像 co.uk 这样的扩展名会有不同的 extension_id。哦,而且...我不在乎两个域是否指向同一个网站。

标签: mysql database-design


【解决方案1】:
  • 分区不太可能带来任何好处。当然,如果您是在第一个字母上进行分区。

  • 不要使用 OFFSET 和 LIMIT 进行批处理。而是“记住你离开的地方”。有关详细信息,请参阅my blog。

  • 如果您已将domain_ext 声明为INT,那么我问为什么? INT 占用 4 个字节。 .com 也是如此。即使你用SMALLINT 或.uk 反驳,我也会用“微小的差异不足以证明复杂性”来反驳。

编辑(在 UNIQUE 上)

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

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

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

【讨论】:

  • 感谢@Rick James,好帖子!我会用那个技术。一个问题:我想使用 domain_ext 列,因为它在进行 UNIQUE 检查时缩小了潜在行的数量。我错了吗?你认为让 MySQL 检查所有表而不是一半会更好吗,因为 extension_id 是更快的索引?
  • 没有好处——见编辑。
猜你喜欢
  • 2019-05-10
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多