【问题标题】:Is there a scalable way to implement database search by multiple tags?是否有一种可扩展的方式来通过多个标签实现数据库搜索?
【发布时间】:2017-05-02 22:12:31
【问题描述】:

我有一个 Postgres 数据库和一个用户标签表,其中包含 UserId 和 TagId 列。每个用户可以有多个标签,反之亦然。

有没有办法以可扩展的方式实现多个标签的搜索?示例查询:

  • 获取同时拥有tag1和tag2的所有用户
  • 获取所有拥有(tag1或tag2)和tag3的用户
  • 获取所有有tag1和tag2但没有tag3的用户

由于这不容易索引和扩展,我正在考虑使用某种内存缓存来加快查找速度。你知道这个问题的任何现成的解决方案吗?

谢谢

【问题讨论】:

  • 你有多少个用户和标签? Postgres 应该能够轻松处理这些查询(例如,选择所有带有 tag1 的用户与所有带有 tag2 的用户相交)。如果您在内存中有适当的索引,它会非常快,postgres 确实已经有内存缓存和查询优化。但是,如果这不能很好地为您服务,您可以查看 Solr 或 Elastic。

标签: database database-design tags scalability in-memory-database


【解决方案1】:

首先,在不知道太多细节的情况下,我假设标签有很多但没有那么多,这使得列TagIds的基数较低。我的回答是基于这个假设。

一般来说,低基数列上的索引无助于扩大对该列的查询。更多详情请参考Why low cardinality indexes negatively impact performance

其次,您给出的一组示例查询清楚地给人一种印象,即(该组的)其他查询可以是析取形式(换句话说,WHERE 条件包含 OR 布尔谓词),这暗示没有索引可以挽救析取数很大时的性能。 DBMS 将考虑 (a) 扫描整个表并使用 WHERE 条件测试每一行和 (b) 扫描列 TagIds 上的索引。

最后但并非最不重要的一点是,基于数据现在驻留在内存中的事实,进入内存将为您提供帮助。但是,原则上,内存 DBMS 也会考虑 (a) 和 (b),并且可能会选择 (a) 而不是 (b)。

我建议使用 PostgreSQL 中记录的function index。如果您不处理临时查询,请考虑到这一点:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    相关资源
    最近更新 更多