常用的数据架构
OLAP场景
绝大多数是读请求。
数据以相当大的批次(> 1000 行)更新,而不是单行更新;或者根本没有更新。
已添加到数据库的数据不能修改。
对于读取,从数据库中提取相当多的行,但只提取列的一小部分。
宽表,即每个表包含着大量的列。
查询相对较少(通常每台服务器每秒查询数百次或更少)。
对于简单查询,允许延迟大约 50 毫秒。
列中的数据相对较小:数字和短字符串(例如,每个 URL 60 个字节)。 处理单个查询时需要高吞吐量(每台服务器每秒可达数十亿行)。
事务不是必须的。
对数据一致性要求低。有副本情况下,写入一个即可,后台自动同步。
每个查询有一个大表。除了他以外,其他的都很小。
查询结果明显小于源数据。换句话说,数据经过过滤或聚合,因此结果适合于单个服务器的 RAM 中
行存储与列存储
行存储在数据写入和修改上的优势
行存储的写入是一次完成的,如果这种写入建立在操作系统的文件系统上,可以保证写 入过程的成功或者失败,可以保证数据的完整性。列式存储需要把一行记录拆分成单列保存, 写入次数明显比行存储多(因为磁头调度次数多,而磁头调度是需要时间的,一般在 1ms~10ms),再加上磁头需要在盘片上移动和定位花费的时间,实际消耗更大。 数据修改实际上也是一次写入过程,不同的是,数据修改是对磁盘上的记录做删除标记。 行存储是在指定位置写入一次,列存储是将磁盘定位到多个列上分别写入,这个过程仍是行 存储的列数倍。 所以,行式存储在数据写入和修改上具有很大优势。
列式存储在数据读取和解析、分析数据上具有优势
数据读取时,行存储通常将一行数据完全读出,如果只需要其中几列数据的情况,就会 存在冗余列,出于缩短处理时间的考量,消除冗余列的过程通常是在内存中进行的。列存储 每次读取的数据是集合的一段或者全部,不存在冗余性问题。 列式存储中的每一列数据类型是相同的,不存在二义性问题,例如,某列类型为整型 int,那么它的数据集合一定是整型数据,这种情况使数据解析变得十分容易。相比之下,行存储则要复杂得多,因为在一行记录中保存了多种类型的数据,数据解析需要在多种数据 类型之间频繁转换,这个操作很消耗 CPU,增加了解析的时间。
CK的数据压缩
通过以上案例可以看到,压缩的本质是按照一定步长对数据进行匹配扫描,当发现重复 部分的时候就进行编码转换。例如:(5,3)代表从下划线往前数 5 个字节,会匹配上 3 个 字节长度的重复项,即:“BCD”。当然,真实的压缩算法比以上举例更复杂,但压缩的本 质就是如此,数据中重复性项越多,则压缩率越高,压缩率越高,则数据体量越小,而数据 体量越小,则数据在网络中的传输越快,对网络带宽和磁盘 IO 的压力也就越小。
列式存储中同一个列的数据由于它们拥有相同的数据类型和现实语义,可能具备重复项 的可能性更高,更利于数据的压缩。所以 ClickHouse 在数据压缩上比例很大。