行式存储
优点
适用于事务处理和随机写入
行式存储将完整的记录按行存储,使得随机写入和事务处理更加高效。当需要频繁进行数据插入、更新和删除操作时,行式存储通常更为合适。
适合OLTP工作负载
OLTP(联机事务处理)工作负载通常需要根据特定的条件查询少量的记录,行式存储在这种场景下查询性能较好。
缺点
查询效率较低
行式存储在进行聚合、分组和跨列查询等操作时效率较低。因为每次查询都需要读取完整的记录,包括不相关的列,造成了额外的IO开销和数据传输。
数据冗余
行式存储方式下,每个记录都包含完整的列数据,可能导致存储冗余。特别是在存在大量重复数据的情况下,行式存储会占用更多的存储空间。
一般的数据存储过程
数据切分
将待存储的数据按照记录(行)进行切分。每个记录通常包含多个列的数据,将这些列数据组合成一条完整的记录。
数据编码
对每个记录进行适当的编码,以便在存储和查询时能够有效地表示和解析数据。编码过程通常包括数据类型转换、序列化等操作。
存储组织
将编码后的记录按照一定的存储结构组织起来,可以是以文件、表或其他数据结构为单位。每个记录通常存储在一个固定大小的数据块或页中,以便在存储和查询时进行高效的读写操作。
元数据管理
维护关于存储的元数据信息,如记录的结构、列的名称和数据类型等。元数据信息可以帮助系统在查询时了解记录的组织方式和数据的含义。
索引管理(可选)
为了提高查询性能,可以建立索引结构来加速特定条件下的记录查找。索引通常包括某个列或多个列的值以及指向对应记录位置的指针。
行式存储的查询逻辑
确定主键:首先确定用于唯一标识记录的主键列。
根据主键查找:使用主键的值,定位到存储中对应的主键索引位置,找到目标记录所在的位置。
获取所有列的值:一旦找到记录的位置,就可以直接获取该记录的所有列的值。因为行式存储将完整的记录按行存储,所以可以一次性获取所有列的值。
使用所需的列数据:从获取到的记录中提取出需要的列数据,根据业务需求进行进一步处理或使用。
列式存储
优点
查询效率高
列式存储将每个列的数据存储在一起,使得针对特定列的查询效率更高。当需要查询特定列或进行聚合、分组操作时,列式存储通常比行式存储更高效。
压缩比较高
由于相邻的列通常具有相似的值,列式存储可以采用更好的压缩算法,从而减少存储空间的占用。
缺点
随机写入性能较差
由于列式存储将每个列的数据分开存储,进行随机写入操作时需要涉及多个列的写入,因此写入性能较差。
适用于批量查询
列式存储在面对大规模数据的批量查询时表现出色,但对于单条记录的查询性能较低。
一般的数据存储过程
数据切分
将待存储的数据按照列进行切分。这意味着将每一列的数据分离出来,形成单独的列数据块。
压缩和编码
对每个列的数据进行压缩和编码。压缩算法可以根据数据的特征选择合适的算法,如字典编码、位图压缩、Run-Length Encoding(RLE)等。压缩和编码的目的是减少存储空间的占用。
存储组织
将压缩和编码后的列数据存储在物理上相邻的位置。相邻的列数据通常存储在同一个列族或数据块中,以便在查询时能够高效地读取相关的列。
元数据管理
维护关于存储的元数据信息,如列的名称、数据类型、压缩算法等。元数据信息可以帮助系统在查询时识别和解码各个列的数据。
列式存储的查询逻辑
确定主键:首先确定用于唯一标识记录的主键列。
根据主键查找:使用主键的值,定位到存储中对应的主键索引位置,找到记录所在的位置。
逐列获取数据:针对每个需要查询的列,根据记录的位置信息,从相应的列数据块或页中读取该列的值。这意味着你需要进行多次查询,每次查询获取一个列的值。
组合列的值:将获取到的多个列的值组合起来,形成完整的记录。
与数据库分类的区别
列式存储和行式存储与关系型数据库和非关系型数据库(NoSQL)有一定的相似性,但并不完全对应。
关系型数据库
通常采用行式存储,将完整的记录按行存储,每个记录包含多个列的数据。关系型数据库使用表来组织数据,每个表由行组成,每行代表一条记录,每列代表记录的一个属性。关系型数据库使用结构化查询语言(SQL)进行数据操作和查询。
非关系型数据库(NoSQL)
非关系型数据库则包括多种不同的数据库类型,其中一些采用列式存储,而其他一些则使用行式存储或其他存储方式。非关系型数据库通常设计用于大规模数据存储和高吞吐量的场景,强调可扩展性和灵活性,不依赖于固定的表结构和关系模型。
列式存储和行式存储
列式存储和行式存储的选择通常取决于特定的应用需求和查询模式。列式存储适合于分析型查询,其中涉及大量列的聚合计算和数据过滤操作。列式存储能够提供更好的查询性能和压缩效果,因为它能够高效地读取和处理特定的列。而行式存储适合于事务处理和快速查询的场景,因为它可以快速地读取和处理整个记录。