文档章节

Hibernate与数据库分表

王春-海子
 王春-海子
发布于 2016/05/11 21:49
字数 1708
阅读 148
收藏 11

数据库分片(shard)是一种在数据库的某些表变得特别大的时候采用的一种技术。

 

通过按照一定的维度将表切分,可以使该表在常用的检索中保持较高的效率,而那些不常用的记录则保存在低访问表中。比如:销售记录按照时间来切分。(横向切分)

也可以根据地域进行拆分,使得每个地区访问自己的表从而进行负载均衡。(纵向切分)

也可以纵横切分,使表拆的更细致。

也可以分库,让不同的数据存放在不同的服务器上,从而进一步均衡负载。

 

当遇到这样的事情的时候,如果不是采用了MongoDB这种自动拆表的工具,一般来说,都要自己实现一下切表的策略。其实,Hibernate中已经提供了一个很好用的包:

Hiberante Shard,该包是Google贡献给Hibernate社区的。根据其资料显示,现在这个包还是有些限制的。

比如:不能够进行跨表的order by,不能实现跨表的distinct,不能采用基础数据类型(如int)作为ID的类型。

 

但是它可以支持跨表的唯一ID,跨表的查询,跨表的累计...

而且它似乎只要少量的代码和简单的配置就可以使用,看来它真的是一个很好的工具。值得一试。

很不幸,网上的例子太少了,只找到了一段例子代码:

Hibernate Shards 数据的水平、垂直切割系列

 

这段代码下载之后运行了,由于数据量太少,并且生成在同一个表中,无法证明Hibernate Shards的作用。

官方网站的资料似乎也是惜墨如金,没有解释的非常详细。

 

    Shards如何配置,如何使用呢?

    一个工程里,有的表要切分,有的不必,如何做?

    Shard和ebean如何结合使用呢?

 

带着这些课题,我开始了对Hibernate Shard的调查和研究。

 

Hibernate是一种ORM的包,它要有来自mapping.xml的“原型”,来自Java的Entity才能够形成ORMapping,还有一个数据库的表,它们的关系是一对一。

而如果采用分片技术,那么应该是一个原型,一个Entity,对应数据库的若干个结构相同的表。

 

在Hibernate Shard中,通过一个叫做“策略”的东西来完成这样的过程。

它允许通过定义不同的策略,来将不同分类的数据存放在不同的表(乃至库)中,而这个要通过一组和hibernate.cfg.xml结构一样的配置文件来定义。就像下面这样:

复制代码

1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-configuration PUBLIC 
 3     "-//Hibernate/Hibernate Configuration DTD//EN" 
 4     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6 <session-factory>
 7       <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 8       <property name="connection.url">jdbc:mysql://localhost/test</property>
 9       <property name="connection.username">root</property>
10       <property name="connection.password">root</property>
11       <property name="connection.pool_size">10</property>
12       <property name="show_sql">true</property>
13       <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
14       <property name="hbm2ddl.auto">validate</property>
15       <property name="hibernate.connection.shard_id">0</property>
16       <property name="hibernate.shard.enable_cross_shard_relationship_checks">false</property>
17 
18 
19       <mapping resource="ContactEntity.hbm.xml" />
20 </session-factory>
21 
22 </hibernate-configuration>

复制代码

 

然后在生成SessionFactory的时候采用这样的代码:

复制代码

1 private static SessionFactory createSessionFactory() {
 2         Configuration prototypeCfg = new Configuration()
 3             .configure("shard0.hibernate.cfg.xml");
 4         List<ShardConfiguration> shardCfgs = new ArrayList<ShardConfiguration>();
 5         shardCfgs.add(buildShardConfig("shard0.hibernate.cfg.xml"));
 6         shardCfgs.add(buildShardConfig("shard1.hibernate.cfg.xml"));
 7         ShardStrategyFactory strategyFactory = buildShardStrategyFactory();
 8         ShardedConfiguration shardedConfig = new ShardedConfiguration(
 9             prototypeCfg, shardCfgs, strategyFactory);
10        return shardedConfig.buildShardedSessionFactory();
11    }

复制代码

而策略则分为三种:

   ShardAccessStrategy

   ShardSelectionStrategy

   ShardResolutionStrategy

我们需要上述三种策略才能够构建Hibernate的SessionFactory,就像下面这样。

复制代码

1 private static ShardStrategyFactory buildShardStrategyFactory() {
 2        return new ShardStrategyFactory() {
 3            public ShardStrategy newShardStrategy(List<ShardId> shardIds) {
 4                ShardSelectionStrategy ss = new MyShardSelectionStrategy(shardIds);
 5                ShardResolutionStrategy rs = new MyShardResolutionStrategy(shardIds);
 6                ShardAccessStrategy as = new SequentialShardAccessStrategy();
 7                return new ShardStrategyImpl(ss, rs, as);
 8            }
 9        };
10     }

复制代码

那么这三种策略都是什么,应该怎么配置呢?

这三种策略的文档说明和代码说明不怎么一致。(说实在的,这段文档真的没怎么看懂,幸运的是,它是OpenSource的)

  ShardAccessStrategy   文档说,切片访问策略,它定义了Hibernate如何和多个Shard之间进行访问。

                幸运的是,Hibernate已经为我们创建了两个定义好了的ShardAccessStrategy,它们是:

                 SequentialShardAccessStrategy  (顺序切片访问策略) 和  ParallelShardAccessStrategy(并行切片访问策略)

                顺序切片访问策略 如其名称所言,它按照顺序切片,资料显示,它有可能在访问无序数据时性能偏低,若是这种情况,官方建议使用LoadBalancedSequentialShardAccessStrategy。

                并行切片访问策略 如其名称所言,它提供了并行访问的策略,所以它同时要求提供一个并行策略执行器。 —— 听起来挺难得,而且,介绍资料说——这超纲了。

                先不管这么多吧,假设我们访问的数据是一种,按地区、按年份增长的数据,每个城市个月增长量都在10万~1百万,那么我们要在这里采用什么策略呢?

  数据是按照时间排序的,所以,我们可以采用SequentialShardAccessStrategy,按月分片,并且按照地区分片。

 

        ShardSelectionStrategy  文档说定义了如何创建一个新对象。

        代码上的注释说:Determine the specific shard on which this object should reside

         也就是说,这个是定义哪个领域用来存放这条数据的。

       ShardResolutionStrategy 文档说是表示如何将数据进行分流的。比如我们提到的按地区、按月分片。那么数据需要根据这些条件存放在不同的表中。而ShardResolutionStrategy就是帮助我们来完成这个动作的。

        代码注释上说:Determine the shards on which an object might live

 

 

       在ShardStrategyFactory的newShardStrategy方法中传入的参数List<ShardId> shardIds会帮助我们进行选择区域动作。ShardId会定位对应的Continent。

       我跟踪了一下那段例子代码,这里的shardIds表示有多少个hibernate.cfg.xml文件中的不同的shard_id字段的值。而ShardSelectionStrategy在Insert的时候会执行,而ShardResolutionStrategy则会在Select的时候执行。(update/delete尚未尝试。)

       我们可以在ShardSelectionStrategy中建立自己的策略,比如,按照时间,按照地区来区分数据。从而把数据存放在不同的中。

       因为shardx.hibernate.cfg.xml指定了不同的数据库,所以,到这里可以实现分库了。

      而对于那些不必分表的直接return 0即可。

 

     第一版的测试代码在这里下载

---------------

下一步我将研究一下,如何分表和如何结合Ebean。

本文转载自:http://www.cnblogs.com/stephen-wang/archive/2013/07/05/3172900.html

王春-海子
粉丝 7
博文 49
码字总数 11981
作品 0
江北
技术主管
私信 提问
基于 Spring JDBC 的轻量级 ORM 框架--sborm

一、SBORM 介绍 1、目前只考虑支持 mysql; 2、基于spring jdbc的上层封装,底层jdbc操作基于JdbcTemplate,对于使用spring jdbc的人会有一点价值,比较简洁的封装可以节省很多重复劳动,具体...

franticwind
2015/03/30
2.6K
0
分库分表事宜

分库分表概念 按字面解释,分库是把原本存储于一个库的数据分块存储到多个库上,分表是把原本存储于一个表的数据分块存储到多个表上。 合理的分库可以降低单台服务器的负载压力,合理的分表可...

wangshuaixin
2016/12/18
135
2
使用hibernate 分表做增删改查

公司项目有一张表的数据量特别大、而且时间越长累积的数据量就越大、 后来DBA决定分表来解决性能问题、 分表是指 一个母体表 一群子表(结构和字段与母体表完全一样) 我们程序对母表操作其实...

王春-海子
2016/05/13
123
0
hibernate实现分库分表

@Sky__ 你好,想跟你请教个问题: 看到你的评论,说实现了hibernate的分库分表,想请教下如何实现的 分库分表我做到了,用spring的架构 , 可以在一个应用中跨多个数据库,而且是线程安全的!...

lslmail
2013/09/22
2.5K
2
Hibernate如何实现自动分表以及查询问题?

有个需求,服务器部分日志需要存入数据库,用于统计分析.数据量有点大,打算按照日志时间每日分表,保留半年内数据. 重点是按照日期分表. 我用mybatis实现了一个分表逻辑,用法就是替换表名. 插入...

Jwxl
2017/11/03
350
2

没有更多内容

加载失败,请刷新页面

加载更多

还为PDF转Word抓狂?以下神器让你在职场倍受欢迎!

身在职场的你,是否一直在琢磨:如何能让自己在公司更受欢迎?如何才能在办公室里混个好人缘?如何在同事圈里留个好印象?其实,想要让自己成为受欢迎的人,只要让自己成为大家需要的人不就行...

foxit2world
10分钟前
3
0
AndServer+Service打造Android服务器实现so文件调用

so 文件调用 随着 Android 移动安全的高速发展,不管是为了执行效率还是程序的安全性等,关键代码下沉 native 层已成为基本操作。 native 层的开发就是通指的 JNI/NDK 开发,通过 JNI 可以实...

夜幕NightTeam
12分钟前
3
0
Docker下kafka学习三部曲之二:本地环境搭建

在上一章《 Docker下kafka学习,三部曲之一:极速体验kafka》中我们快速体验了kafka的消息分发和订阅功能,但是对环境搭建的印象仅仅是执行了几个命令和脚本,本章我们通过实战来学习如何编写...

程序员欣宸
12分钟前
2
0
萌新推荐!不再为Excel转换PDF发愁,Aspose.Cells for .NET一步到位!

Aspose.Cells for .NET(点击下载)是Excel电子表格编程API,可加快电子表格管理和处理任务,支持构建具有生成,修改,转换,呈现和打印电子表格功能的跨平台应用程序。 将Excel工作簿转换为...

mnrssj
13分钟前
2
0
对于绘画小白怎么画制服?该注意什么?

怎样制作学生服装?想必绘画初学者们常常会想的问题吧,不知道怎样才能画好人物的衣服,别着急,今日就在这儿讲一些关于如何绘画学生衣服校服的教程给我们!期望能够帮到你们! 轻便西装是不...

热爱画画的我
18分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部