我们在使用 ShardingJDBC 作为分片工具的时候,会在配置中指定分片键,例如根据 create_time 创建时间来按月分片是比较常用的操作。当分片表中需要根据主键 ID 来进行更新的时候,由于不确定数据的 create_time 具体是多少,ShardingJDBC 就会在选择使用分片表的时候,就会默认选择全部。如果涉及到事务就有可能会产生 锁表
、事务等待
等问题,从而导致数据库操作时间延长。
首先从逻辑上讲,在没有确定分片键值的情况下,确实没有办法只根据ID确定数据所在分表的位置。
但是俗话说,没有绝对的问题,只有相对的场景
。我们要从场景入手,才能找到解决问题的办法。
所以,我们要先确认根据ID更新的使用场景:
例如:将数据插入到数据库中后,还需要使用数据库中生成的ID,来更新同一条数据的其他字段的话,就会涉及到根据主键更新扫描全部分表的问题。
由于是先新增后更新,那么我们程序中已经拿到了 set 好的 createTime 字段,所以我们在更新的时候,只需要在 where 中再添加一下 create_time 的筛选条件就好了:
update t_user set user_no = id where id = ? and create_time = ?;
如果是数组的话,可以这样:
update t_user set user_no = id where id in (?, ?) and create_time in (?, ?);
这样就可以大大缩小操作分表的范围。
例如:在列表中编辑某一条数据的时候,就会涉及到根据主键更新扫描全部分表的问题。
整理完毕,完结撒花~