数据库分库分表有两个种方式
垂直切分
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面。
优点:- 拆分后业务清晰,拆分规则明确;- 系统之间整合或扩展容易;- 数据维护简单。
**缺点:** - 部分业务表无法 join,只能通过接口方式解决,提高了系统复杂度; - 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高; - 事务处理复杂。
由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决。
- 水平切分
相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,如图:
**优点:** - 拆分规则抽象好,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=0nanjing=1bengbu=2server.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/...