第36期:MySQL 原生水平拆表

腾讯游戏安全组件运行异常的全面解决方案 在使用腾讯游戏时,玩家可能会遭遇游戏安全组件运行异常的问题,这不仅影响游戏的正常启动,还可能在游戏过程中引发一系列问题。本文将详细介绍解决腾讯游戏安全组件运行异常的几种方法,帮助玩家重拾游戏乐趣。腾讯游戏安全组件运行异常是一个复杂的问题,可能涉及服务设置、游戏更新、系统环境优化以及硬件与驱动检查等多个方面。最后,希望本文能帮助玩家顺利解决腾讯游戏安全组件运行异常的问题,让玩家能够无忧无虑地享受游戏带来的乐趣。首先,我们需要从系统的服务管理入手,检查与游戏安全组件相关的服务是否正常运行。 阅读详情

引言

上一章节我们探讨过数据垂直拆分,今天我们来继续讨论数据拆分:水平拆分!

水平拆分和垂直拆分有些不一样,垂直拆分最小单元是字段,与业务有很强的关联性,具体业务对应具体的拆分数据;而水平拆分最小单元是数据行,与具体业务关系不大,业务关联可以是拆分后的单张表数据,也可以是拆分前的全局数据。简单来说,水平拆分对应用透明,应用逻辑在数据拆分后不需要大动。

正文

一般在关系数据库中,水平拆分具体对应两个方面:
第一是水平拆表。
水平拆表是基于一张表的某个字段,以一定的拆分方法拆分为多张表的数据拆分,拆分完后需要把原来对单张表的操作转换为对多张子表的操作。一般来讲,和垂直拆分类似,需要一张全局路由表。定义好路由表后,即可简化对拆分表的操作。比如涉及到数据拆分后的数据同步,查询语句下发到拆分子表等都可以直接操作路由表。

如下图所示,表 A 按照 ID 拆分,奇数表为表 A1 ,偶数表为表 A2 :

第二是水平分区。

水平分区和水平拆表类似,都是基于一个字段对表数据进行拆分。 不同的是水平分区是数据库内置功能,相比水平分表来讲,操作上会更加简单。不过最大的缺点是拆分后的数据不能跨实例,这也是现在大部分中间件或者是 NEW SQL 不直接用水平分区的原因。但是如果仅仅考虑在单机上进行数据拆分,应该首选水平分区,具体原因我们后续章节会讲,今天主要是来回顾下 MySQL 的内置水平拆表方案。

MySQL 原生水平拆表

提到 MySQL 的原生水平拆表,能想到的就是 MERGE 表!MERGE 表是针对传统 MYISAM 表做水平汇总的功能表。一提到 MYISAM ,可能好多人觉得过时了,没必要继续了!不过我这儿要讲的是,虽然 MERGE 过时了,但是 MERGE 提供给我们未来进行水平拆分的方法是非常值得学习的,这也就是为什么这篇要对 MERGE 做一个示例说明的原因。了解如何使用 MERGE 表对我们后面要讲的 INNODB 表拆分有很大的借鉴意义。

MERGE 表的优点很多,罗列如下:
  1. 数据易于管理。比如一张很大的日志表,存放10年的数据,按照月份拆分成120张表,采用 MERGE 表做汇聚,不需要对120张子表分别检索,只需要检索 MERGE 表即可。
  2. 降低单块磁盘 IO 使用率。比如可以把日志表不同月份的数据分散到不同的磁盘来避免单一磁盘 IO 使用率过高的问题。
  3. 查询简单。比如日志表的查询模式比较固定,查询当前年份数据的请求非常频繁,历史数据偶尔查询,就可以拆分成两张表,一张当前表,一张历史表,再用 MERGE 表来做这两张表的统一入口,查询 MERGE 表会自动路由到当前表。
  4. MERGE 表零维护。MERGE 表只存放所包含的子表元数据,所以不需要维护,创建销毁非常快速。
  5. MERGE 表管理的子表非常灵活。每张子表不需要局限在单个数据库中,可以灵活的分布在不同的数据库里。
那接下来,用几个简单例子来了解下 MERGE 表的使用方法。

表m1 - m10,10张子表,分别按照 id 从小到大来存放,每张表10000条记录,表结构如下:

(debian-ytt1:3500)|(ytt)>show create table m1\G
*************************** 1. row ***************************
       Table: m1
Create Table: CREATE TABLE `m1` (
  `id` int NOT NULL,
  `r1` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_r1` (`r1`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

(debian-ytt1:3500)|(ytt)>select count(*) from m1;
+----------+
| count(*) |
+----------+
|    10000 |
+----------+
1 row in set (0.00 sec)
...

对应的 MERGE 表结构如下:

(debian-ytt1:3500)|(ytt)>show create table m_global\G
*************************** 1. row ***************************
       Table: m_global
Create Table: CREATE TABLE `m_global` (
  `id` int NOT NULL,
  `r1` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_r1` (`r1`)
) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci INSERT_METHOD=LAST UNION=(`m1`,`m2`,`m3`,`m4`,`m5`,`m6`,`m7`,`m8`,`m9`,`m10`)
1 row in set (0.00 sec)

表定义中包含的子表用 union 来定义,Insert_method 表示插入时往最后一张表插入。

用 merge 表来查询这10张表记录总数:

(debian-ytt1:3500)|(ytt)>select count(*) from m_global;
+----------+
| count(*) |
+----------+
|   100000 |
+----------+
1 row in set (0.00 sec)

简化查询:

比如要在m1,m2,m3这三张表分别查询 id 为1,10001,20001的记录,需要每张表查询出来后再 UNION

(debian-ytt1:3500)|(ytt)>select * from m1 where id = 1
    -> union all
    -> select * from m2 where id = 10001
    -> union all
    -> select * from m3 where id = 20001;
+-------+------+
| id    | r1   |
+-------+------+
|     1 |    1 |
| 10001 |    1 |
| 20001 |    1 |
+-------+------+
3 rows in set (0.00 sec)

使用 merge 表来简化查询,只需查询一次即可。

(debian-ytt1:3500)|(ytt)>select * from m_global where id in (1,10001,20001);
+-------+------+
| id    | r1   |
+-------+------+
|     1 |    1 |
| 10001 |    1 |
| 20001 |    1 |
+-------+------+
3 rows in set (0.00 sec)

MERGE 表最大的问题是插入记录:MERGE 表属性 insert_method 有三个选项,NO/FIRST/LAST。

表m_global设置的是LAST,也就是说插入新的记录会往最后一张表里插入。 比如插入一条记录(1000001,100),会往子表m10里插入。

(debian-ytt1:3500)|(ytt)>insert into m_global values (1000001,100);
Query OK, 1 row affected (0.00 sec)

(debian-ytt1:3500)|(ytt)>select * from m_global where id = 1000001;
+---------+------+
| id      | r1   |
+---------+------+
| 1000001 |  100 |
+---------+------+
1 row in set (0.00 sec)

(debian-ytt1:3500)|(ytt)>select * from m10 where id = 1000001;
+---------+------+
| id      | r1   |
+---------+------+
| 1000001 |  100 |
+---------+------+
1 row in set (0.00 sec)

同样,如果设置 insert_method=first ,则只会往第一张表插入。 这会造成数据分布非常不均匀,后期需要对数据增大的表再次手动拆分。所以 MERGE 表提供了第三个选项:insert_method=no 。 设置后,不允许对 MERGE 表写入,只允许读取。

(debian-ytt1:3500)|(ytt)>alter table m_global insert_method=no;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

(debian-ytt1:3500)|(ytt)>insert into m_global values (1000002,100);
ERROR 1036 (HY000): Table 'm_global' is read only
(debian-ytt1:3500)|(ytt)>

设置 MERGE 表为只读后,子表数据的分布就得靠非 MySQL 原生方法来保证。

上面我只列了 MERGE 表的优点,缺点也有很多:
  1. MERGE 表的子表是 MYISAM 引擎,并且不能基于 MERGE 表建立全文索引。

  2. MERGE 表使用更多的文件描述符。

  3. 对 MERGE 表索引的读取会更慢。MERGE 表会扫描底下的每张表索引来看看哪个合适。

    针对第三个缺点,比如之前的查询,来对比下两条 SQL 的执行计划:

   (debian-ytt1:3500)|(ytt)>explain format=tree  select * from m1 where id = 2 union all select * from m2 where id = 10002 union all select * from m3 where id = 20002\G
   *************************** 1. row ***************************
   EXPLAIN: -> Append
       -> Stream results
           -> Rows fetched before execution
       -> Stream results
           -> Rows fetched before execution
       -> Stream results
           -> Rows fetched before execution
   
   1 row in set (0.00 sec)
   
   (debian-ytt1:3500)|(ytt)>explain format=tree select * from m_global where id in (2,10002,20002)\G
   *************************** 1. row ***************************
   EXPLAIN: -> Filter: (m_global.id in (2,10002,20002))  (cost=2.11 rows=3)
       -> Index range scan on m_global using PRIMARY  (cost=2.11 rows=3)
   
   1 row in set (0.00 sec)

结果很明显,对三张子表的 UNION 查询效率比 MERGE 表查询效率高。

  1. 对 MERGE 表的删除不会删除底下的子表。MERGE 表就是一张路由表,删除路由表不会对底下子表有影响。
   (debian-ytt1:3500)|(ytt)>drop table m_global;
   Query OK, 0 rows affected (0.01 sec)
   
   (debian-ytt1:3500)|(ytt)>show tables like 'm%';
   +--------------------+
   | Tables_in_ytt (m%) |
   +--------------------+
   | m1                 |
   | m10                |
   | m2                 |
   | m3                 |
   | m4                 |
   | m5                 |
   | m6                 |
   | m7                 |
   | m8                 |
   | m9                 |
   +--------------------+
   10 rows in set (0.00 sec)
所以 MERGE 表的应用场景仅仅局限于以下:
  1. 日志表,并且已经按照定义好的拆分键,对表进行了拆分。比如按照日期,按照用户 ID 等。
  2. 不常更新的表,可以对表进行压缩。
  3. 数据可靠性要求不高的表。比如新闻资讯类等。

总结

这篇我们讨论了 MySQL 的原生水平拆表,虽然 MERGE 表已经过时,但熟悉 MERGE 表的使用可以拓展我们后续的水平拆表思路。


关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!

第一百三十九回 介绍三个BLE包 本章回中主要介绍了Flutter中BLE的概念和操作方法,主要介绍了三个BLE包的功能和差异,以方便大家在BLE操作中选择不同的包。 阅读详情

相关推荐

arcgis根据矢量范围统计栅格数据众数、最大值、均值、中位数、最小值、少数等

像元统计数据 根据多个栅格数据计算每个像元的统计数据。 可用的统计数据有:众数、最大值、均值、中位数、最小值、少数、范围、标准差、总和及变异度。 https://desktop.arcgis.com/zh-cn/arcmap/10.3/tools/spatial-analyst-toolbox/an-overview-of-the-local-tools.htm ...

GIS哼哈哈的博客 6万+

通俗易懂:MySQL中如何对表进行垂直拆分和水平拆分?

MySQL中对表进行垂直拆分和水平拆分是为了应对数据量的增长和访问压力增大带来的性能瓶颈,这两种拆分方法分别适用于不同的场景和需求。 ### 1. 垂直拆分(Vertical

pengweid专栏 2199

STM32实战:5分钟搞定CanFestival协议栈下的CANopen心跳报文配置(附避坑指南)

本文详细介绍了如何在STM32平台上使用CanFestival协议栈快速配置CANopen心跳报文,包括硬件准备、协议栈移植、心跳报文配置及常见问题解决方案。通过实战步骤和避坑指南,帮助开发者高效实现节点状态监控,提升工业控制系统的可靠性。

win55的博客 747

【mysql的设计与优化专题(4)】表的垂直拆分和水平拆分

垂直拆分 垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表 通常我们按以下原则进行垂直拆分: 把不常用的字段单独放在一张表; 把text,blob等大字段拆分出来放在附表中; 经常组合查询的列放在一张表中; 垂直拆分更多时候就应该在数据表设计之初就执行的步骤,然后查询的时候用jion关键起来即可; 水平拆分 水平拆分是指数据表行的拆分,表的行数超过200万行时,就会变慢,这时可...

weixin_30474613的博客 575

ESP32接入扣子(Coze) API使用自定义智能体

本示例将使用ESP32开发板通过WiFi接入 **Coze API**,实现一个简单的聊天机器人功能。用户可以通过串口向机器人输入问题,ESP32将通过Coze API与智能体进行通信,并返回对应的回复。本文将详细介绍了如何通过HTTP请求和JSON解析来与API进行交互,并给出完整的代码示例。

宁子希的博客 1万+

【PCIe 总线及设备入门学习专栏 3.2.2 -- PCIe 中什么是 SR-IOV】

SR-IOV(Single Root I/O Virtualization)是 PCIe 规范中的一种技术,允许物理 PCIe 设备(称为 Physical Function, PF)虚拟化为多个虚拟设备(称为 Virtual Functions, VFs),使多个操作系统或虚拟机能够共享同一个物理设备。SR-IOV:一种 PCIe 虚拟化技术,允许将一个物理 PCIe 设备虚拟化为多个虚拟设备。:物理设备的主要管理接口。:PF 的轻量级副本,分配给虚拟机或操作系统。

CodingCos的博客 1513

mysql 大表的拆分方式

一.横向拆分 create table 新表的名称 select * from 被拆分的表 order by id limit int1,int2 int1为其实位置,int2为几条 注意:这样拆分后主键会失效手动让其主键生效即可所有要执行 alter table 新表的名称 modify 主键字段 int primary key auto_increment 二.纵向拆分 create table 新表的名称 select 需保留的字段 from 被拆分的表 拆分后原表都要保存 主要是把

jacklin_01的博客 3269

【扣子AI开发】如何开发一个图像生成智能体?

【扣子AI开发】如何开发一个图像生成智能体,从创建到发布

tl437002770的博客 2427

怎么拆分MySQL 表

MySQL 表可以通过使用ALTER TABLE语句来拆分。例如,ALTER TABLE table_name SPLIT PARTITION partition_name INTO (PARTITION p1 VALUES LESS THAN (value1), PARTITION p2 VALUES LESS THAN (value2), ...); ...

weixin_42577243的博客 636

canoe安装完成开启之后因为VectorDeviceParams30_64.dll报错崩溃打不开...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 1079

configure: error: no acceptable C compiler found in $PATH解决方案

本文主要介绍了configure: error: no acceptable C compiler found in $PATH解决方案,希望能对使用Linux的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 4万+

垂直拆分、水平拆分、分库分表策略、主从复制、读写分离

垂直拆分就是要把表按功能模块划分到不同数据库中,如果你的系统是分布式微服务的架构,那就更好理解了,一般一个微服务对应这一个或多个数据库。比如电商系统一般都会有用户中心、订单、商品等等。用户中心数据库存的都是用户信息相关的,商品数据库存的都是商品相关的数据,订单数据库则是存的订单相关的。...

qq_36929638的博客 4226

【异常】解决 Claude Code 及第三方插件提示 “API Error: 404“ 的配置修复指南

在使用 Claude 相关的 CLI 工具(如)或 IDE 插件进行开发辅助时,配置错误的模型参数是导致连接失败的常见原因。本文将针对这一典型报错进行复盘与解决。

奶爸的编程之路,也就一周冷个三天 7747

MySQL学习(36)

书籍推荐 文字教程推荐 视频教程推荐 常见问题总结 什么是MySQL? 存储引擎 一些常用命令 MyISAM和InnoDB区别 字符集及校对规则 索引 查询缓存的使用 什么是事务? 事物的四大特性(ACID) 并发事务带来哪些问题? 事务隔离级别有哪些?MySQL的默认隔离级别是? 锁机制与InnoDB锁算法 大表优化 1. 限定数据的范围 2. 读/写分离 3. 垂直分区 4. 水...

GeekLee的博客 561

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

MySQL数据库表的分区

分区的过程是将一个表或索引分解为多个更小、更可管理的部分。就访问数据库的应用而言,从逻辑上讲,只有一个表或索引,但是在物理上这个表或索引可能由数十个物理分区组成。每个分区都是独立的对象,可以独自处理,也可以作为一个更大的对象的一部分进行处理。MySQL数据库支持的分区类型为水平分区,并不支持垂直分区。此外,MySQL数据库的分区是局部分区索引,一个分区中既存放了数据又存放了索引。

weixin_41489136的博客 1112

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

MySQL分库分表

本文知识点较多,篇幅较长,请耐心学习 题记: 文章内容输出来源:拉勾教育Java高薪训练营。 本篇文章是 MySQL 学习课程中的一部分笔记。 MySQL分库分表 互联网系统需要处理大量用户的请求。比如微信日活用户破10亿,海量的用户每天产生海量的数量;美团外卖,每天都是几千万的订单,那这些系统的用户表、订单表、交易流水表等是如何处理呢? 数据量只增不减,历史数据又必须要留存,非常容易成为性能的瓶颈,而要解决这样的数据库瓶颈问题,“读写分离”和缓存往往都不合适,目前比较普遍的方案就是使用NoSQL/Ne.

weixin_41018580的博客 9924

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

MySQL 分库分表脚本实践:批量创建数据库与表

本文介绍了一个批量创建MySQL分库分表架构的自动化脚本解决方案。该脚本通过嵌套循环创建8个数据库(user_0到user_7),每个库包含16张表(user_info_0到user_info_127),共128张表。脚本实现了数据库连接配置、utf8mb4字符集支持、表结构定义(包含用户信息字段和索引)等功能,采用HereDocument语法执行批量SQL命令。该方案可有效解决大数据量下的性能瓶颈问题,同时脚本提供了清晰的执行进度显示。文章还分析了分库分表的优势、分片策略选择以及可能带来的分布式事务等挑战

pop_opo_的博客 1185

java day36 mysql(3)

1、msyql练习 1.1 数据库文件下载: 链接:https://pan.baidu.com/s/1bqfkFf0TDSacFRD4SVPjFw 提取码:2ys0 1.2 题目及答案 一、单表查询 1、选择部门30中的雇员 SELECT *from emp where Deptno=30; 2、列出所有办事员的姓名、编号和部门 SELECT e.Ename,e.Empno,d.Dname from emp as e inner join dept as d on e.Deptno=d.Deptno;

qq_43642864的博客 495

水平分表

概述 当一个表的数据很大,比如200G,这时太大,我们只靠索引也不好使了,这时我们需要分表和分区处理。分表有两种形式(水平分表和垂直分表)。 一、水平分表   核心思想:把一个大表,分割N个小表,小表和大表结构一样,只是把数据分散到不同的表中。 简单例子:比如说是通过ID直接登录(例如QQ号),可以直接使用下面的例子 每次登录验证的时候只要把传过来的Id...

不求前途凶吉,但求落幕无悔! 6459

mysql 表字段信息从一张表迁移到另一张表_Mysql之分库分表

互联网系统需要处理大量用户的请求。比如微信日活用户破10亿,海量的用户每天产生海量的数量;美团外卖,每天都是几千万的订单,那这些系统的用户表、订单表、交易流水表等是如何处理呢? 数据量只增不减,历史数据又必须要留存,非常容易成为性能的瓶颈,而要解决这样的数据库瓶颈问题,“读写分离”和缓存往往都不合适,目前比较普遍的方案就是使用NoSQL/NewSQL或者采用分库分表。使用分库分表时,主要有垂直拆分...

weixin_39887183的博客 426

AskTUG 论坛迁移实战:Discourse 从 PostgreSQL 到 MySQL 到 TiDB | 极客分享第 36 期

什么是“极客分享每周精选” “极客分享”是一个书签分享的网站(hackershare.dev),“每周精选”是该网站汇总精选书签的一个栏目。 本期正文 原文链接: https://hackershare.dev/weekly_selections/48 1. AskTUG 论坛迁移实战:Discourse 从 PostgreSQL 到 MySQL 到 TiDB 迁移数据库的障碍还挺多 标签: #TiDB #postgresql #MySQL 2. 徒手用 Go 写个 Redis 服务器 想提高编程水平

weixin_40949750的博客 371

MySQL 表结构优化:字段类型选择 + 分表分库(水平 / 垂直)实战

存储节省量 = $\sum_{i=1}^{n} (L_{old_i} - L_{new_i}) \times R$($L$=字段长度,$R$=行数)

2501_93897623的博客 330

网易一面:select分页要调优100倍,说说你的思路? (内含Mysql的36军规)

这里尼恩给大家 调优,做一下系统化、体系化的梳理。上半部分回答已接近满分,怎么得到120分呢?具体请看MySQL数据库开发的三十六条军规!

架构师尼恩 5133

【SQL】按某个关联列用一张表的数据更新另一张表

SQL更新表——用一张表的部分字段数据更新另一张表

欢迎指错||纠正||建议||水评+点赞&&评论&&关注&&转发 4903

数据库分区分表

为了提升性能,所以我们必须要解决上述几个问题,那就有必要引进分库分表,当然除了分库分表,还有别的解决方案,就是NoSQL和NewSQL,NoSQL主要是MongoDB等,NewSQL则以TiDB为代表。ƒ 当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,例如 userID 散列,进行划分,然后存储到多个结构相同的表,和不同的库上。因为单个服务的磁盘空间是有限制的,如果并发压力下,所有的请求都访问同一个节点,肯定会对磁盘IO造成非常大的影响。优点:数据库自带功能,有序,性能佳。

qq_24428851的博客 605

mysql +cobar_mysql分布式中间件cobar

Cobar的分布式主要是通过将表放入不同的库来实现:1.Cobar支持将一张表水平拆分成多份分别放入不同的库来实现表的水平拆分2.Cobar也支持将不同的表放入不同的库3.多数情况下,用户会将以上两种方式混合使用4.Cobar不支持将一张表,例如test表拆分成test_1, test_2, test_3.....放在同一个库中,必须将拆分后的表分别放入不同的库来实现分布式环境规划:IP...

weixin_42234804的博客 230
上一篇: 技术分享 | Kubernetes 学习笔记之基础知识篇
下一篇: 分布式 | dble元数据更新同步
爱可生开源社区
博客等级 码龄8年 1936粉丝 1004原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值