- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章MyBatis实现Mysql数据库分库分表操作和总结(推荐)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
作为一个数据库,作为数据库中的一张表,随着用户的增多随着时间的推移,总有一天,数据量会大到一个难以处理的地步。这时仅仅一张表的数据就已经超过了千万,无论是查询还是修改,对于它的操作都会很耗时,这时就需要进行数据库切分的操作了.
MyBatis实现分表最简单步骤 。
既然文章的标题都这么写了,不如直接上干货来的比较实际,我们就先来看看如何实现最简单的分表.
1、我们模拟用户表数据量超过千万(虽然实际不太可能) 。
2、用户表原来的名字叫做user_tab,我们切分为user_tab_0和user_tab_1(实际也可能不是这么随意的名字),这样就能把原来千万的数据分离成两个百万的数据量的两张表了.
3、如何操作这两张表呢?我们利用userId也就是用户的唯一标识进行区分.
4、userId%2 == 0的用户操作表user_tab_0,同理userId%2 == 1的用户操作表user_tab_1 。
5、那么在MyBatis中sql语句如何实现呢?下面是举例查询一个用户的sql语句 。
1
2
3
4
5
|
<select id=
"getUser"
parameterType=
"java.util.Map"
resultType=
"UserDO"
>
SELECT userId, name
FROM user_tab_#{tabIndex}
WHERE userId = #{userId}
</select>
|
其中我们传入了两个参数tabIndex和userId,tabIndex就是需要操作表的标示值(0或1),这样如果需要查询userId为5的用户,那么最终出现的sql语句就会是:
1
2
3
|
SELECT
userId,
name
FROM
user_tab_1
WHERE
userId = 5
|
其他多余的DAO服务和实现我这里就不多展示了,相信聪明的你肯定会的.
以上就是最简单的实现,不需要多余的框架,不需要任何的插件也就满足了分表的要求.
上面基本上就是所有实现的内容了,下面就要开始详细说说分离的细节了,看热闹的基本可以散了.
我将从下面几个角度分别来说说。我尽可能用最简单的白话来说.
分离的方式 。
切分的方式主要有两种,水平切分和垂直切分.
1、水平切分 。
简单的说就是,把一张表分离成几张一模一样的表,然后表的名字不同。就和上面最简单的例子一样.
这种切分适合于一张表的数据量过大而导致操作时间变慢的情况,如保存的一些记录表.
2、垂直切分 。
把不同的业务模块分成不同的数据库,这些业务模块直接最好是0耦合(简单的说就是毫无关系).
这主要是适合数据量普遍较大,而且业务场景比较分散,互相之间没有逻辑关系的情况.
分离的策略 。
具体的策略有很多种,你也可以设计你自己的,普遍的策略有下面几种,只是列举就不具体展开了.
1、“%”取模,也就是上面例子中实现的,也是最简单的一种.
2、MD5哈希 。
3、移位 。
4、日期时间(根据不同的日期分表,如一个月一张表,这个月就操作这张表,下个月就下张表) 。
5、枚举范围(用户1-10000操作第一张表,用户10001-20000操作第二张表) 。
分离的问题 。
下面说说最终要的点,导致的问题.
数据库肯定不是你说分就分的。(人家比较有感情的,怎么能说分就分呢?) 。
正经来说,我列举了下面几个分离只有会导致的问题.
1、添加时主键唯一性的问题;分离之后多张表,就会导致原有的自增长主键不唯一,所以没有办法自增长了,导致问题,解决方案的也是有的,比如单独维护一张主键表专门用来存放当前主键,或者说用别的中间件等.
2、新增时的效率问题,虽然不是个大问题,但是新增肯定会多了计算量嘛,这个问题可以忽略不计.
3、查询所带来的分页问题,分离成多张表之后,分页查询就很困难了,这也考虑到不同的分离用不同的解决方案,总之会产生问题.
4、同理,关联查询,原本一张表关联别的表或者别的表关联一张表,都很简单,但是现在分离之后就难了.
5、事务问题,多张表需要使用分布式事务才能完成原来带有事务的操作。因为原来的事务只是锁一张表现在可能要锁多张了呢.
6、扩展性问题,有的切分策略下,对数据的扩展性其实不好,之后如果有更多的数据来了,是说还能再新建表来扩展吗?
分离的原则 。
下面总结了几点分离的原则,主要是参考了网络上的,没有任何实际的依据(我也不是个年薪百万的DBA也碰不到那么大的数据去实际检验嘛),所以如果有任何问题也请指出.
1、能不分就不分 。
2、能分少就不分多 。
3、多冗余,不关联 。
4、避免使用分布式事务,主要是太难我也不会啊 。
5、单表千万记录以内就不分 。
6、现在不分以后分也来得及 。
7、扩展,耦合,仔细考虑 。
实现分离的方式 。
最后说说分离的方式,现在流行使用的DAO框架是MyBatis,也有很多别的框架。分离的实现主要有下面几种方式.
1、原生实现,就和最上面的例子一样,不需要其他任何的东西,利用原生的框架,自己去控制实现.
优点是:容易控制,掌握主动权.
缺点是:代码量多,需要自己很清楚,修改不方便,不支持复杂的切分,比如切分之后还需要做一些分页查询,还有上面说的主键问题等.
2、插件实现,利用框架本身开发的一些插件,去实现这些插件,然后利用插件去访问数据库,直接实现分离.
优点是:代码量少,实现简单,扩展性好.
缺点是:不易控制,分离方式有限,出现问题难以解决。没有找到特别成熟的插件.
3、中间件实现。利用一些数据库访问的中间件,在访问数据库之前做一些操作使得sql进行相应的变化从而实现分离.
优点是:耦合小,扩展性好,可以解决分布式事务的问题.
确定是:实现比较复杂,需要对中间件进行学习,成本较大。维护也是一个大问题,万一挂掉了。.
总之方式各有千秋,但是考虑到成本上面,第一种几乎是0成本,即可上手,而且比较容易控制,就如同最上面给出的例子一样,而且当前我处理的数据还没有到达那种处处要分离的地步,所以我选择第一种。也推荐使用。如果你找到比较好用的插件或者中间件也可以在评论中推荐.
总结 。
在实际项目中,我是因为用户的账户记录过多所以不得不进行分离,而且因为账户记录更多的只是新增没有修改和删除,查询也是少数,所以使用了最简单的方式进行分离,也选择了最简单的策略。希望上面的原则策略方式和问题的总结能对你有所帮助,有所参考。如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 。
原文链接:http://www.cnblogs.com/linkstar/p/7404698.html 。
最后此篇关于MyBatis实现Mysql数据库分库分表操作和总结(推荐)的文章就讲到这里了,如果你想了解更多关于MyBatis实现Mysql数据库分库分表操作和总结(推荐)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一台 MySQL 服务器和一台 PostgreSQL 服务器。 需要从多个表中复制或重新插入一组数据 MySQL 流式传输/同步到 PostgreSQL 表。 这种复制可以基于时间(Sync)或事
如果两个表的 id 彼此相等,我尝试从一个表中获取数据。这是我使用的代码: SELECT id_to , email_to , name_to , status_to
我有一个 Excel 工作表。顶行对应于列名称,而连续的行每行代表一个条目。 如何将此 Excel 工作表转换为 SQL 表? 我使用的是 SQL Server 2005。 最佳答案 这取决于您使用哪
我想合并两个 Django 模型并创建一个模型。让我们假设我有第一个表表 A,其中包含一些列和数据。 Table A -------------- col1 col2 col3 col
我有两个表:table1,table2,如下所示 table1: id name 1 tamil 2 english 3 maths 4 science table2: p
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 1 年前。 Improve th
下面两个语句有什么区别? newTable = orginalTable 或 newTable.data(originalTable) 我怀疑 .data() 方法具有性能优势,因为它在标准 AX 中
我有一个表,我没有在其中显式定义主键,它并不是真正需要的功能......但是一位同事建议我添加一个列作为唯一主键以随着数据库的增长提高性能...... 谁能解释一下这是如何提高性能的? 没有使用索引(
如何将表“产品”中的产品记录与其不同表“图像”中的图像相关联? 我正在对产品 ID 使用自动增量。 我觉得不可能进行关联,因为产品 ID 是自动递增的,因此在插入期间不可用! 如何插入新产品,获取产品
我有一个 sql 表,其中包含关键字和出现次数,如下所示(尽管出现次数并不重要): ____________ dog | 3 | ____________ rat | 7 | ____
是否可以使用目标表中的LAST_INSERT_ID更新源表? INSERT INTO `target` SELECT `a`, `b` FROM `source` 目标表有一个自动增量键id,我想将其
我正在重建一个搜索查询,因为它在“我看到的”中变得多余,我想知道什么 (albums_artists, artists) ( ) does in join? is it for boosting pe
以下是我使用 mysqldump 备份数据库的开关: /usr/bin/mysqldump -u **** --password=**** --single-transaction --databas
我试图获取 MySQL 表中的所有行并将它们放入 HTML 表中: Exam ID Status Assigned Examiner
如何查询名为 photos 的表中的所有记录,并知道当前用户使用单个查询将哪些结果照片添加为书签? 这是我的表格: -- -- Table structure for table `photos` -
我的网站都在 InnoDB 表上运行,目前为止运行良好。现在我想知道在我的网站上实时发生了什么,所以我将每个页面浏览量(页面、引荐来源网址、IP、主机名等)存储在 InnoDB 表中。每秒大约有 10
我在想我会为 mysql 准备两个表。一个用于存储登录信息,另一个用于存储送货地址。这是传统方式还是所有内容都存储在一张表中? 对于两个表...有没有办法自动将表 A 的列复制到表 B,以便我可以引用
我不是程序员,我从这个表格中阅读了很多关于如何解决我的问题的内容,但我的搜索效果不好 我有两张 table 表 1:成员 id*| name | surname -------------------
我知道如何在 ASP.NET 中显示真实表,例如 public ActionResult Index() { var s = db.StaffInfoDBSet.ToList(); r
我正在尝试运行以下查询: "insert into visits set source = 'http://google.com' and country = 'en' and ref = '1234
我是一名优秀的程序员,十分优秀!