1. 问题:关系数据库的限制

⚠️ 效率低下

带通配符的标准 LIKE 查询(例如 %laptop%)会触发全表扫描,这使得它们的计算成本很高,并且随着数据集扩展到数百万条记录而变得越来越慢。

⚠️缺乏相关性

传统的 SQL 查询返回匹配没有排名或相关性评分。这意味着结果没有优先顺序,例如,一本“关于”机器学习的书与仅简要提及它的书被视为相同。

⚠️ 可扩展性问题

随着系统扩展(例如,亚马逊或谷歌等平台),需要亚毫秒级搜索延迟。传统的关系数据库很难有效地满足这些性能需求。

用于搜索的关系数据库的其他限制

⚠️ 全文搜索支持不佳

关系数据库并非专为高级全文搜索功能而设计,例如:

  • 代币化
  • 词干提取(例如,“运行”→“运行”)
  • 同义词处理
    与专用搜索引擎相比,这使得搜索不太智能。

⚠️没有内置排名算法

没有对相关性评分算法(例如 TF-IDFBM25)的本机支持,而这些算法对于对搜索结果进行有意义的排名至关重要。

⚠️ 难以处理拼写错误和模糊搜索

关系数据库面临以下问题:

  • 拼写错误(例如,“laptpo”而不是“laptop”)
  • 近似匹配
    实现模糊搜索既复杂又低效。

⚠️ 有限的水平可扩展性

扩展关系数据库通常意味着垂直扩展(为一台机器添加更多功能),而现代搜索系统需要水平扩展(分布式系统)。

⚠️ 复杂查询的高延迟

结合过滤器+排序+文本搜索会导致:

  • 查询执行速度慢
  • 增加数据库负载

⚠️ 未针对读取繁重的工作负载进行优化

搜索系统读取繁重,但关系数据库针对**事务工作负载(CRUD)**进行优化,而不是针对高速搜索查询。

⚠️ 索引限制

虽然存在索引(B 树等),但它们并未针对以下方面进行优化:

  • 全文搜索
  • 倒排索引(用于搜索引擎)

⚠️ 实时搜索挑战

与 Elasticsearch 等系统相比,更新索引并在搜索结果中立即反映变化更加困难。


2. 解决方案:倒排索引 (8:48 - 16:12)

概念

该系统不是为每个搜索查询扫描整个文档,而是使用倒排索引 - 一种专门的数据结构,将每个术语(单词)映射到它出现的文档列表。

👉 将其视为书籍索引:

  • 不必阅读整本书来查找单词
  • 直接在索引中查找单词并跳转到页面

传统方法(效率低下)

扫描每个文档 → 检查它是否包含“laptop

####倒排索引方法(高效)
“笔记本电脑”→ [doc1、doc7、doc21、doc105]

因此,系统不会搜索所有文档,而是直接检索相关文档。


内部如何运作

  1. 代币化

    • 文本被分解为单独的术语(标记)
    • 示例:"Gaming Laptop under 50k"["gaming", "laptop", "under", "50k"]
  2. 标准化

    • 转换为小写,删除标点符号等。
    • "Laptop""laptop"
  3. 索引创建

    • 每个令牌都存储有文档 ID 列表
      笔记本电脑 → [doc1、doc3、doc10]
      游戏 → [doc1, doc8]
  4. 搜索

  • 查询也被标记化
  • 立即从索引中获取匹配的文档

🚀 为什么它如此强大

  • 极速搜索
    无需全表扫描——直接查找

  • 大规模高效
    即使处理数百万/数十亿的文档也能正常工作

  • 支持高级功能

  • 全文搜索

  • 排名(TF-IDF、BM25)

  • 模糊搜索(拼写错误)

  • 短语匹配


⚙️技术

Elasticsearch 使用 Apache Lucene 作为其核心引擎。

  • Apache Lucene 处理:

  • 倒排索引创建

  • 查询处理

  • 排名和评分

  • Elasticsearch 添加:

  • REST API

  • 分布式架构

  • 横向可扩展性


🆚 与关系型数据库的比较

特色 关系数据库 (LIKE) 倒排索引
搜索方法 全面扫描 直接查找
速度 快⚡
相关性排名 ❌ 否 ✅ 是的
可扩展性 有限公司 高🚀

3. 搜索智能 (16:12 - 22:05)

现代搜索引擎不仅仅是寻找匹配,它们还专注于提供最相关的结果。这是通过先进的排名算法和智能查询处理来实现的。


🧠 相关性评分(BM25 算法)

Elasticsearch 等搜索引擎使用 BM25(最佳匹配 25) 算法根据文档与查询的相关程度对文档进行排名。

BM25 没有平等对待所有匹配项,而是使用多个因素为每个文档分配 分数

📌 1. 词频 (TF)

  • 测量搜索词在文档中出现的频率
  • 更高的频率→更高的相关性

👉 示例:

  • 文档 A:“笔记本电脑笔记本电脑”→ 更相关
  • Doc B:“笔记本电脑”(仅一次)→ 不太相关

📌 2. 文档频率 (DF)

  • 衡量某个术语在所有文档中的常见程度
  • 稀有术语比常见术语更有价值

👉 示例:

  • “笔记本电脑”(常用词)→ 影响较小
  • “ultrabook”(罕见词)→ 更高的影响力

这有助于系统避免高估通用词。


📌 3. 场增强

  • 并非所有领域都同等重要
  • 某些领域的比赛被赋予更高的权重

👉 示例:

  • 匹配标题 → 非常重要
  • 匹配描述/内容 → 不太重要

标题:“最佳游戏笔记本电脑” ✅ 高优先级
描述:“…包括笔记本电脑…” ❌ 较低优先级


🤖 拼写错误容错和查询智能

现代搜索引擎可以理解用户意图,即使查询不完美。

🔍特点:

  • 模糊搜索(拼写错误处理)
    检测并纠正拼写错误
    “笔记本电脑”→“笔记本电脑”

  • “您是说”建议
    输入错误时建议更正查询

  • 自动完成/建议
    实时预测用户正在输入的内容


🚀 为什么这很重要

  • 用户立即获得准确的结果
  • 显着改善用户体验
  • 对于以下平台至关重要:
  • 电子商务(亚马逊)
  • 搜索引擎(谷歌)
  • 求职门户、博客、SaaS 应用程序

🆚 没有搜索智能

场景 没有BM25 与BM25
关键词精准匹配 同等级 排名
重要字段(标题与正文) 被忽略 优先
罕见词与常见词 相同重量 平衡
打字错误 ❌ 失败 ✅ 已处理

4. 实际基准测试

🧪 测试用例

PostgreSQLElasticsearch 之间的性能比较是使用 50,000 条记录的数据集进行的。

⏱️ 结果:

  • PostgreSQL → ~7.5 秒
  • Elasticsearch → ~500 毫秒

👉 这表明使用 Elasticsearch 等搜索优化引擎时性能大幅提升


为什么有区别?

  • PostgreSQL

    • 使用传统查询(LIKE、连接等)
    • 经常执行完整或部分扫描
    • 未针对大规模全文搜索进行优化
  • 弹性搜索

    • 使用倒排索引
    • 执行直接查找而不是扫描
    • 针对快速、实时搜索查询进行了优化

要点

  • 一、掌握SQL和数据库优化

    • 索引
    • 查询优化
    • 架构设计
  • 然后,在以下情况下使用 Elasticsearch(或类似工具)

    • 您的应用程序搜索量较大
    • 您需要以下功能:
      • 提前输入(自动完成)
      • 全文搜索
      • 高级过滤和排名
      • 实时搜索体验

何时使用什么?

使用案例 PostgreSQL 弹性搜索
CRUD 操作
交易系统
简单搜索
全文检索 ⚠️ 有限公司
高性能搜索
自动完成/建议