MySQL数据库优化之分表分库操作实例详解

所属分类: 数据库 / Mysql 阅读数: 2046
收藏 0 赞 0 分享

本文实例讲述了MySQL数据库优化之分表分库操作。分享给大家供大家参考,具体如下:

分表分库

垂直拆分

垂直拆分就是要把表按模块划分到不同数据库表中(当然原则还是不破坏第三范式),这种拆分在大型网站的演变过程中是很常见的。当一个网站还在很小的时候,只有小量的人来开发和维护,各模块和表都在一起,当网站不断丰富和壮大的时候,也会变成多个子系统来支撑,这时就有按模块和功能把表划分出来的需求。其实,相对于垂直切分更进一步的是服务化改造,说得简单就是要把原来强耦合的系统拆分成多个弱耦合的服务,通过服务间的调用来满足业务需求看,因此表拆出来后要通过服务的形式暴露出去,而不是直接调用不同模块的表,淘宝在架构不断演变过程,最重要的一环就是服务化改造,把用户、交易、店铺、宝贝这些核心的概念抽取成独立的服务,也非常有利于进行局部的优化和治理,保障核心模块的稳定性
垂直拆分用于分布式场景。

水平拆分

上面谈到垂直切分只是把表按模块划分到不同数据库,但没有解决单表大数据量的问题,而水平切分就是要把一个表按照某种规则把数据划分到不同表或数据库里。例如像计费系统,通过按时间来划分表就比较合适,因为系统都是处理某一时间段的数据。而像SaaS应用,通过按用户维度来划分数据比较合适,因为用户与用户之间的隔离的,一般不存在处理多个用户数据的情况,简单的按user_id范围来水平切分
通俗理解:水平拆分行,行数据拆分到不同表中, 垂直拆分列,表数据拆分到不同表中

水平分割案例

思路:在大型电商系统中,每天的会员人数不断的增加。达到一定瓶颈后如何优化查询。
可能大家会想到索引,万一用户量达到上亿级别,如何进行优化呢?
使用水平分割拆分数据库表。

如何使用水平拆分数据库

使用水平分割拆分表,具体根据业务需求,有的按照注册时间、取摸、账号规则、年份等。

使用取摸方式分表

首先我创建三张表 user0 / user1 /user2 , 然后我再创建 uuid表,该表的作用就是提供自增的id。

create table user0(
id int unsigned primary key ,
name varchar(32) not null default '',
pwd varchar(32) not null default '')
engine=myisam charset utf8;
create table user1(
id int unsigned primary key ,
name varchar(32) not null default '',
pwd varchar(32) not null default '')
engine=myisam charset utf8;
create table user2(
id int unsigned primary key ,
name varchar(32) not null default '',
pwd varchar(32) not null default '')
engine=myisam charset utf8;
create table uuid(
id int unsigned primary key auto_increment)engine=myisam charset utf8;

创建一个demo项目

POM文件

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

Service代码

@Service
public class UserService {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public String regit(String name, String pwd) {
        // 1.先获取到 自定增长ID
        String idInsertSQL = "INSERT INTO uuid VALUES (NULL);";
        jdbcTemplate.update(idInsertSQL);
        Long insertId = jdbcTemplate.queryForObject("select last_insert_id()", Long.class);
        // 2.判断存储表名称
        String tableName = "user" + insertId % 3;
        // 3.注册数据
        String insertUserSql = "INSERT INTO " + tableName + " VALUES ('" + insertId + "','" + name + "','" + pwd
                + "');";
        System.out.println("insertUserSql:" + insertUserSql);
        jdbcTemplate.update(insertUserSql);
        return "success";
    }
    public String get(Long id) {
        String tableName = "user" + id % 3;
        String sql = "select name from " + tableName + " where id="+id;
        System.out.println("SQL:" + sql);
        String name = jdbcTemplate.queryForObject(sql, String.class);
        return name;
    }
}

Controller

@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/regit")
    public String regit(String name, String pwd) {
        return userService.regit(name, pwd);
    }
    @RequestMapping("/get")
    public String get(Long id) {
        String name = userService.get(id);
        return name;
    }
}

更多关于MySQL相关内容感兴趣的读者可查看本站专题:《MySQL查询技巧大全》、《MySQL常用函数大汇总》、《MySQL日志操作技巧大全》、《MySQL事务操作技巧汇总》、《MySQL存储过程技巧大全》及《MySQL数据库锁相关技巧汇总

希望本文所述对大家MySQL数据库计有所帮助。

更多精彩内容其他人还在看

MySQL中按照多字段排序及问题解决

这篇文章主要介绍了MySQL中按照多字段排序及问题解决的方法,非常的实用,有需要的小伙伴可以参考下。
收藏 0 赞 0 分享

MySQL外键使用详解

两天有人问mysql中如何加外键,今天抽时间总结一下。mysql中MyISAM和InnoDB存储引擎都支持外键(foreign key),但是MyISAM只能支持语法,却不能实际使用。
收藏 0 赞 0 分享

Mysql中LAST_INSERT_ID()的函数使用详解

从名字可以看出,LAST_INSERT_ID即为最后插入的ID值,有了这个实用的函数,我们可以实现很多问题,下面我们就来深入探讨下。
收藏 0 赞 0 分享

MySql insert插入操作的3个小技巧分享

这篇文章主要介绍了MySql insert插入操作的3个小技巧分享,本文讲解了插入的数据来源自其他表、插入时排除(忽略)重复记录、插入时遇到重复记录做更新操作三个小技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

mysql修改自增长主键int类型为char类型示例

这篇文章主要介绍了mysql修改自增长主键int类型为char类型示例,需要的朋友可以参考下
收藏 0 赞 0 分享

Windows下使用Cygwin编译MySQL客户端

这篇文章主要介绍了Windows下使用Cygwin编译MySQL客户端,本文详细的讲解了编译过程,需要的朋友可以参考下
收藏 0 赞 0 分享

MySQL数据库优化推荐的编译安装参数小结

这篇文章主要介绍了MySQL数据库优化推荐的编译安装参数小结,需要的朋友可以参考下
收藏 0 赞 0 分享

MySQL之Field‘***’doesn’t have a default value错误解决办法

这篇文章主要介绍了MySQL之Field‘***’doesn’t have a default value错误解决办法,需要的朋友可以参考下
收藏 0 赞 0 分享

php连接MySQL的两种方式对比

这篇文章主要介绍了php连接MySQL的两种方式对比,一种是原生的链接方式另外一种是PDO方式,附上示例,推荐给大家,有需要的小伙伴可以参考下
收藏 0 赞 0 分享

Mysql InnoDB删除数据后释放磁盘空间的方法

这篇文章主要介绍了Mysql InnoDB删除数据后释放磁盘空间的方法,Innodb数据库对于已经删除的数据只是标记为删除,并不真正释放所占用的磁盘空间,这就导致InnoDB数据库文件不断增长,本文就讲解释放磁盘空间的方法,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多