背景
随着项目的规模扩大,部分表存储的业务数据越来越多,MySQL单表查询耗费的时间也跟着激增,严重影响了用户的体验。对此,开发商讨决定,对部分常用表进行分表处理,提升sql查询效率。
数据库分表,就是将原本一个表的数据,按照某种规则分拆到多张表中,降低锁粒度以及索引树,提升数据查询效率。这样效率是挺高,但非代码层面,人为的去数据库查询记录时,就稍微变得麻烦了。假设某表分16张,我们查数据时就需要分别去这十六张表中查询,人为手动一张表一张表查,肯定不现实,故而引出下面的方案。
解决方案
以设备表为例大致说明思路:
1、关联查询(多表查询)
使用 union 关键字进行表联接查询,可以同时查询多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同,并且相互对应。
select * from device_0 where device_id = "a051d43521c72a43"
UNION select * from device_1 where device_id = "a051d43521c72a43"
UNION select * from device_2 where device_id = "a051d43521c72a43"
UNION select * from device_3 where device_id = "a051d43521c72a43"
UNION select * from device_4 where device_id = "a051d43521c72a43"
UNION select * from device_5 where device_id = "a051d43521c72a43"
UNION select * from device_6 where device_id = "a051d43521c72a43"
UNION select * from device_7 where device_id = "a051d43521c72a43"
UNION select * from device_8 where device_id = "a051d43521c72a43"
UNION select * from device_9 where device_id = "a051d43521c72a43"
UNION select * from device_10 where device_id = "a051d43521c72a43"
UNION select * from device_11 where device_id = "a051d43521c72a43"
UNION select * from device_12 where device_id = "a051d43521c72a43"
UNION select * from device_13 where device_id = "a051d43521c72a43"
UNION select * from device_14 where device_id = "a051d43521c72a43"
UNION select * from device_15 where device_id = "a051d43521c72a43"
2、计算数据所属分表ID
方案1考虑到数据量问题,还是不怎么建议的。可以向开发咨询他们的分表算法,需要查数据时,自己先计算一下,直接找到对应表查,就会方便一些。
伪代码算法:绝对值(MD5(productId + device_id + device_type).hashCode() % 16)
//获取分表id
private static int getTableId(String productId, String device_id, String device_type) {
int i = Math.abs(DigestUtils.md5Hex(productId + device_id + device_type).hashCode() % 16);
System.out.println(device_id+" 的分表id为:" + i );
return i;
}
<!-- MD5依赖 -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
总结:
目前我遇到的数据库按片分表场景,可以通过上述两种思路去查数据,虽然也没方便太多,但最起码不需要一张表一张表去查了。
评论区