3.4.2.18.Denormalizing / flattening data
创作人:章海怒
审稿人:欧阳楚才
摘要:数据插入的时候,让有关联的数据产生关联,数据扁平化最主要的目的,是提升查询性能。
关键词:非规范化;扁平化
使用 Elasticsearch 得到最好的搜索性能的方法是有目的的通过在索引时进行扁平化denormalizing。对每个文档保持一定数量的冗余副本可以在需要访问时避免进行关联。Elasticsearch中实现扁平化的一个原因是:在 Elasticsearch 中,索引不能与另一个索引 join。因此如果需要使用数据,则必须将其包含在索引中。这样做的好处是提高搜索的速度,但是带来的坏处是如果需要更新其中一个文档,则需要更新当前索引内的所有文档。
Normalization (规范化):规范化是数据库中用于减少表中数据冗余和数据不一致的方法。 这是将非冗余和一致性数据存储在设置的架构中的技术。 通过使用规范化,表的数量增加而不是减少。
Denormalization(非规范化): 反范式化也是数据库中使用的方法。 它用于添加冗余以快速执行查询。 它是一种将数据组合起来以快速执行查询的技术。 通过使用反范式化,减少了表数量。
如果我们希望能够通过某个用户姓名找到他写的博客文章,可以在博客文档中包含这个用户的姓名,而不是通过关联找到这个数据:
PUT /my_index/_doc/1 { "name": "John Smith", "email": "john@smith.com", 794 > 三、产品能力 "dob": "1970/10/24" } PUT /my_index/_doc/2 { "title": "Relationships", "body": "It's complicated...", "user": { "id": 1, "name": "John Smith" //(1) "email": "john@smith.com", "dob": "1970/10/24" } }
这部分用户的字段数据已被冗余到文档中而不需要通过 join 来获取可以直接搜索。
现在,我们通过单次查询就能够通过 relationships 找到用户 John 的博客文章。
GET /my_index/_search { "query": { "bool": { "must": [ { "match": { "title": "relationships" }}, { "match": { "user.name": "John" }} ] } } }
数据扁平化的优点是速度快。因为每个文档都包含了所需的所有信息,当这些信息需要在查询进行匹配时,并不需要进行昂贵的连接操作。
关联关系处理
现实世界有很多重要的关联关系:博客帖子有一些评论,银行账户有多次交易记录,客户有多个银行账户,订单有多个订单明细,文件目录有多个文件和子目录。
关系型数据库被明确设计—毫不意外—用来进行关联关系管理:
l 每个实体(或行,在关系世界中)可以被主键唯一标识。
l 实体规范化。唯一实体的数据只存储一次,而相关实体只存储它的主键。只能在一个具体位置修改这个实体的数据。
l 实体可以进行关联查询,可以跨实体搜索。
l 单个实体的变化是原子的, 一致的 ,隔离的,和持久的。
l 大多数关系数据库支持跨多个实体的 ACID 事务。
但是关系型数据库有其局限性,包括对全文检索有限的支持能力。 实体关联查询时间消耗是很昂贵的,关联的越多,消耗就越昂贵。特别是跨服务器进行实体关联时成本极其昂贵,基本不可用。 但单个的服务器上又存在数据量的限制。
Elasticsearch ,和大多数 NoSQL 数据库类似,是扁平化的。索引是独立文档的集合体。 文档是否匹配搜索请求取决于它是否包含所有的所需信息。
Elasticsearch 中单个文档的数据变更是支持 ACID 事务的,而涉及多个文档的事务则不是。当一个事务部分失败时,无法回滚索引数据到前一个状态。
扁平化有以下优势:
l 索引过程是快速和无锁的。
l 搜索过程是快速和无锁的。
l 因为每个文档相互都是独立的,大规模数据可以在多个节点上进行分布。
但关联关系仍然非常重要。某些时候,我们需要缩小扁平化和现实世界关系模型的差异。以下四种常用的方法,用来在 Elasticsearch 中进行关系型数据的管理:
l 应用端连接
l 非规范化
l 嵌套对象
l 父子关系
通常都需要结合其中的某几个方法来得到最终的解决方案。
数据建模
Elasticsearch 是如此与众不同,特别是如果你来自 SQL 的世界。 Elasticsearch 有非常多的优点:高性能、可扩展、近实时搜索,并支持大数据量的数据分析。一切都很容易! 只需下载并开始使用它。
但它不是魔法。为了充分利用 Elasticsearch,你需要了解它的工作机制,以及如何让它如你所需的进行工作。
和专用的关系型数据存储有所不同,Elasticsearch 并没有对处理实体之间的关系给出直接的方法。一个关系数据库的黄金法则是 --遵从数据库的范式-- 但这不适用于 Elasticsearch。 在关联关系处理、嵌套对象和父子关系我们讨论了这些提供的方法的优点和缺点。
Elasticsearch 提供了快速、灵活的扩容能力。 当然扩容并没有一个放之四海而皆准的方案。你需要考虑这些通过系统产生的数据流的具体特点, 据此设计你的模型。例如日志事件或者社交网络流这些时间序列数据类型,和静态文档集合在处理模型上有着很大的不同。