2019独角兽企业重金招聘Python工程师标准>>>

数据库分片(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。

转载于:https://my.oschina.net/u/2351717/blog/673672

Hibernate与数据库分表相关推荐

  1. 数据库分表时OR Mapping方法

    最近使用ADO.net Entity应用中遇到一个分表的应用,IDE中是不可视化支持这个的,为此使用了基于LINQ的方法解决了该问题. 数据库分表的意义和目的 分表技术顾名思义,就是把若干个存储相同类 ...

  2. 超大数据量存储常用数据库分表分库算法总结

    这篇文章主要介绍了超大数据量存储常用数据库分表分库算法总结,本文讲解了按自然时间来分表/分库.按数字类型hash分表/分库.按md5值来分表/分库三种方法,以及分表所带来的问题探讨,需要的朋友可以参考 ...

  3. mysql一张表1亿天数据_1亿条数据在PHP中实现Mysql数据库分表100张

    转: 1亿条数据在PHP中实现Mysql数据库分表100张 http://php-z.com/thread-2115-1-1.html (出处: PHP-Z) 当数据量猛增的时候,大家都会选择库表散列 ...

  4. 数据库分表之雪花算法

    文章目录 一.背景 二.数据库分表 1. 垂直分表 2. 水平分表 一.背景 需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量. 数据库的扩展方式主要包括:业务分库.主从复制, ...

  5. 数据库基础知识(二)数据库分表技术

    数据库分表技术: 1. 分表技术 a). 水平分割(分表) 将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,MYI索引文件,frm表 ...

  6. php mysql新闻表模板_新闻数据库分表案例

    新闻数据库分表案例目录:[-]NetkillerMySQL手札MySQLMariaDB...Mr.NeoChan,陈景峰(BG7NYT)4.16.3.新闻数据库分表案例NetkillerMySQL手札 ...

  7. mysql新闻分表,新闻数据库分表案例 - http://www.netkiller.cn - OSCHINA - 中文开源技术交流社区...

    本文节选自<Netkiller Architect 手札> 6.3. 新闻数据库分表案例 这里我通过一个新闻网站为例,解决分表的问题 避免开发中经常拼接表,我采用一个一劳永逸的方法,建立一 ...

  8. MySQL数据库分表分区

    防伪码:当你终于沉默,成熟才刚刚开始. 为什么要分表和分区? 我们的数据库数据越来越大,随之而来的是单个表中数据太多.以至于查询书读变慢,而且 由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性 ...

  9. mysql数据库分表备份脚本_MySQL分库分表备份脚本

    MySQL分库分表备份脚本 vim /data/mysqlback.sh #! /bin/bash BAKPATH=/data/mysql-back MYUSER=root MYPASS=" ...

最新文章

  1. 使用深度学习检测DGA(域名生成算法)——LSTM的输入数据本质上还是词袋模型...
  2. Unet实现图像分割(二)
  3. Jenkins 技术篇-jenkins的下载、安装与配置
  4. ddr2是几代内存_内存系列一:快速读懂内存条标签
  5. 逆序数介绍以及算法实现浅析
  6. MySQL InnoDB存储引擎为什么要用自增的主键?
  7. Android在程序中浏览网页
  8. 算法与数据结构 第3章 高级排序算法下 学习笔记
  9. java常识(小细节)
  10. 苹果手机查看mysql_教你苹果手机怎么查几个月或多天以前的通话记录
  11. 移动互联网创业者遭遇巨头模仿蚕食
  12. 微信小程序自定义省市区下拉框
  13. mysql键值_如何在MySQL中存储键值对?
  14. 应对ME23数据抓取时ID发生变化 SAP
  15. 在uniapp的小程序中使用自己的字体库
  16. 接力贷合力贷你知道吗?
  17. python爬取网易云评论最多的歌_python爬取网易云音乐评论
  18. USB输入单节锂电池0.5A充电管理IC,防高压40V保护电路-7号电路板
  19. 乐博Android客户端(新浪微博)1.01发布,欢迎各位童鞋试用
  20. wps手机版ppt动画效果_你不知道的WPS|仅这2个制作PPT的动画技能,就足够让你的PPT逼格瞬间提升...

热门文章

  1. SharePoint 数据迁移解决方案
  2. Heritrix 3.1.0 源码解析(六)
  3. MongoDB最佳实践(转)
  4. RAID5EE 含有上次残余信息的分析
  5. How to remove live visual tree?
  6. web上传图片的几种方法!
  7. 正则表达式在JS中的应用
  8. Android屏幕适配全攻略(最权威的官方适配指导) (转)
  9. F# -- TCP/IP小测试
  10. 如何在一个站点里使用两个Web.sitemap 或是多个Web.sitemap?