首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【赵渝强老师】TiDB表数据与键值对的映射关系

【赵渝强老师】TiDB表数据与键值对的映射关系

原创
作者头像
赵渝强老师
发布2025-08-14 17:23:04
发布2025-08-14 17:23:04
1300
举报
文章被收录于专栏:TiDBTiDB

TiDB实例将表中的每一行数据映射成RocksDB中的键值对,则需要考虑如何构造Key和Value。首先,OLTP场景下有大量针对单行或者多行的增、删、改、查等操作,要求数据库具备快速读取一行数据的能力。因此,对应的Key最好有一个唯一ID(显示或隐式的ID),以方便快速定位。其次,很多OLAP型查询需要进行全表扫描。如果能够将一个表中所有行的Key编码到一个区间内,就可以通过范围查询高效完成全表扫描的任务。

基于上述考虑,TiDB中的表数据与Key-Value的映射关系作了如下设计:

  1. 为了保证同一个表的数据放在一起,方便查找,TiDB会为每个表分配一个表ID,用TableID表示。表ID是一个整数,在整个集群内唯一。
  2. TiDB会为表中每行数据分配一个行ID,用RowID表示。行ID也是一个整数,在表内唯一。对于行ID,TiDB做了一个小优化,如果某个表有整数型的主键,TiDB会使用主键的值当做这一行数据的行ID。

视频讲解如下:

每行数据按照如下规则编码成(Key,Value)键值对:

代码语言:sql
复制
Key:tablePrefix{TableID}_recordPrefixSep{RowID}
Value:[col1,col2,col3,col4]

# 提示:通过查询information_schema.tables可以获取到TableID,例如:
tidb> select tidb_table_id from tables where table_name='DEPT';
+---------------+
| TIDB_TABLE_ID |
+---------------+
|           121 |
+---------------+

对于存在主键或者唯一约束的表,TiDB将会使用主键或者唯一约束条件作为RowID;而对于不存在主键或者唯一约束的表,TiDB将会表自动生成_tidb_rowid。下面是一个简单的示例。

(1)当表有主键的时候是没有这个_tidb_rowid列

代码语言:sql
复制
tidb> create table table1(id int primary key,name char(30));
tidb> insert into table1 values(1,'AAA');
tidb> select _tidb_rowid from table1;
ERROR 1054 (42S22): Unknown column '_tidb_rowid' in 'field list'

(2)当表不存在主键时,TiDB会自动创建_tidb_rowid且该列初始值是1,递增也是1。

代码语言:sql
复制
tidb> create table table2(id int,name char(30));
tidb> insert into table2 values(1,'AAA'),(2,'BBB'),(3,'CCC');
tidb> select _tidb_rowid,id,name from table2;
+-------------+------+------+
| _tidb_rowid | id   | name |
+-------------+------+------+
|           1 |    1 | AAA  |
|           2 |    2 | BBB  |
|           3 |    3 | CCC  |
+-------------+------+------+
3 rows in set (0.020 sec)

下面通过一个简单的例子,来理解TiDB的Key-Value映射关系。假设TiDB中有如下这个表:

代码语言:sql
复制
tidb> create table user (
    id int,
    name varchar(20),
    role varchar(20),
    age int,
    primary key (id),
    key idxage (age)
);

# 假设该表中有3行数据:
1, "TiDB",	"SQL Layer",	10
2, "TiKV",	"KV Engine",	20
3, "PD", 	"Manager",		30

首先每行数据都会映射为一个(Key,Value)键值对,同时该表有一个int类型的主键,所以RowID的值即为该主键的值。假设该表的TableID为10,则其存储在TiKV上的表数据为:

代码语言:sql
复制
t10_r1 --> ["TiDB", "SQL Layer", 10]
t10_r2 --> ["TiKV", "KV Engine", 20]
t10_r3 --> ["PD", "Manager", 30]

除了主键外,该表还有一个非唯一的普通二级索引idxAge,假设这个索引的IndexID为1,则其存储在TiKV上的索引数据为:

代码语言:sql
复制
t10_i1_10_1 --> null
t10_i1_20_2 --> null
t10_i1_30_3 --> null

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档