分区表
OceanBase 数据库支持普通表和分区表。
在 OceanBase 数据库中,分区是指根据一定的规则,把一个表或者索引分解成多个更小的、更容易管理的部分。每个分区都是一个独立的对象,具有自己的名称和可选的存储特性。
分区表由一个或多个分区组成,这些分区是单独管理的,可以独立于其他分区运行。表包括已分区或未分区。即使已分区表仅由一个分区组成,该表也不同于未分区表,非分区表不能添加分区。
OceanBase 数据库将每个表分区的数据存储在自己的 SStable 中。每个 SStable 包含表数据的一部分。
OceanBase 数据库提供了多种分区策略来使用多种业务的需求。由于分区是完全透明的,业务不需要进行过多的修改,就可以将分区功能应用到绝大多数业务。
表组
对于分布式数据库, 多个表中的数据可能会分布在不同的机器上, 这样在执行 Join 查询或跨表事务等复杂操作时就需要涉及跨机器的通信,而表组功能可以避免这种跨机器操作,从而提高数据库性能。本文主要介绍表组功能及其工作原理。
作为分布式数据库,为了满足扩展性和多点写入等需求,OceanBase 数据库支持分区功能,即将一个表的数据分成多个分区来存储。表中用来参与具体数据分区的列称为分区键,通过一行数据的分区键值,对其进行 Hash 计算(数据分区的方式有多种,这里以 Hash 分区为例),能够锁定其所属的分区。
让用户将分区方式相同的表聚集到一起就形成了表组(以 Hash 分区为例,分区方式相同等价于分区个数相同,当然计算分区的 Hash 算法也是一样的),表组内每个表的同号分区称为一个分区组,如下图所示。
OceanBase 数据库在分区创建以及之后可能发生的负载均衡时, 会将一个分区组的分区放到一个机器,这样即便存在跨表操作,只要操作数据所在的分区是属于同一个分区组,那么就不存在跨机器的操作。那么如何保障操作的数据在同一个分区组呢?OceanBase 数据库无法干涉用户的操作,但是可以根据业务特点大概率地保障某些操作涉及的跨表数据在同一分区组中。
以学生表和班级表为例,学生表和班级表中都有班级 id , 可以将班级 id 列作为分区键,两表中同一班级的数据聚集到同一个分区中,这样在对班级 id 列作 JOIN 的时候,只需要在这个分区所在的机器上处理,不需要所有分区跨机锁定某一班级 id 对应的数据。对于分布式写事务的场景,如果增加一个同学信息, 需要在学生表中增加一条数据,并在班级表中更新学生总数。因为这两个数据不在一个表,自然也不在一个分区,因此需要执行分布式写事务才能进行一致的更新。由于两个分区在同一台 OBServer,OceanBase 数据库对于同一台 OBServer 上的分布式事务执行优化,因此相对跨机的分布式事务效率更高。因为分区方式相同的表才能聚集到一个表组中,所以在表组里的表不支持打破分区规则的分区操作,但是可以通过对表组作分区操作来更改其内所有表的分区。
目前的表组功能设计中,一个分区对应一个日志流,日志流通过 Paxos 算法将数据变动日志由主副本同步到备副本上,如果涉及多分区的事务,就对应多个日志流的写入,因此需要分布式事务才能完成一致的操作。尽管单机分布式事务相对跨机已经有一些优化,OceanBase 数据库支持绑定表组作为进一步的优化方式 : 分区组的分区不仅在一台机器上,而且将分区的改动写在一个日志流里,这样对一个分区组的跨表写事务就可以在一个日志流里原子的提交,将分布式事务优化为单机事务,可以达到更好的优化效果。由于分区组对应一个日志流,导致表从表组里删除变得很困难,OceanBase 数据库目前还不支持绑定表组来删除表。用户可以根据特点灵活使用表组。