三篇文章了解 TiDB 技术内幕 - 说计算 | PingCAP
如何将SQL数据映射到KV数据库weixin33804582的博客-CSDN博客
关系模型到 Key-Value 模型的映射
有多种方式可以将关系模型映射到键值存储模型,以下是其中的几种:
- 使用主键作为键:关系模型中每个表格都有一个主键,可以将主键作为键,将包含该行数据的JSON对象作为值存储到键值存储中。
- 使用复合键:如果关系模型中的表格中没有唯一的主键,可以使用多个列组合成一个复合键作为键,将包含该行数据的JSON对象作为值存储到键值存储中。
- 使用索引作为键:在关系模型中,我们通常会创建索引来提高查询性能。可以将索引作为键,将包含该行数据的JSON对象作为值存储到键值存储中。
- 使用冗余数据:在关系模型中,我们可以将某些数据冗余存储以提高查询性能。可以将这些冗余数据作为键,将包含该行数据的JSON对象作为值存储到键值存储中。
以上这些方式各有优缺点,需要根据具体情况选择合适的方式进行映射。需要注意的是,在使用这些方式进行映射时,需要确保数据的一致性和完整性。
关于表的元数据,可以使用一个单独的目录进行保存。
使用主键作为键
在关系型数据库中,每个表格都有一个主键,它可以唯一地标识表格中的每一行数据。在键值存储中,键也可以用作唯一标识符。因此,可以将关系型数据库中的表格映射到键值存储中的键值对。
例如,如果我们有一个名为“users”的表格,其中包含用户的姓名、电子邮件和密码等信息。我们可以将每个用户的姓名作为键,将包含该用户信息的JSON对象作为值,然后将这些键值对存储到键值存储中。
{
"John": {
"email": "john@example.com",
"password": "password123"
},
"Jane": {
"email": "jane@example.com",
"password": "password456"
}
}
这种映射方式的好处是可以在某些情况下提高性能和可伸缩性,因为键值存储通常比关系型数据库更快、更简单。但是需要注意的是,这种映射方式并不适用于所有情况,因为它可能会导致某些查询变得困难或不可能。
使用冗余数据
使用冗余数据是将关系模型映射到键值存储模型的一种方式。在关系模型中,我们通常需要进行多表联接查询才能获取完整的数据。而在键值存储模型中,我们可以将冗余数据存储在键值对中,以便更快地获取完整的数据。
例如,我们有一个名为“users”的表格和一个名为“orders”的表格,其中“orders”表格包含有关用户的订单信息。如果我们想要获取某个用户的所有订单信息,需要进行多表联接查询。但是,如果我们将每个用户的订单信息作为一个数组存储在该用户的JSON对象中,就可以更快地获取完整的数据。
以下是一个示例JSON对象:
{
"id": 1,
"name": "John",
"email": "john@example.com",
"orders": [
{
"id": 1,
"product": "iPhone",
"price": 999
},
{
"id": 2,
"product": "iPad",
"price": 799
}
]
}
在这个示例中,“orders”数组包含了该用户的所有订单信息。当我们需要获取某个用户的所有订单信息时,只需要获取该用户的JSON对象并访问“orders”数组即可,而不需要进行多表联接查询。
需要注意的是,使用冗余数据的方式会增加数据冗余和存储空间的占用,因此需要权衡利弊,并根据具体情况选择是否使用该方式。同时,在使用冗余数据的方式时,需要确保数据的一致性和完整性。
实例
表中的数据和索引是如何映射为 KV
至此我们已经聊完了如何将 Table 映射到 KV 上面,这里再举个简单的例子,便于大家理解,还是以上面的表结构为例。假设表中有 3 行数据:
1, "TiDB", "SQL Layer", 10
2, "TiKV", "KV Engine", 20
3, "PD", "Manager", 30
那么首先每行数据都会映射为一个 Key-Value pair,注意这个表有一个 Int 类型的 Primary Key,所以 RowID 的值即为这个 Primary Key 的值。假设这个表的 Table ID 为 10,其 Row 的数据为:
t10_r1 --> ["TiDB", "SQL Layer", 10]
t10_r2 --> ["TiKV", "KV Engine", 20]
t10_r3 --> ["PD", "Manager", 30]
除了 Primary Key 之外,这个表还有一个 Index,假设这个 Index 的 ID 为 1,则其数据为:
t10_i1_10_1 --> null
t10_i1_20_2 --> null
t10_i1_30_3 --> null
根据索引查询的时候,可以根据表、索引、索引值、找到一些key,然后从key中解析出rowid,再根据表、rowid定位到数据。