分布式主键问题
传统数据库软件开发中,主键自动生成技术是基本需求。而各个数据库对于该需求也提供了相应的支持,比如 MySQL 的自增键,Oracle 的自增序列等。 数据分片后,不同数据节点生成全局唯一主键是非常棘手的问题。同一个逻辑表内的不同实际表之间的自增键由于无法互相感知而产生重复主键。 虽然可通过约束自增主键初始值和步长的方式避免碰撞,但需引入额外的运维规则,使解决方案缺乏完整性和可扩展性。
目前有许多第三方解决方案可以完美解决这个问题,如 UUID 等依靠特定算法自生成不重复键,或者通过引入主键生成服务等。为了方便用户使用、满足不同用户不同使用场景的需求, Apache ShardingSphere 不仅提供了内置的分布式主键生成器,例如 UUID、SNOWFLAKE,还抽离出分布式主键生成器的接口,方便用户自行实现自定义的自增主键生成器。
可以参考之前的一篇文章:https://mp.weixin.qq.com/s?__biz=MzI3Njk5ODg4OQ==&mid=2247484129&idx=1&sn=12c724ee210cc31aa15eb3bb7e3bb3b9&chksm=eb6dbd67dc1a3471501954af3e1640e3a4a6b8154006697af4e776489cd90811f7c541bcf61e&token=274298666&lang=zh_CN#rd
分片键
用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL 中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,Apache ShardingSphere 也支持根据多个字段进行分片。
路由
广播路由
对于不携带分片键的 SQL,采取广播路由的方式。
SELECT * FROM t_order WHERE good_prority IN (1, 10);
这样一句 SQL 广播到全库表查询
SELECT * FROM t_order_0 WHERE good_prority IN (1, 10);
SELECT * FROM t_order_1 WHERE good_prority IN (1, 10);
SELECT * FROM t_order_2 WHERE good_prority IN (1, 10);
SELECT * FROM t_order_3 WHERE good_prority IN (1, 10);
单播路由
单播路由用于获取某一真实表信息的场景,它仅需要从任意库中的任意真实表中获取数据即可。
实践
由于我们数据库的发展方向大概是这样的:
所以我们按照趋势先做单库分表的操作实践,再做分库分表的。
声明一下版本,以下实践用的是 ShardingSphere5.0 Beta版本
单库分表-新业务
我们先假设在理想情况下,也就是业务未开始前就采用分表的方式。
由于 ShardingSphere 是不会自动按照分表规则创建表的,所以我们先手动将表创建好,当然也只是表名不一样,表结构是相同的,以下是测试用建表语句:
CREATE TABLE `t_order_sharding_0` (
`order_id` bigint(20) NOT NULL,
`user_id` bigint(20) DEFAULT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`order_id`