问题描述
我的数据格式如下:
+---------+---------+----------+-----------+-----------+-----------+
| id | title | author | keyword_1 | keyword_2 | keyword_3 |
+---------+---------+----------+-----------+-----------+-----------+
我希望将其存储在数据库中,以便可以通过title
,keyword_1
,keyword_2
或keyword_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中,我们有LIKE
和Levenshtein()
。但是,我不确定这是否是正确的方法。将关键字与所有三列进行比较似乎是非常昂贵的操作。
当然必须有一种干净的方法来做到这一点。我在这里发布消息是因为我想检查这是否是我应该走的路。
从架构的角度来看,这是存储数据的正确方法吗?我曾考虑过使用基于文档的系统,但不确定是否会好得多。
我对这一切还是有些陌生,希望对建议的内容提供一些指导。 谢谢!
解决方法
我将从规范化的关系模型开始:
书籍:
| id | title | author |
| 123 | Learn Java 101 | John Doe |
然后:
BookKeywords
| book_id | Keyword |
| 123 | java |
| 123 | programming |
| 123 | software |
此数据模型的一个特别有价值的功能是您可以拥有一个Keywords
表,并验证只有有效的关键字才能进入该表。
这是每个实体存储多个值的“常规”方法。
掌握了这一点之后,您可以考虑其他结构。例如:
- 将关键字存储为文本字段并使用文本搜索在某些情况下可以很好地工作。
- 将关键字存储为数组可以在某些情况下很好地工作 。
- 将关键字存储在JSON中可以在某些情况下很好地工作 。
但是从设计SQL语言所要支持的功能开始-表格中的单独实体。
,在使用RDBMS时,您很清楚将要存储的信息,为什么要优先存储在文档中。 在RDBMS中,通常在信息不相关或目的只是存储和检索且几乎没有修改的情况下使用json,xml等数据类型。 从表的角度来看,在处理海量数据时,与文档方法相比,关系方法将始终为您提供更快的结果。
是的,类似的操作有点贵,而替代的是REGEXP或SIMILAR TO(对于Postgres)。您应该知道在哪里使用什么。您始终可以在将在where子句中使用的列上创建模式匹配索引。存储2个以上单词的列的GIN / GIST索引。例如:标题
如果正在进行连续的更新或删除,请考虑通过设置正确的真空参数,分析表,重建/重新创建索引来对表执行维护操作。
如果要存储数百万条记录,请使用表分区。
您的要求相当不错,我认为这里不需要存储在文档中。