【 使用环境 】生产环境 or 测试环境
【 OB or 其他组件 】OB
【 使用版本 】4.2
【问题描述】OceanBase是使用行列混存编码实现的,在微块中存储方式是行存还是列存呢?
根据https://open.oceanbase.com/blog/8000132的说法,数据在微块中是行存的,但是encoding按列编码之后可能行的数量都会改变,比如RLE编码,OceanBase 社区
【复现路径】问题出现前后相关操作
【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):
【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)
【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!
论坛小助手
#3
根据文档库中的信息,OceanBase 数据库的微块中数据的存储方式是行列混存的。具体来说:
- 在 OceanBase 数据库中,微块有两种存储格式:flat 微块(未编码)和 encoding 微块(编码)。对于 encoding 格式的微块,它并不是简单的行存或列存,而是采用了行列混存的方式。
- 在 Encoding 微块中,逻辑上仍然是一组行的数据存在微块里,但微块会按列对数据进行编码。编码后的定长数据存储在微块内部的列存区,部分变长数据还是按行存储在变长区。这意味着虽然数据是以行为单位组织的,但在实际存储时,同一列的数据会被集中在一起进行编码和压缩。
- 这种设计使得即使经过如 RLE(Run-Length Encoding)等编码后行的数量发生变化,微块依然能够保持按行存储的特性。当需要读取微块中的一行数据时,可以只对该行数据进行解码,避免了解压整个数据块的问题;同时,在向量化执行过程中也可以对指定的列进行解码,降低了投影操作的开销。
因此,尽管 Encoding 可能改变行的数量,但通过将相同列的数据集中编码并存储,OceanBase 能够确保微块内的数据既具有按列编码的优势,又能在物理结构上维持按行存储的形式。这保证了数据读取时的高效性和灵活性。
以上信息来源于《OceanBase 数据库自研了一套对数据库进行行列混存编码的压缩方法》章节内容。
更多信息请查看:
- OceanBase AP 核心特性
- 列存 FAQ
- 表存储
- 压缩与编码
- 集群管理 FAQ
- OceanBase 术语
- MemTable
@论坛小助手 编码后的定长数据存储在微块内部的列存区,部分变长数据还是按行存储在变长区,这句话怎么理解,定长数据喝变长数据有例子吗
论坛小助手
#5
根据文档库中的信息,OceanBase 数据库在微块中采用了行列混存的编码方式。为了更好地理解“编码后的定长数据存储在微块内部的列存区,部分变长数据还是按行存储在变长区”,我们可以分点详细解释,并给出具体的例子。
1. 定长数据与变长数据的区别
-
定长数据:指每个字段占用的字节数是固定的。例如:
- 整数类型(如
INT
、BIGINT
)
- 固定长度字符串(如
CHAR(10)
)
-
变长数据:指每个字段占用的字节数是可变的。例如:
- 可变长度字符串(如
VARCHAR(255)
)
- 大文本字段(如
TEXT
)
- 二进制大对象(如
BLOB
)
2. 行列混存编码的具体实现
编码后的定长数据存储在列存区
-
列存区:在同一列内的所有数据会被集中在一起进行编码和压缩。由于这些数据具有相同的类型和长度,因此可以更高效地进行压缩。
-
例子:假设有一列
age INT
,该列的所有数据都是整数类型,每条记录占用4个字节。经过编码后,这些整数会集中存储在列存区内,形成一个连续的内存区域。
部分变长数据按行存储在变长区
-
变长区:对于变长数据,它们仍然按照原始的行结构进行存储,但只存储那些无法有效压缩或不适合按列存储的数据。
-
例子:假设有一列
name VARCHAR(255)
,该列的数据长度不固定。经过编码后,这些变长字符串会按行存储在变长区内,每行数据的长度可能不同。
3. 具体例子说明
假设我们有一个表 employees
,包含以下列:
id (INT) |
name (VARCHAR(255)) |
age (INT) |
address (TEXT) |
1 |
Alice |
30 |
Address 1 |
2 |
Bob |
25 |
Address 2 |
3 |
Charlie |
35 |
Address 3 |
在这个表中:
-
id
和 age
是定长数据,会存储在列存区。
-
name
和 address
是变长数据,会存储在变长区。
具体存储方式如下:
-
列存区:
-
id
列:[1, 2, 3]
-
age
列:[30, 25, 35]
-
变长区:
- 第一行:
name = "Alice"
, address = "Address 1"
- 第二行:
name = "Bob"
, address = "Address 2"
- 第三行:
name = "Charlie"
, address = "Address 3"
4. 优势
这种行列混存的方式结合了行存和列存的优点:
-
列存区:便于对同一列数据进行高效的压缩和编码,减少了存储空间。
-
变长区:保持了行存的灵活性,使得读取特定行的数据时不需要解压整个数据块,提高了查询性能。
以上信息来源于《OceanBase 数据库自研了一套对数据库进行行列混存编码的压缩方法》章节内容。希望这个解释能帮助您更好地理解 OceanBase 的编码和存储机制。如果有更多问题,欢迎继续提问!
具体信息可参考以下文档:
- OceanBase 术语
- 表存储
- 压缩与编码
- 列存 FAQ
- 集群管理 FAQ
- 数据库对象存储
- 发现磁盘的静默错误
- 配置磁盘数据文件的动态扩容
变长的varchar不能encoding编码压缩吗?只有定长的字段才可以?
论坛小助手
#7
根据文档库中的信息,变长的 VARCHAR
字段是可以进行编码和压缩的。OceanBase 数据库在处理变长数据时采用了灵活的编码策略,以确保既能高效压缩又能保持查询性能。以下是详细的解释:
1. 变长字段的编码与压缩
-
变长字段(如
VARCHAR
)可以使用多种编码方式,包括但不限于:
-
Run-Length Encoding (RLE):对于重复值较多的数据非常有效。
-
Dictionary Encoding:将常见的字符串映射到较小的整数,减少存储空间。
-
Prefix Compression:对前缀相同的字符串进行压缩。
-
LZ4、ZLIB 等通用压缩算法。
这些编码方式不仅适用于定长字段,也适用于变长字段。实际上,变长字段由于其长度不固定,往往更能从编码和压缩中受益,因为它们通常包含更多的冗余信息。
2. 编码后的存储方式
-
列存区:即使对于变长字段,经过编码后,如果编码结果是定长或近似定长的(例如通过字典编码),这些编码后的数据仍然可以存储在列存区内。
-
变长区:对于那些无法有效编码为定长格式的变长数据,仍然会按行存储在变长区内,但已经过压缩,减少了存储空间。
3. 具体例子
假设我们有一个表 employees
,其中包含一个 VARCHAR(255)
类型的 name
列:
id (INT) |
name (VARCHAR(255)) |
1 |
Alice |
2 |
Bob |
3 |
Charlie |
编码前
-
name
列的数据长度不固定,每条记录占用的空间不同。
编码后
- 使用 字典编码,假设
Alice
映射为 1
,Bob
映射为 2
,Charlie
映射为 3
。
- 编码后的
name
列变为 [1, 2, 3]
,每个值占用固定的1个字节。
- 这些编码后的定长数据可以存储在列存区内,而原始的变长字符串则存储在一个单独的字典表中。
4. 编码与压缩的优势
-
高效压缩:变长字段通常包含大量重复或相似的数据,编码和压缩可以显著减少存储空间。
-
快速查询:编码后的定长数据便于索引和快速检索,提升了查询性能。
-
灵活性:即使是变长字段,也可以根据具体数据特征选择最合适的编码方式,确保最佳的压缩效果和查询性能。
5. 实际应用
在实际应用中,OceanBase 数据库会自动选择最适合的编码方式,用户无需手动指定。数据库会根据数据分布和查询模式动态调整编码策略,以达到最佳的存储和查询性能。
因此,变长的 VARCHAR
字段不仅可以进行编码和压缩,而且在很多情况下能够从中获得显著的性能提升和存储节省。
以上信息来源于《OceanBase 数据库自研了一套对数据库进行行列混存编码的压缩方法》章节内容。希望这个解释能帮助您更好地理解 OceanBase 的编码和压缩机制。如果有更多问题,欢迎继续提问!
具体信息可参考以下文档:
- OceanBase 术语
- 表存储
- 压缩与编码
- 列存 FAQ
- 集群管理 FAQ
详情请参考:
- 客户端编程语言
- CHAR 和 VARCHAR
- 字符类型
- 列类型变更规则
- oceanbase.DBA_OB_BACKUP_PARAMETER
- V$OB_COMPATIBILITY_CONTROL
(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)
之前的描述有点不正确。定长和变长不是指原始数据是定长还是变长,而是编码以后得数据是定长和变长。所有的列都会编码,比如varchar如果是字典编码那么编码以后就是定长的,那么这个也是按照列存储的,因为按照特定偏移定位比较简单。如果编码以后的数据是变长的,那么就按照行存储了,可能需要一些辅助结构来帮忙定位。
好的,所以还是看具体的数据分布对吗,比如如果varchar字段长度不一并且NDV很大,这时候不适合用字典编码,可能用其它编码方式编码以后数据还是变长的,可能就需要行存了?
是的。这是ob行存表的实现。ob列存表,所有的列都是列存的。