【问题标题】:What is the best way to search multiple columns of a database for user/client inputted information? [closed]在数据库的多个列中搜索用户/客户输入信息的最佳方法是什么? [关闭]
【发布时间】:2020-12-08 05:19:23
【问题描述】:

我有以下格式的数据:

+---------+---------+----------+-----------+-----------+-----------+
|    id   |  title  |  author  | keyword_1 | keyword_2 | keyword_3 |     
+---------+---------+----------+-----------+-----------+-----------+

我希望将其存储在数据库中,以便通过titlekeyword_1keyword_2keyword_3 进行搜索。
一个例子是

+---------+------------------+-----------+-------------+-------------+-----------+
|    id   |  title           | author    |   keyword_1 | keyword_2   | keyword_3 |     
+---------+------------------+-----------+-------------+-------------+-----------+
|    123  |  Learn Java 101  | John Doe  |   java      | programming | software  |     
+---------+------------------+-----------+-------------+-------------+-----------+

在前端,有一个表单,用户可以在其中输入标题和/或关键字。需要查询数据库以获取此信息。但用户输入可能不会完全匹配,因此我们需要进行某种正则表达式或模糊匹配。用户有效载荷可能会输入如下内容:

{
    title: "Learn Java",
    author: "Jon Doee",
    keyword1: "computers",
    keyword2: "softwar",
    keyword3: null,

}

我知道有一些内置操作,例如,在 Postgres 中我们有 LIKELevenshtein()。但是,我不确定这是否是正确的方法。将关键字与所有三列进行比较似乎是一项非常昂贵的操作。

当然必须有一个干净的方法来做到这一点。我在这里发帖是因为我想检查这是否是我应该走的路。

从架构的角度来看,这是存储数据的正确方法吗?我考虑过使用基于文档的系统,但我不确定这会更好或更糟。

我对这一切有些陌生,希望能就推荐的内容提供一些指导。 谢谢!

【问题讨论】:

    标签: sql database-design architecture full-text-search fuzzy-search


    【解决方案1】:

    我将从规范化的关系模型开始:

    书籍:

    |    id   |  title           | author    | 
    |    123  |  Learn Java 101  | John Doe  |
    

    然后:

    书籍关键词

    |    book_id   |  Keyword     |
    |    123       |  java        |
    |    123       |  programming |
    |    123       |  software    |
    

    此数据模型的一个特别有价值的功能是您可以拥有一个Keywords 表并验证只有有效的关键字才能进入此表。

    这是为每个实体存储多个值的“正常”方式。

    掌握了这一点后,您可以考虑替代结构。例如:

    • 将关键字存储为文本字段并使用文本搜索可以很好地在某些情况下
    • 将关键字存储为数组可以很好地在某些情况下
    • 在 JSON 中存储关键字可以很好地在某些情况下

    但首先要了解 SQL 语言旨在支持的内容——表中的单独实体。

    【讨论】:

    • 这是有道理的。我看到一个小问题,我想不出一个明确的解决方法。那么,我将如何查询book_id where keyword="java" and keyword="programming" 等。似乎它默认为OR 语句,因为所有关键字都在不同的行上
    • @JacFrall 。 . .它默认为or。您需要使用两个比较 (where exists (. . . = 'java') and exists (. . . = 'programming')) 或聚合。
    【解决方案2】:

    当您使用 RDBMS 并且清楚地知道要存储什么信息时,为什么更喜欢存储在文档中。 在 RDBMS 中,当信息不是关系或目的只是存储和检索并且修改最少时,通常使用 json、xml 等数据类型。 查看您的表格,在处理大量数据时,与文档方法相比,关系方法总是会给您更快的结果。

    是的,类似操作有点昂贵,替代方法是 REGEXP 或 SIMILAR TO(对于 Postgres)。你应该知道在哪里使用什么。您始终可以在要在 where 子句中使用的列上创建模式匹配索引。存储超过 2 个单词的列的 GIN/GIST 索引。例如:标题

    如果有持续的更新或删除,考虑通过设置正确的vacuum参数、分析表、索引重建/重新创建对表进行维护操作。

    如果要存储数百万条记录,请使用表分区。

    您的要求相当不错,我认为这里不需要存储在文档中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 2019-01-24
      • 2013-02-28
      • 2010-09-14
      • 2013-02-03
      • 1970-01-01
      相关资源
      最近更新 更多