联表(join)操作通常非常耗时,“淘宝海量数据库之一:来自业务的挑战”(http://blog.sina.com.cn/s/blog_3fc85e260100mm4u.html )提到的淘宝收藏夹的需求其实就是一种联表,在经典的关系数据库中,两张大表的联表是个让人头疼的事情。
OceanBase以一种独特的方式实现了一类的联表。仍然以上述的淘宝收藏夹为例,DBA仍然定义info表(收藏信息)和item表(被收藏的宝贝和店铺)两张表,并且info表中冗余了宝贝/店铺的收藏相关字段(比如价格,title等)。与经典关系数据库不同的是,OceanBase的这类联表是预定义的,即DBA必须在schema中定义这两个表的关联关系,包括外键和所有关联的字段(如价格,title等)。
增加预定义联表后,item表的读写事务的执行跟没有增加预定义联表一样,但info表的查询过程会增加一个join步骤(第3步):
1)
2)
3)
由于每日合并其实就是一种全表扫描,因此info表的新tablet生成也是上述3个步骤,唯一的差别是第2)和第3)步中获取的info表以及item表的修改增量仅仅来自于frozen memtable,而非frozen memtable + new memtable。
假设系统每天凌晨1:00启动每日合并,那么每日合并完成后系统不仅把截止到凌晨1:00的info表的增量融入到了info表的新tablet中,还把item表的修改也join到了info表的新tablet中,这样后续对info表的查询,只需融合凌晨1:00以后的info修改增量以及join item表的修改增量。由于只需要join item表的增量并且这个增量通常在内存中,所以join速度很快。
由于info表中冗余的item相关字段其实是由item表决定的,因此OceanBase禁止用户直接修改info表中的这些字段。
预定义的联表,由于在info表中冗余了相关item表字段,因此整个数据库的数据量有所增加;此外,由于在每次查询中增加了一次join操作(第3步),因而每日合并的耗时也有所增加。与其完成的联表性能相比,这两条只是很小的代价。