资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

mysql水平折分怎么做 无收入证明去哪里开

亿级用户大表如何作水平拆分?

一般面对几千万级的数据,刚开始可能都是把数据放在MySQL的一个单库单表里,但往往这么大量级的数据到后期,数据库查询速度就很慢,因为数据量级太大,导致表的索引很大,树的层级很高,进而导致搜索性能下降,而且能放内存缓存的数据页是比较少。

创新互联公司专注于靖远企业网站建设,成都响应式网站建设公司,商城网站制作。靖远网站建设公司,为靖远等地区提供建站服务。全流程按需开发网站,专业设计,全程项目跟踪,创新互联公司专业和态度为您提供的服务

所以推荐MySQL单表数据量不超过1000w,最好是在500w内,若能控制在100万以内,那是 最佳选择,基本单表100万以内的数据,性能上不会有太大的问题,前提是,只要你建好索引就行,其实保证MySQL高性能通常没什么特别高深的技巧,就是控制数据量不要太大,另外就是保证你的查询用上了索引就行。

针对该问题,就能分库分表,可选择将该用户大表拆分为比如100张表,那么此时几千万 数据瞬间分散到100个表里去,类似

这样的100个表,每个表也就几十万数据而已。

其次,可将这100个表分散到多台数据库服务器上去,此时要分散到几台服务器呢?你要考虑两个点,一个是数据量有多少个GB/TB,一个是针对用户中心的并发压力有多高。

互联网公司对用户中心的压力不会高到离谱,因为一般不会有很多人同时注册/登录或同时修改自己的个人信息,所以并发不是大问题。

数据量层面,一般1亿行数据,大致在1~几GB之间的范围,和具体你一行数据有多少个字段也有关,所以说你几千万的用户数据,往多了说也就几个GB。这点数据量,对服务器存储空间没压力。

综上,此时你完全能给他分配两台数据库服务器,放两个库,然后100张表均匀分散在2台服务器。分的时候,注意指定一个字段来分,一般就指定userid, 根据用户id进行hash后,对表进行取模,路由到一个表里去,这就能让数据均匀分散。

至此搞定用户表的分库分表,只要给系统加上数据库中间件技术,设置好路由规则,即可轻松对2个分库上的100张表crud。平时针对某个用户增删改查,直接对他的userid进行hash,然后对表取模,做个路由,就知道到哪个表里去找这个用户的数据了。

但是这里可能会出现一些问题:用户在登录时,可能不是根据userid登录,而是根据username、手机号,此时你就没有userid了, 怎么知道去哪个表里找这个用户的数据判断是否能登录? 对此。常规方案是建立一个索引映射表,搞个表结构为 (username, userid)的索引映射 表,把username和userid一一映射, 然后针对username再做一次分库分表,把这个索引映射表可拆分为比如100个表分散在两台服务器。然后用户登录时,就能根据username先去索引映射表里查找对应userid,比如对username进行hash,然后取模路由到一个表里去,找到username对应的userid,接着根据userid进行hash再取模,路由到按照userid分库分表的一个表里,找到用户的完整数据。但这种方式会把一次查询转化为两个表的两次查询,先查索引映射表,再根据userid去查具体的数据,性能有损耗,不过有时为解决分库分表问题,也只能用这种方案。

另外就是若公司运营团队里,有用户管理模块,需要对公司的用户按照手机号、住址、年龄、性别、职业等各种条件搜索,这咋办?

没啥好办法,基本上就是要对你的用户数据表进行binlog监听,把你要搜索的所有字段同步到ES,建立好搜索的索引。然后你的运营系统就可以通过ES进行复杂的多条件搜索,ES是适合干这个事儿的,然后定位到一批userid,通过userid回到分库分表环境里去找出具体的用户数据,在页面上展示出来即可。

这就是一套比较常规和完整的分库分表的方案。

mysql水平分表的几种方法

1.按时间分表

这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。

2.按区间范围分表

一般在有严格的自增id需求上,如按照user_id水平分表:

table_1  user_id从1~100w 

table_2  user_id从101~200w 

table_3  user_id从201~300w 

... 

3.hash分表

通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表。

按如下分10张表:

function get_hash_table($table, $userid)

{

$str = crc32($userid);

if ($str  0) {

$hash = "0" . substr(abs($str), 0, 1);

} else {

$hash = substr($str, 0, 2);

}

return $table . "_" . $hash;

}

echo get_hash_table('message', 'user18991'); //结果为message_10

echo get_hash_table('message', 'user34523'); //结果为message_13

mysql里的大表用mycat做水平拆分,是不是要先手动分好,再配置mycat

将所有数据都迁移到mycat中,一共有4个数据库,blog01,blog02,blog_article01,blog_article02。

article,article_tags分别在blog_article01,blog_article02,按照uid进行水平拆分。

user_info表在blog01,link,category,tag在blog02数据库中。

浅谈mysql数据库分库分表那些事-亿级数据存储方案

mysql分库分表一般有如下场景

其中1,2相对较容易实现,本文重点讲讲水平拆表和水平拆库,以及基于mybatis插件方式实现水平拆分方案落地。

在 《聊一聊扩展字段设计》 一文中有讲解到基于KV水平存储扩展字段方案,这就是非常典型的可以水平分表的场景。主表和kv表是一对N关系,随着主表数据量增长,KV表最大N倍线性增长。

这里我们以分KV表水平拆分为场景

对于kv扩展字段查询,只会根据id + key 或者 id 为条件的方式查询,所以这里我们可以按照id 分片即可

分512张表(实际场景具体分多少表还得根据字段增加的频次而定)

分表后表名为kv_000 ~ kv_511

id % 512 = 1 .... 分到 kv_001,

id % 512 = 2 .... 分到 kv_002

依次类推!

水平分表相对比较容易,后面会讲到基于mybatis插件实现方案

场景:以下我们基于博客文章表分库场景来分析

目标:

表结构如下(节选部分字段):

按照user_id sharding

假如分1024个库,按照user_id % 1024 hash

user_id % 1024 = 1 分到db_001库

user_id % 1024 = 2 分到db_002库

依次类推

目前是2个节点,假如后期达到瓶颈,我们可以增加至4个节点

最多可以增加只1024个节点,性能线性增长

对于水平分表/分库后,非shardingKey查询首先得考虑到

基于mybatis分库分表,一般常用的一种是基于spring AOP方式, 另外一种基于mybatis插件。其实两种方式思路差不多。

为了比较直观解决这个问题,我分别在Executor 和StatementHandler阶段2个拦截器

实现动态数据源获取接口

测试结果如下

由此可知,我们需要在Executor阶段 切换数据源

对于分库:

原始sql:

目标sql:

其中定义了三个注解

@useMaster 是否强制读主

@shardingBy 分片标识

@DB 定义逻辑表名 库名以及分片策略

1)编写entity

Insert

select

以上顺利实现mysql分库,同样的道理实现同时分库分表也很容易实现。

此插件具体实现方案已开源:

目录如下:

mysql分库分表,首先得找到瓶颈在哪里(IO or CPU),是分库还是分表,分多少?不能为了分库分表而拆分。

原则上是尽量先垂直拆分 后 水平拆分。

以上基于mybatis插件分库分表是一种实现思路,还有很多不完善的地方,

例如:


分享标题:mysql水平折分怎么做 无收入证明去哪里开
文章URL:http://cdkjz.cn/article/dojsooj.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220