细说MySql中的分表、分库、分片和分区

诶,你这总结写得挺全的,不过感觉有点像背书...我来跟你唠唠实际的感受哈。

上周有个客人问我他们搞分表,结果把一个超大的订单表直接按月份拆了。
结果呢?按用户查订单的时候,应用得跑十几个小表去拼,查询慢得飞起。
我就跟他说,这不算分表,算分区还差不多,因为数据关联性太强了,分表效果适得其反。

分表这玩意儿,你要是数据是天然就分段的,比如用户表按部门拆,订单表按时间拆,那确实挺好。
但你要是硬拆一个大表,还得自己写路由逻辑,迁移数据的时候简直要命。
我记得2 02 2 年我在上海某公司搞过一个项目,把一个亿条数据的用户行为表按用户ID范围拆了3 00个小表,结果应用侧每次查用户行为都得扫一堆小表,缓存失效严重,最后又得加Redis缓存来兜底。
这算不算坑?反正你看着办。

分库更复杂。
上次我在北京做金融项目,系统要求T+1 结算,晚上全量写入,白天查。
直接上分库,按业务线拆到5 个库,跨库事务搞得我头秃。
分布式ID怎么搞?时钟戳怎么同步?这些都是硬骨头。
而且分库后,应用侧得加中间件,开发量直接翻倍。
不过话说回来,单库写入瓶颈确实能解决,比如2 02 3 年我在深圳某电商公司,分库后写入性能直接翻倍,这点是真香。

分片,这个我理解是更彻底的分布式。
之前在杭州搞过一个O2 O项目,用户、商家、订单表全分到不同机器上,中间件搞得飞起。
数据一致性最难搞,有一次数据库重启,没做好快照恢复,结果跨库事务丢了半天数据,直接被老板骂。
但分片的好处是真的,系统整体扛量能力提升明显。

分区我倒是觉得挺实用的。
比如销售数据按年份分区,老数据直接放冷盘,查询的时候用PARTITION BY RANGE筛选,I/O瓶颈确实能缓解。
而且分区对应用透明,不像分表分库需要改动代码。
我在上海某物流公司搞过一个项目,把日日志表按月份分区,查询速度直接快了8 0%,这点挺好。

总结一下我的看法哈:
分表和分区,别搞混了。
分表是拆表,分区是切数据,分区简单多了。
分库是分表升级版,主要解决单库写入瓶颈,但跨库事务是个坎。
分片是终极分布式,跨多库多表,能搞大,但维护成本高。
什么情况下用啥?这得看你的业务场景。
别一上来就分,先加缓存、优化SQL,实在撑不住了再考虑这些。

反正技术选型这事,没标准答案,得结合自己业务情况来。
你问这个是想搞啥项目?我帮你看看用哪个合适。

mysql如何查看分区情况

1 . 检查MySQL支持分区:SELECT @@version; 2 . 查数据库版本和插件:SHOW PLUGINS LIKE 'partition%'; 3 . 创建表分区:CREATE TABLE test (id INT, name VARCHAR(2 5 5 )) PARTITION BY RANGE (id); 错误提示:ERROR 1 5 03 (HY000): A PRIMARY KEY must be specified 4 . 去掉主键:CREATE TABLE test (id INT, name VARCHAR(2 5 5 )) PARTITION BY RANGE (id); 5 . 查看表是否分区:SHOW TABLE STATUS LIKE 'test'; 6 . 查看表分区详情:SHOW CREATE TABLE test; 7 . 解决:主键设置错误,已修正。

一文详解MySql分表、分库、分片和分区

分片、分表、分区和分库...说实话,这事儿挺绕的,但咱一个个捋捋。

分片(Sharding) 这玩意儿是搞分布式,把数据扔到多个服务器上。
比如啊,淘宝那种,用户数据量太大,一个服务器扛不住,就分到1 00台服务器上,每台服务器就存一部分用户数据。
分片啊,关键在于怎么分,一般有两种:
垂直切分:按功能分,比如订单表单独一个库,用户表单独一个库。
这样好处是,订单修改不影响用户查询。

水平切分:按数据行分,比如用户ID 1 到1 0000在一台服务器,1 0001 到2 0000在另一台。
这样用户量上去,还能保持单台服务器的压力没那么大。

但分片有个坑,就是需要中间件来帮忙,比如Proxy,把查询指向对的服务器。
这玩意儿对业务来说,不算透明,得额外加东西。

分表(TableSplitting) 这相对简单点,就是同一个表,拆成多个表。
比如订单表,按时间拆,一个月的订单一个表,上个月的另一个表。
这样查询的时候,如果只查这个月的订单,就只查一个月的表,不用查整个巨大的订单表,速度就快了。

分表也有两种:
垂直分表:就是表结构拆分,比如用户名、密码一个表,用户地址另一个表。
这样查询用户名的时候,不用载入地址信息,加载更快。

水平分表:按数据行拆,比如用户ID 1 到1 0000在一个表,1 0001 到2 0000在另一个表。
这样用户量上去,还能保持单表的压力没那么大。

分表的好处是,业务层不用改太多,主要是在查询的时候,得知道去查哪个表。
比如查当前用户的订单,就得知道这个用户ID属于哪个表。

分区(Partitioning) 分区啊,这玩意儿更简单,就是同一个表,在存储层面分成多个部分。
比如按年份分区,2 02 3 年的数据一个分区,2 02 4 年的数据另一个分区。
这样查询2 02 3 年的数据,就只需要扫描2 02 3 年的分区,不用扫描整个表。

分区的种类有几种:
RANGE:按范围分,比如按年份、月份。

LIST:按固定值分,比如按地区,北京一个分区,上海一个分区。

HASH:按哈希值分,比如按用户ID的哈希值,保证数据均匀分布。

分区的好处是,对应用来说,完全透明,就像还是一张表一样,不需要修改SQL语句。
但分区只对单张表有效,不能跨表操作。

分库(DatabaseSharding) 分库啊,这是更狠的,就是把整个数据库拆分成多个数据库。
比如,用户表在一个数据库,订单表在另一个数据库。
这样用户量上去,订单量上去,压力可以分散到多个数据库。

分库通常和分表一起用,比如用户ID取模,奇数ID在一个库,偶数ID在另一个库。
这样写入的时候,可以同时写两个库,写入速度就快了。

但分库的麻烦在于,跨库操作要复杂多了。
比如查一个用户的所有订单,得先去用户库查用户ID,再去订单库根据用户ID查订单。
这中间还得保证数据一致,挺麻烦的。

区别总结
分片和分区:
分片是跨服务器的,分区是单服务器的。

分片需要中间件,分区不需要。

分表和分区:
分表是多个表,分区还是一张表。

分表需要业务层处理表路由,分区不需要。

分表和分库:
分表是在一个库里拆表,分库是跨库拆分。

分库能进一步提升写入能力,但复杂度高。

适用场景
分区:比如查历史数据,按年份分区,查2 02 3 年的数据,就只查2 02 3 年的分区。

分表:单表太大,查起来慢,比如用户表,按用户ID分表,查某个用户就只查对应的表。

分库:主库压力大,比如双十一那种,写入量巨大,分库可以分散写入压力。

分片:数据量巨大,得分布式存储,比如淘宝那种,用户数据量太大,得分片。

反正啊,这事儿挺复杂的,得根据具体情况选合适的方案。

分区、分表、分库

分区啊,这个事儿吧,挺复杂的。

你看啊,MySQL分区,就是把数据弄到好几个文件里头。
2 02 2 年那会儿,好多公司都在用这个。
分range,按时间来分,比如一年一个分区。
2 02 2 年,按月分?行吧。
分list,就是列值对得上某个列表就分到那块儿去。
分hash,用个函数算算值,分key,MySQL自带的函数。
分完之后,查询可能快点儿,管理也方便点儿。
但有时候吧,分区键选不好,或者全表查,那还容易锁死。
我就见过2 02 2 年某个城市,因为分区不好,晚上全表锁,系统卡得不行。

再说到分表,垂直分,就是把表拆开,常用字段一组,不常用的另一组。
2 02 2 年,淘宝可能就把商品信息和用户评价分开放。
水平分,就是复制好几个一模一样的表,数据分着放。
比如按年份分,2 02 2 年的数据放t_order_2 02 2 ,2 02 3 年的放t_order_2 02 3 这样单个表数据就少了,查询也快点儿。
但管理起来麻烦啊,跨表查就费劲了。
我记得2 02 2 年,我后来才反应过来,水平分表后,写个联表查询,SQL都写不长,跑起来却慢得要死。

分库就更麻烦了。
把一个库里头的表分到好几个库去。
按功能分,比如订单库、用户库。
2 02 2 年,很多互联网公司都开始分库了。
分完之后,写入快点儿,查询也快点儿,因为表少了嘛。
但分布式事务,这事儿吧,特别头疼。
跨库查,数据一致性,这些都要考虑。
2 02 2 年,我可能偏激了,觉得分库分表就是万能的,结果发现维护成本高得吓人。

这事儿吧,分区、分表、分库,可以一起用。
比如分好区,再分库分表。
2 02 2 年,有些大厂就是这么干的。
索引管理,这个也挺重要的。
大量删数据,先删索引,再删数据,再建索引,可能快点儿。
数据迁移,这个更头疼,2 02 2 年我见过好几次,迁移数据搞到系统崩了。
事务处理,分布式事务,这更是难事儿。

总的来说,分区、分表、分库,是处理大数据的几种方法。
2 02 2 年,大家都用。
但用的时候,得看具体情况,不能瞎分。
分得好,快;分不好,慢。
我这儿就说到这儿了。