共计 2873 个字符,预计需要花费 8 分钟才能阅读完成。
数据库分库分表有两个种方式
-
垂直切分
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面。
优点:- 拆分后业务清晰,拆分规则明确;- 系统之间整合或扩展容易;- 数据维护简单。
** 缺点:**
- 部分业务表无法 join,只能通过接口方式解决,提高了系统复杂度;- 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高;- 事务处理复杂。
由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决。
- 水平切分
相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,如图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190804210504414.png)
** 优点:**
- 拆分规则抽象好,join 操作基本可以数据库做;- 不存在单库大数据,高并发的性能瓶颈;- 应用端改造较少;- 提高了系统的稳定性跟负载能力。** 缺点:**
- 拆分规则难以抽象;- 分片事务一致性难以解决;- 数据多次扩展难度跟维护量极大;- 拆分规则难以抽象;- 分片事务一致性难以解决;
等等还有很多。具体的就参照 Mycat 的问题说明。还有 Mycat 支持的分片策略:
http://www.mycat.io/document/…
基于 Mycat 用枚举分片算法实现分库
创建三个数据库
修改配置文件,如果觉得手动输入比较慢,可以直接复制然后修改库名和连接信息就可以
schema.xml 配置
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- testdb 是 mycat 的逻辑库名称,链接需要用的 -->
<schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
<!--rule 对应 rule.xml name 的名称 -->
<table name="t_user" dataNode="dn1,dn2,dn3" rule="role2" />
</schema>
<!-- database 是 MySQL 数据库的库名 -->
<dataNode name="dn1" dataHost="localhost1" database="t_user1" />
<dataNode name="dn2" dataHost="localhost1" database="t_user2" />
<dataNode name="dn3" dataHost="localhost1" database="t_user3" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 可以配置多个主从 -->
<writeHost host="hostM1" url="192.168.100.131:3306" user="root" password="root">
<!-- 可以配置多个从库 -->
<readHost host="hostS2" url="192.168.100.132:3306" user="root" password="root" />
</writeHost>
</dataHost>
</mycat:schema>
rule.xml 配置
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="role2">
<rule>
<!-- 根据传入的 name 字段来判断存入那个库 -->
<columns>name</columns>
<!-- 指定的规则 -->
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
<!-- 指定的规则枚举文件 -->
<property name="mapFile">partition-hash-int.txt</property>
<!-- key 如果是数值就写 0,不是就写 1 -->
<property name="type">1</property>
<!-- 如果都不符合,默认存入 1 节点库中 -->
<property name="defaultNode">1</property>
</function>
</mycat:rule>
partition-hash-int.txt 配置 key 是 name 对应的值,value 指的是存在哪个库中
hefei=0
nanjing=1
bengbu=2
server.xml 配置
<mycat:server xmlns:mycat="http://io.mycat/">
<!-- 读写都可用的用户 -->
<user name="root" defaultAccount="true">
<property name="password">root</property>
<property name="schemas">testdb</property>
</user>
<!-- 只读用户 -->
<user name="user">
<property name="password">user</property>
<property name="schemas">testdb</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
这样配置完成,然后启动 Mycat。使用 Navicat 连接的时候还是会出现表找不到的原因
通过日志可以看到,每次查询表的时候都会携带逻辑库的名字。所以导致没有查询到。这个问题我还没有解决。只能通过写 sql 来查询和新增了。
新增四个地区名称
INSERT INTO t_user (name) VALUES ('shanghai');
INSERT INTO t_user (name) VALUES ('nanjing');
INSERT INTO t_user (name) VALUES ('hefei');
INSERT INTO t_user (name) VALUES ('bengbu');
这样就可以看出来效果了
还有很多分片策略都可以在 Mycat 官方指南上面看到。
http://www.mycat.io/document/…
正文完