前面我也写过一篇分库实战,很多读者讨论的很热烈。今天我在给大家实现一个分表的手把手实战。
在开始之前,我先啰嗦一点理论知识。说实话,我们每个系统并不是一上来就开始分表,分库。而是在数据量达到一定程度,且各种优化手段都使用过后,仍然存在系统瓶颈的时候,才使用分表。因为分表会加大业务的复杂程度,通常都是不得已而为之的操作。
一般的,MySQL 在单表达到千万数据量同时还在持续增长的时候,就需要想办法优化设计和实现了。通常我们的优化手段有下面 6 个步骤:
第一优化你的 SQL 和索引,这种效果立竿见影。采用这种优化方式后,若还存在性能瓶颈,可以采用第二种架构设计。
第二加缓存,memcached、redis 等。针对热点数据做优化,缓存是现在系统必须的且可靠的一种手段。
第三以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以采用第三方工具。
第四如果以上都做了还是慢,不要想着去做切分,mysql 自带分区表,先试试这个,对你的应用是透明的,无需更改代码。但是 sql 语句是需要针对分区表做优化的,sql 条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑。这一条对数据库的知识要求比较高,如果公司没有配备 DBA,或者技术储备不足的情况下,要慎用。
第五如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统。这是现在各大系统热衷采用的方案,可以优先考虑。
第六才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的 sharding key。为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql 中尽量带 sharding key,将数据定位到限定的表上去查,而不是扫描全部的表。
针对 mysql 数据库一般都是按照这个步骤去演化的,成本也是由低到高。好了,现在介绍完这些知识后,我就来给大家一个简单的分表实现。
假设我们现在有 1000 万数据,项目要求需要分 2 个表。比如,xttblog 表会被分成 xttblog_0 和 xttblog_1。注意,我这里只是举例,实际业务中,会根据具体的数据量,和增长趋势进行水平分表,分表数量也将远远的超过几十个。
根据上面的说明,我需要对 1000 万条数据分成两个表,那我的做法就是,将利用 xttblog 表的自动增长 ID 来实现分表。id%2 == 0 的操作表 xttblog_0,同理 Id%2 == 1 的操作表 xttblog_1。
你理解了这个之后,再来看看我们 MyBatis 对分表查询的相关代码吧。
<select id="getXttblog" parameterType="java.util.Map”
resultType="XttblogDO">
SELECT id,name
FROM xttblog_#{tabIndex}
WHERE id = #{id}
</select>
这个 SQL 虽然很简单,但分表会影响到其他一些业务的复杂度。
现在,假设我们要查询 1000001 的数据,那么我们的实际执行的 SQL 就如下面所示:
SELECT id,name
FROM xttblog_1
WHERE id = 1000001
我这里的分表逻辑非常简单,实际项目中可能会采用其他的一些分表策略。其中具体有哪些分表策略,以及分表会带来哪些业务问题?欢迎大家留言讨论。我后面会继续书写这方面的文章,和大家一起成长!
: » 手把手教你 Java + Mybatis 实现电商系统分表查询
原创文章,作者:wure,如若转载,请注明出处:https://blog.ytso.com/252108.html