物化视图模式
当数据未针对所需的查询操作进行理想的格式化时,在一个或多个数据存储区中的数据上生成预填充的视图。这可以帮助高效的查询和数据提取,并提高应用程序的性能。
背景和问题
在存储数据时,开发人员和数据管理员的优先级往往集中在如何存储数据,而不是如何读取数据。所选择的存储格式通常与数据格式,管理数据大小和数据完整性的要求以及使用中的存储类型密切相关。例如,使用NoSQL文档存储时,数据通常表示为一系列聚合,每个聚合包含该实体的所有信息。
但是,这可能会对查询产生负面影响。 当查询只需要来自某些实体的数据的一个子集,例如几个客户的订单摘要而不是所有的订单细节时,它就必须提取相关实体的所有数据以获得所需的信息。
解决方案
为了支持高效的查询,一个通用的解决方案是事先生成一个视图,以适合所需结果集的格式实现数据。物化视图模式描述了在源数据不适于合适格式的查询,或者由于数据或数据存储的性质而导致查询性能差的情况下,生成数据的预先填充的视图。
这些仅包含查询所需数据的物化视图允许应用程序快速获取所需的信息。除了连接表或组合数据实体之外,物化视图还可以包括计算列或数据项的当前值,组合值或对数据项执行转换的结果以及作为查询一部分指定的值。物化视图甚至可以针对单个查询进行优化。
关键点是,物化视图及其包含的数据是完全一次性的,因为它可以完全从源数据存储重建。物化视图永远不会被应用程序直接更新,所以它是一个专门的缓存。
当视图的源数据更改时,必须更新视图以包含新信息。可以设置为自动更新,或者在系统检测到对原始数据的更改更新。在某些情况下,可能需要手动重新生成视图。下图是如何使用物化视图模式的例子。
问题和注意事项
在决定如何实现这种模式时,请考虑以下几点:
如何以及何时更新视图。理想情况下,它将会响应于指示源数据更改的事件而重新生成,但是如果源数据快速更改,这可能会导致过多的开销。或者,考虑使用计划任务,外部触发器或手动操作来重新生成视图。
在某些系统中,例如当使用事件源模式来维护只修改数据的事件时,物化视图是必需的。通过检查所有事件来确定当前状态来预先填充视图可能是从事件存储库获取信息的唯一方法。如果不使用事件溯源,则需要考虑物化视图是否有用。物化视图往往是专门为一个或少量的查询定制的。如果使用了许多查询,物化视图会导致不可接受的存储容量要求和存储成本。
考虑生成视图时的数据一致性以及更新视图(如果按计划进行)时对数据一致性的影响。如果源数据在生成视图时发生变化,则视图中的数据副本将不会与原始数据完全一致。
考虑将在哪里存储视图。该视图不必与原始数据位于同一存储或分区中。它可以是几个不同分区组合的子集。
视图如果丢失可以重建。因此,如果视图是暂时的,并且仅用于通过反映数据的当前状态来提高查询性能,或者为了提高可伸缩性,则可以将其存储在缓存中或不太可靠的位置。
在定义物化视图时,根据现有数据项的计算或转换,查询中传递的值或适当时组合这些值,通过向其添加数据项或列来最大化其值。
在存储机制支持的情况下,考虑索引物化视图以进一步提高性能。大多数关系数据库都支持索引视图,而基于Apache Hadoop的大数据解决方案也是如此。
何时使用该模式
这种模式在以下情况下很有用
- 对难以直接查询的数据创建物化视图,或者非常复杂的查询才能提取的,以规范化,半结构化或非结构化方式存储的数据。
- 创建可显著提高查询性能的临时视图,或者可以直接作为UI的源视图或数据传输对象,用于报告或展示。
- 在数据存储连接不总是可用时,支持偶尔连接或断开连接的情况。在这种情况下,视图可以缓存在本地。
- 不需要知道源数据格式的方式简化查询和公开数据以进行实验。例如,通过在一个或多个数据库中加入不同的表,或在NoSQL存储中加入一个或多个域,然后格式化数据以适应其最终用途。
- 为了安全或隐私的原因,提供访问源数据的特定子集的访问权限通常不应该是可访问的,可以修改或者完全暴露给用户。
- 连接不同的数据存储,以利用其单独功能。例如,使用写入高效的云存储作为参考数据存储,以及提供良好查询和读取性能来保存物化视图的关系数据库。
该模式不适于以下情况:
- 源数据简单易于查询。
- 源数据变化非常快,或者可以在不使用视图的情况下访问。在这些情况下,应该避免创建视图的处理开销。
- 一致性是重中之重。这些视图可能并不总是与原始数据完全一致。
案例
下图显示了使用物化视图模式生成销售摘要。将Azure存储帐户中单独分区中的Order
,OrderItem
和Customer
表中的数据组合在一起生成一个视图,其中包含Electronics
类别中每个产品的总销售额以及购买的每一个项目的用户的数量。
创建这个物化视图需要复杂的查询。 但是,通过将查询结果公开为物化视图,用户可以轻松获得结果并直接使用,或将它们合并到另一个查询中。该视图很可能会在报告系统或仪表板中使用,并且可以按计划进行更新,例如每周更新一次。
尽管例子中使用Azure表存储,但许多关系数据库管理系统也原生支持物化视图功能。
相关模式和指南
以下模式和指南在实施这种模式时可能是相关的:
- 数据一致性入门。物化视图中的摘要信息必须保留,以便反映基础数据值。随着数据值的变化,实时更新汇总数据可能不太实际,相反,不得不采取最终一致的方法。该文章总结围绕分布式数据保持一致性的问题,并介绍了不同一致性模型的优点和折衷。
- 命令和查询责任分离(CQRS)模式。用于通过响应基础数据值更改时发生的事件来更新物化视图中的信息。
- 事件溯源模式。与CQRS模式结合使用以维护物化视图中的信息。当物化视图所基于的数据值发生更改时,系统可以引发描述这些更改的事件并将其保存在事件存储中。
- 索引表模式。物化视图中的数据通常由主键组织,但查询可能需要通过检查其它字段中的数据来从该视图中检索信息。该模式用于为不支持本机二级索引的数据存储的数据集创建二级索引。