mysql 分表的一些方案

2020-07-31 11:24:02 +08:00
 putyy

写在前面

  1. 为什么要分表呢?这个看似不是问题的问题先埋个点

进入主题吧

**ps: 这里只分享一下业务上面进行分表的一些方法吧

1. 垂直分表

垂直分表在业务开发过程中应该是随处可见的,比如:用户相关的表

CREATE TABLE `user` (
  `uid` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_name` varchar(50) DEFAULT '' COMMENT '用户登录名',
  `password` char(32) DEFAULT '' COMMENT '用户登录密码',
  `is_del` tinyint(1) unsigned DEFAULT '1' COMMENT '1,正常 2,删除',
  `create_time` char(10) DEFAULT '0' COMMENT '录入时间',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户基本表';

CREATE TABLE `user_info` (
  `uid` int(11) unsigned NOT NULL,
  `head_img` varchar(50) DEFAULT '' COMMENT '头像',
  `nick_name` varchar(50) DEFAULT '' COMMENT '昵称',
  `sign_content` varchar(255) DEFAULT '' COMMENT '个性签名',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户信息表';

......

如上所见,垂直分表就是把一个实体按照某种属性进行分类划分成多个表。


.

2.水平分表
1. 范围取表方式

比如用户联系信息: 我们可以按照范围分表

1-100w: user_info_1 100w-200w: user_info_2

CREATE TABLE `user_info_{{1+}}` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT '0' COMMENT '用户 uid',
  `mobile` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
  `address` varchar(50) NOT NULL DEFAULT '' COMMENT '住址',
  ......
  `is_del` tinyint(1) unsigned DEFAULT '1' COMMENT '1,正常 2,删除',
  `create_time` char(10) DEFAULT '0' COMMENT '录入时间',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uid_index` (`uid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户联系信息表';

.

2. 过某种特定的算法分表(取模、哈希)

取模:比如用户 ID%100,分 100 张表

CREATE TABLE `visit_record_{{1-100}}` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT '0' COMMENT '所属人 uid',
  `source_id` int(11) NOT NULL DEFAULT '0' COMMENT '资源 id',
  `type_mark` int(10) NOT NULL DEFAULT '0' COMMENT '资源类型',
  ......
  `create_time` char(10) DEFAULT '0' COMMENT '录入时间',
  `update_time` char(10) DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`id`),
 UNIQUE KEY `st_index` (`source_id`,`type_mark`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户资源访问记录';

优缺点:

取模方式:

冷热数据比较均衡,但扩展性比较差,一但数据量超过预期,原定表数量就无法承载,再加表就比较麻烦

范围方式:

扩展性比较强,但是一般新用户是比较活跃的,大部分都查询到新表上面,就导致冷热数据不均衡要解决这样的问题可以两者结合互补, 首先根据范围进行分组: 比如用户 1~1000w,分为 10 张表,然后 uid%10 得到具体表、相当于 1-10 表的总数据量已经确定了,先取范围再取模,扩展性问题就不存在了

原文

http://www.putyy.com/article/53

1065 次点击
所在节点    问与答
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/694576

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX