ShardingJdbc垂直分库及公共表

前面已经介绍过,垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器
上,它的核心理念是专库专用。接下来看一下如何使用Sharding-JDBC实现垂直分库。
(1)创建数据库
创建数据库user_db 的t_user表中

CREATE TABLE`t_user`(
`user_id` bigint(20)NOT NULL COMMENT ‘用户id‘,
`fullname` varchar(255)CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘用户姓名‘,
`user_type` char(1) DEFAULT NULL COMMENT‘用户类型‘,
PRIMARY KEY(`user_id`) USING BTREE
)ENGINE=InnoDB CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=Dynamic;

修改配置信息

server:
  port: 56081
  servlet:
    context-path: /sharding-jdbc-simple-demo
spring:
  application:
    name: sharding-jdbc-simple-demo
  http:
    encoding:
      enabled: true
      charset: utf-8
      force: true
  main:
    allow-bean-definition-overriding: true
  shardingsphere:
    datasource:
      #新增一个m2库
      names: m2,m3,m1
      m1:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://rm-xxxxxx.mysql.rds.aliyuncs.com:3306/order_db_1?useUnicode=true
        username: root
        password: 123456
      m2:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://rm-xxxxxxxxx.mysql.rds.aliyuncs.com:3306/order_db_2?useUnicode=true
        username: root
        password: 123456
      m3:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://rm-xxxxxxx.mysql.rds.aliyuncs.com:3306/user_db?useUnicode=true
        username: root
        password: 123456
    sharding:
      tables:
        t_order:
          # 分库策略,以user_id为分片键,分片策略为user_id % 2 + 1,user_id为偶数操作m1数据源,否则操作m2。
          databaseStrategy:
            inline:
              shardingColumn: user_id
              algorithmExpression: m$->{user_id % 2 + 1}
          # 指定t_order表的数据分布情况,配置数据节点
          actualDataNodes: m$->{1..2}.t_order_$->{1..2}
          tableStrategy:
            inline:
              shardingColumn: order_id
              algorithmExpression: t_order_$->{order_id % 2 + 1}
          # 指定t_order表的分片策略,分片策略包括分片键和分片算法
          keyGenerator:
            type: SNOWFLAKE
            column: order_id
        t_user:
          # 指定t_user表的数据分布情况,配置数据节点
          actualDataNodes: m3.t_user
          tableStrategy:
            inline:
              shardingColumn: user_id
              algorithmExpression: t_user
      broadcast-tables: t_dict
    props:
      sql:
        show: true
mybatis:
  configuration:
    map-underscore-to-camel-case: true
swagger:
  enable: true
logging:
  level:
    root: info
    org.springframework.web: info
    com.topcheer.dbsharding: debug
    druid.sql: debug

/**
 * Created by Administrator.
 */
@Mapper
@Component
public interface UserDao {

    /**
     * 新增用户
     * @param userId 用户id
     * @param fullname 用户姓名
     * @return
     */
    @Insert("insert into t_user(user_id, fullname) value(#{userId},#{fullname})")
    int insertUser(@Param("userId") Long userId, @Param("fullname") String fullname);

    /**
     * 根据id列表查询多个用户
     * @param userIds 用户id列表
     * @return
     */
    @Select({"<script>",
            " select",
            " * ",
            " from t_user t ",
            " where t.user_id in",
            "<foreach collection=‘userIds‘ item=‘id‘ open=‘(‘ separator=‘,‘ close=‘)‘>",
            "#{id}",
            "</foreach>",
            "</script>"
    })
    List<Map> selectUserbyIds(@Param("userIds") List<Long> userIds);

    /**
     * 根据id列表查询多个用户
     * @param userIds 用户id列表
     * @return
     */
    @Select({"<script>",
            " select",
            " * ",
            " from t_user t ,t_dict b",
            " where t.user_type = b.code and t.user_id in",
            "<foreach collection=‘userIds‘ item=‘id‘ open=‘(‘ separator=‘,‘ close=‘)‘>",
            "#{id}",
            "</foreach>",
            "</script>"
    })
    List<Map> selectUserInfobyIds(@Param("userIds") List<Long> userIds);
}

测试插入方法

  @Test
    public void testInsertUser(){
        for (int i = 10 ; i<14; i++){
            Long id = i + 1L;
            userDao.insertUser(id,"姓名"+ id );
        }

    }

测试查询方法:

  @Test
    public void testSelectUserbyIds(){
        List<Long> userIds = new ArrayList<>();
        userIds.add(1L);
        userIds.add(2L);
        List<Map> users = userDao.selectUserbyIds(userIds);
        System.out.println(users);
    }

 公共表
公共表属于系统中数据量较小,变动少,而且属于高频联合查询的依赖表。参数表、数据字典表等属于此类型。可
以将这类表在每个数据库都保存一份,所有更新操作都同时发送到所有分库执行。接下来看一下如何使用
Sharding-JDBC实现公共表。
(1)创建数据库
分别在user_db、order_db_1、order_db_2中创建t_dict表:

CREATE TABLE `t_dict`(
`dict_id` bigint(20) NOT NULL COMMENT ‘字典id‘,
`type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘字典类型‘,
`code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘字典编码‘,
`value` varchar(50)CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘字典值‘,
PRIMARY KEY(`dict_id`) USING BTREE
)ENGINE=InnoDB CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=Dynamic;
@Mapper
@Component
public interface DictDao {

    /**
     * 新增字典
     * @param type 字典类型
     * @param code 字典编码
     * @param value 字典值
     * @return
     */
    @Insert("insert into t_dict(dict_id,type,code,value) value(#{dictId},#{type},#{code},#{value})")
    int insertDict(@Param("dictId") Long dictId, @Param("type") String type, @Param("code") String code, @Param("value") String value);

    /**
     * 删除字典
     * @param dictId 字典id
     * @return
     */
    @Delete("delete from t_dict where dict_id = #{dictId}")
    int deleteDict(@Param("dictId") Long dictId);

}

测试方法:

@Test
    public void testInsertDict(){
        dictDao.insertDict(3L,"user_type","2","超级管理员");
        dictDao.insertDict(4L,"user_type","3","二级管理员");
    }

测试删除

 @Test
    public void testDeleteDict(){
        dictDao.deleteDict(3L);
        dictDao.deleteDict(4L);
    }

测试关联:

@Test
    public void testSelectUserInfobyIds(){
        List<Long> userIds = new ArrayList<>();
        userIds.add(1L);
        userIds.add(2L);
        List<Map> users = userDao.selectUserInfobyIds(userIds);
        System.out.println(users);
    }

补充:

假如有些表没有分库也没有分表,而且有很多的话,应该怎么配置,就开始测试了一下。

在随便的一个库中建了一个表,没有指定节点,也没有配置别的信息,运行接口直接报错,说不到表。

个人猜想是不是和前面的库的配置顺序有关系,把表所在的库放在最后面,最后即可查询成功。

原文地址:https://www.cnblogs.com/dalianpai/p/12316719.html

时间: 2024-10-18 22:01:58

ShardingJdbc垂直分库及公共表的相关文章

数据库水平分库,垂直分库的新理解

水平分库:当数据量巨大时,将数据放到不同的表中,比如表1,表2,表3,...: 垂直分库:当一张表的字段太多,可拆分出一张或多张分表,根据主键唯一标示: 新理解: 垂直分库:当一张表中字段不多,当某些字段长度过长,表占用空间很大,检索表的时候需要执行大量的IO(数据库检索的本质是对硬盘中的文件进行io访问), 此时可以考虑对长度较长的字段进行拆分,单独成表,用原表主键进行唯一标示. 相反: 当数据库记录数不多,但字段较多,可对部分字段进行整合,比如用户的信息(电话,手机号...),以json字符

MyCAT+MySQL 搭建高可用企业级数据库集群——第4章 MyCat进阶实战至垂直分库

4-1 为什么要进行垂直分库和相关操作 4-2 收集分析业务模块 4-3 MySQL复制的步骤 4-4 MySQL复制环境说明 4-5 MySQL复制实战 4-6 MySQL复制总结 4-7 垂直切分 4-8 垂直切分相关配置 4-9 垂直切分schema文件配置 4-10 垂直切分server文件配置 4-11 后续工作 4-12 Mycat启动调试 4-13 Mycat验证配置 4-14 清理多余数据 4-15 跨分片查询 4-16 配置和验证全局表 4-17 垂直切分的优缺点 4-1 为什

分库、分表

数据分表小结 https://www.cnblogs.com/wangiqngpei557/p/9347232.html 背景 分库.分表带来的后遗症 分表策略 一些注意事项 背景 最近一段时间内结束了数据库表拆分项目,这里做个简单的小结. 本次拆分主要包括订单和优惠券两大块,这两块都是覆盖全集团所有分子公司所有业务线.随着公司的业务飞速发展,不管是存储的要求,还是写入.读取的性都基本上到了警戒水位. 订单是交易的核心,优惠券是营销的核心,这两块基本上是整个平台的正向最核心部分.为了支持未来三到

数据库水平切分的原理探讨、设计思路--数据库分库,分表,集群,负载均衡器

本文转载:http://www.cnblogs.com/olartan/archive/2009/12/02/1615131.html 第1章  引言 数据量巨大时,首先把多表分算到不同的DB中,然后把数据根据关键列,分布到不同的数据库中.库分布以后,系统的查询,io等操作都可以有多个机器组成的群组共同完成了.本文主要就是针对,海量数据库,进行分库.分表.负载均衡原理,进行探讨,并提出解决方案. 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的互联网应用,每

mysql大数据分库和分表 php解决方案!

当Mysql数据量过大时,就会面临压力分解,这时分库分表是一个不错的解决方案,现在我们就来谈谈Mysql如何分库分表比较理想,然后再用php如何调用. 1,主从复制,读写分离 对主库修改数据,查询使用从库.一主多从,来降低数据库读取压力. 2,分库分表 根据实体业务来分库,分表.如,根据数据的活跃性,根据用户uid等. 3,MySQL 不同存储引擎区别 InnoDB 用于数据完整性/写性能要求比较高的应用. MyISAM 适合查询应用. 分表是分散数据库压力的好方法. 分表,最直白的意思,就是将

你的数据库数据量上亿,为了提高效率,要分库还是分表?具体怎么做 - 开源中国社区

你的数据库数据量上亿,为了提高效率,要分库还是分表?具体怎么做 - 开源中国社区 你的数据库数据量上亿,为了提高效率,要分库还是分表?具体怎么做

四、布局管理(绝对&amp;相对、水平、垂直、格栅、表单)

目录 一.绝对布局 二.盒布局 三.格栅布局 四.格栅布局跨行跨列显示 布局管理即设置窗体上各个控件的位置,对于新手来说,这是学习的难点. 布局管理根据绝对坐标是否变动分为绝对布局和相对布局两大类.采用相对布局的窗口在变大或缩小时,各控件的位置关系会保持固定比例做相应变动.而采用绝对布局的窗口变动时,空间位置不会变动. 而相对布局根据方式不同,又可以分为水平布局(QHBoxLayout).垂直布局管理(QVBoxLayout).栅格布局管理(QGridLayout).表单布局管理(QFormLa

【译】高级T-SQL进阶系列 (三)【上篇】:理解公共表表达式(CTEs)

---恢复内容开始--- 伴随着SQL SERVER 2005的首次展示,微软介绍了一种新的被称为“公共表 表达式”(CTE)的查询结构.一个CTE是由一个简单查询定义的临时结果集,并且用在一个单独的 INSERT/UPDATE/DELETE/SELECT的作用域中.在这篇文章中,我将介绍如何定义以及使用 CTEs. 定义及使用CTEs 随着微软对CTEs的介绍,现在你有了一种不同的方式来构造和书写复杂的TSQL代码了.通过使用一个CTE你可以书写并且命名一个TSQL SELECT语句,并且随后

【分库分表】sharding-jdbc实践—分库分表入门

一.准备工作 1.准备三个数据库:db0.db1.db2 2.每个数据库新建两个订单表:t_order_0.t_order_1 DROP TABLE IF EXISTS `t_order_x`; CREATE TABLE `t_order_x` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL, `order_id` bigint NOT NULL, `order_no` varchar(30) NOT NULL,