在 HashData 数据仓库中,创建表时可以选择不同的存储类型。需要清楚什么时候该使用堆存储、什么时候使用追加优化 (AO) 存储、什么时候使用行存储、什么时候使用列存储。对于大型事实表这尤为重要。相比而言,对小的维度表就不那么重要了。选择合适存储模型的常规最佳实践为:
-
对于大型事实分区表,评估并优化不同分区的存储选项。一种存储模型可能满足不了整个分区表的不同分区的应用场景,例如某些分区使用行存储而其他分区使用列存储。
-
使用列存储时,段数据库内每一列对应一个文件。对于有大量列的表,经常访问的数据使用列存储,不常访问的数据使用行存储。
-
在分区级别或者在数据存储级别上设置存储类型。
-
如果集群需要更多空间,或者期望提高 I/O 性能,考虑使用压缩。
堆存储是默认存储模型,也是 PostgreSQL 存储所有数据库表的模型。如果表和分区经常执行 UPDATE、DELETE 操作或者单个 INSERT 操作,则使用堆存储模型。如果需要对表和分区执行并发 UPDATE、DELETE、INSERT 操作,也使用堆存储模型。
如果数据加载后很少更新,之后的插入也是以批处理方式执行,则使用追加优化 (AO) 存储模型。千万不要对 AO 表执行单个 INSERT/UPDATE/DELETE 操作。并发批量 INSERT 操作是可以的,但是不要执行并发批量 UPDATE 或者 DELETE 操作。
AO 表中执行删除和更新操作后行所占空间的重用效率不如堆表,所以这种存储类型不适合频繁更新的表。AO 表主要用于分析型业务中加载后很少更新的大表。
行存储是存储数据库元组的传统方式。一行的所有列在磁盘上连续存储,所以一次 I/O 可以从磁盘上读取整个行。
列存储在磁盘上将同一列的值保存在一块。每一列对应一个单独的文件。如果表是分区表,那么每个分区的每个列对应一个单独的文件。如果列存储表有很多列,而 SQL 查询只访问其中的少量列,那么 I/O 开销与行存储表相比大大降低,因为不需要从磁盘上读取不需要访问的列。
交易型业务中更新和插入频繁,建议使用行存储。如果需要同时访问宽表的很多字段时,建议使用行存储。如果大多数字段会出现在 SELECT 列表中或者 WHERE 子句中,建议使用行存储。对于通用的混合型负载,建议使用行存储。行存储提供了灵活性和性能的最佳组合。
列存储是为读操作而非写操作优化的一种存储方式,不同字段存储在磁盘上的不同位置。对于有很多字段的大型表,如果单个查询只需访问较少字段,那么列存储性能优异。
列存储的另一个好处是相同类型的数据存储在一起比混合类型数据占用的空间少,因而列存储表比行存储表使用的磁盘空间小。列存储的压缩比也高于行存储。
数据仓库的分析型业务中,如果 SELECT 访问少量字段或者在少量字段上执行聚合计算,则建议使用列存储。如果只有单个字段需要频繁更新而不修改其他字段,则建议列存储。从一个宽列存储表中读完整的行比从行存储表中读同一行需要更多时间。特别要注意的是,HashData 数据仓库每个段数据库上每一列都是一个独立的物理文件。