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

news/2024/4/28 1:14:43/文章来源:https://blog.csdn.net/pengweid/article/details/137027433

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

###

1. 垂直拆分(Vertical Partitioning)

垂直拆分

是对表结构进行重组,将一个大表按照列的相关性分割成两个或多个表,通常是将那些不太常用或数据类型差异较大的字段放到另外的表中。这样做的目的是减少单表的宽度,提升查询性能,尤其是对于那些不需要经常一起使用的列。

例如,假设有一个包含用户信息的大表`users`,其中包含用户的姓名、联系方式、登录历史、个人简介等多个字段。如果发现登录历史和个人简介字段并不频繁查询,且数据量较大,则可以通过垂直拆分将其分离到不同的表中:

-- 原始大表

CREATE TABLE users (

id INT PRIMARY KEY,

username VARCHAR(50),

password VARCHAR(50),

email VARCHAR(50),

address TEXT,

bio TEXT,

login_history JSON // 不常用字段,可拆分

);

-- 垂直拆分后的表

CREATE TABLE user_basic_info (

id INT PRIMARY KEY,

username VARCHAR(50),

password VARCHAR(50),

email VARCHAR(50),

address TEXT

);

CREATE TABLE user_profile (

id INT PRIMARY KEY,

bio TEXT,

login_history JSON

);

###

2. 水平拆分(Horizontal Partitioning)

水平拆分

则是将同一个表的行数据按照一定的规则分布在不同的表或数据库中,每个表的结构完全相同,只是存储的数据集合不同。这样做主要是为了分散数据量,提高并行处理能力和降低单表数据过大导致的查询性能下降。

水平拆分通常依据某个特定字段的值(如用户ID取模、时间范围或其他业务逻辑相关的属性)来决定数据存储的位置。例如,一个大型的订单表可以根据订单创建时间,将每年的数据存放在不同的表中:

-- 假设原始订单表

CREATE TABLE orders (

order_id INT PRIMARY KEY,

user_id INT,

order_date DATE,

product_name VARCHAR(100),

price DECIMAL(10,2)

);

-- 水平拆分后的表

CREATE TABLE orders_2020 (

order_id INT PRIMARY KEY,

user_id INT,

order_date DATE,

product_name VARCHAR(100),

price DECIMAL(10,2)

);

CREATE TABLE orders_2021 (

order_id INT PRIMARY KEY,

user_id INT,

order_date DATE,

product_name VARCHAR(100),

price DECIMAL(10,2)

);

-- 这样每年的数据都在单独的表中

更复杂的水平拆分还可以结合分区表(Partitioning)或分布式数据库中间件(如ShardingSphere、Cobar等)实现自动化管理和路由,以便透明地将数据分布到多个物理节点上,同时保持应用程序看起来像在操作单个逻辑表。

总结来说,垂直拆分关注的是减少单表字段数量,优化查询性能;而水平拆分则关注的是将数据行分摊到不同表中,以应对海量数据存储和高并发访问的需求。当然,为了更直观地理解MySQL查询优化器的工作原理,我们再来一个贴近生活的例子:

想象一下光头强是一家快递公司的智能调度员,他每天要面对众多的包裹配送任务(类比SQL查询)。有一天,他接到了一个特殊的任务,需要尽快将一批包裹送到森林各处的小动物手中(获取特定数据)。

有两种配送策略供光头强选择:

策略1(索引扫描):光头强有一份详尽的地址簿,上面标记了每个动物家的位置以及它们附近的地标(类似索引结构)。他可以根据这份地址簿快速定位到每个收件人家附近,然后逐一派送。

策略2(全表扫描):没有地址簿的情况下,光头强只能逐个街区、逐栋房子去找,确保不遗漏任何一家(相当于对所有数据行进行遍历)。

在决定采取哪种策略之前,光头强要考虑以下几个因素:

- 地址簿是否最新且准确,能否有效减少寻找时间?

- 包裹目的地分布是否有规律,使用地址簿能否大大减少走冤枉路的概率?

- 如果不用地址簿,逐户查找的总距离有多长?

基于这些信息,光头强(查询优化器)会选择预期耗时最少、效率最高的配送策略。同样地,在MySQL中,查询优化器也会根据表的统计信息、索引的存在与否及有效性等因素,来判断采用索引扫描还是全表扫描,或者其他更复杂的查询执行路径,以达到最快的查询速度和最少的系统资源消耗。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1028240.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux vim用法

在命令模式下,点i 进入输入模式 输入模式下:通过箭头可以实现左右上下移动 o是从新起下一行开始写 O是新起上一行开始写 $是到此行的末尾 0是到此行的开头 gg是到第一行 yy是复制此行,p是粘贴 dd是删除此行 u是撤销 Ctrl r是反向撤…

边缘计算网关在机械制造企业的应用效果和价值-天拓四方

随着智能制造行业的飞速发展,数据量的激增和实时性要求的提高,传统的数据处理方式已经难以满足生产需求。而边缘计算网关的出现,为智能制造行业带来了革命性的变化。下面,我们将通过一个具体案例展示边缘计算网关在智能制造行业的…

pycharm使用远程服务器的jupyter环境

1、确保服务器上安装了jupyter,如果没有,执行下面命令安装 pip install jupyter2、启动jupyter notebook服务 jupyter notebook --no-browser --port8888 --ip0.0.0.0 --allow-root表明在服务器的8888 端口上启动 Jupyter Notebook,并允许从任何 IP 地…

手动实现一个扩散模型DDPM

扩散模型是目前大部分AIGC生图模型的基座,其本质是用神经网络学习从高斯噪声逐步恢复图像的过程,本文用python代码从零开始构建了一个简单的扩散模型。 理论部分 DDPM(Denoising Diffusion Probabilistic Models) 是一种在生成对抗网络等技术的基础上发展…

阿里云OSS存储的视频如何加水印

OSS是不能进行视频添加水印的,可以图片添加水印。 您可以在视频点播中进行配置: https://help.aliyun.com/zh/vod/user-guide/video-watermarks?spma2c4g.11186623.0.i2 原来的业务代码都是使用python 对oss的 视频进行上传 的,上传的视频路径已经保存到…

小米汽车正式发布:开启智能电动新篇章

随着科技的不断进步,汽车产业正经历着前所未有的变革。智能电动汽车作为这一变革的重要方向,正吸引着越来越多的目光。在这个充满机遇和挑战的时代,小米汽车凭借其卓越的技术实力和深厚的市场底蕴,终于迈出了坚实的一步。今天&…

计算机网络:传输控制协议(Transmission Control Protocol-TCP协议

计算机网络:传输控制协议(Transmission Control Protocol-TCP协议) 本文目的前置知识点TCP协议简介主要特性通信流程1. 建立连接的过程(三次握手,243)1.1 为什么要三次握手,两次不行吗? 2. 释放连接的过程(…

Java基础语法(二)

前言 Hello,大家好!很开心与你们在这里相遇,我是一个喜欢文字、喜欢有趣的灵魂、喜欢探索一切有趣事物的女孩,想与你们共同学习、探索关于IT的相关知识,希望我们可以一路陪伴~ 1. 类型转换 1.1 自动类型转换 什么是自…

RabbitMQ3.x之三_RabbitMQ新建用户及开启远程访问

RabbitMQ3.x之三_RabbitMQ新建用户及开启远程访问 文章目录 RabbitMQ3.x之三_RabbitMQ新建用户及开启远程访问1. guest不能远程访问2. 创建专有用户远程访问RabbitMQ1. 创建用户2. 给用户分配tag(角色)3. 开启远程访问 3. 新用户远程登录 1. guest不能远程访问 在 RabbitMQ 中&…

网络爬虫框架Scrapy的入门使用

Scrapy的入门使用 Scrapy概述引擎(Engine)调度器(Scheduler)下载器(Downloader)SpiderItem Pipeline 基本使用安装scrapy创建项目定义Item数据模型对象创建爬虫(Spider)管道pipeline来保存数据启动爬虫 其他…

利用lidar生成深度图

前言 目前,深度图像的获取方法有:激光雷达深度成像法、计算机立体视觉成像、坐标测量机法、莫尔条纹法、结构光法等。针对深度图像的研究重点主要集中在以下几个方面:深度图像的分割技术,深度图像的边缘检测技术,基于…

python的神奇bug2

今天测试出一个很诡异的bug, 这个错误还真的很难发现 测试1 a [1,10,100] for i in a:print(i)if(i10):a[20,30,-1]一般来说我们在进行迭代时,a这个值时不能改动的,但是现在的问题时如果我不小心给改动了呢,结果如下 也就是说…

文本文件操作

大家好&#xff1a; 衷心希望各位点赞。 您的问题请留在评论区&#xff0c;我会及时回答。 文件操作 程序运行时&#xff0c;产生的数据都是临时数据&#xff0c;程序一旦运行结束都会被释放。通过文件可以将数据持久化。 C中对文件进行操作需要包含头文件<fstream> 文件…

关于深度学习的 PyTorch 项目如何上手分析?从什么地方切入?

文章目录 PyTorch 项目分析1.背景2.分析流程 PyTorch 项目分析 1.背景 当我们拿到一个 PyTorch 的深度学习项目时&#xff0c;应该怎么入手&#xff1f;怎么去查看代码&#xff1f; 2.分析流程 首先阅读对应项目的 README.md 文件。通过阅读 README.md &#xff0c;一般可以…

【Redis面试题】Redis 的大 Key 对持久化有什么影响?

目录 大 Key 对 AOF 日志的影响大 Key 对 AOF 重写和 RDB 的影响总结 Redis 的持久化方式有两种&#xff1a;AOF 日志和 RDB 快照。 所以接下来&#xff0c;针对这两种持久化方式具体分析分析。 大 Key 对 AOF 日志的影响 先说说 AOF 日志三种写回磁盘的策略 Redis 提供了 3 …

记录在项目中引用本地的npm包

1、先把需要的包下载下来&#xff0c;以Photo Sphere Viewer 为引用的npm包、项目以shpereRepo为例子 git clone https://github.com/mistic100/Photo-Sphere-Viewer2、拉下代码后修改之后执行 ./build.sh build.sh #!/usr/bin/env bashyarn run build targetDir"../sh…

HarmonyOS 应用开发之UIAbility组件间交互(设备内)

UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时&#xff0c;会涉及到启动特定的UIAbility&#xff0c;该UIAbility可以是应用内的其他UIAbility&#xff0c;也可以是其他应用的UIAbility&#xff08;例如启动三方支付UIAbility&#xff09;。 本文将从如下场景…

Etcd 基本入门

1&#xff1a;什么是 Etcd ? Etcd 是 CoreOS 团队于2013年6月发起的开源项目&#xff0c;它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法&#xff0c;Etcd基于 Go 语言实现。 名字由来&#xff0c;它源于两个方面&#xff0c;…

面试笔记——MyBatis(执行流程、延迟加载和缓存)

MyBatis 是一个持久层框架&#xff0c;用于简化 Java 应用程序与数据库之间的交互过程。具体而言&#xff0c;它提供了一种将数据库操作映射到 Java 方法的方式&#xff0c;通过 XML 文件或注解配置 SQL 语句与 Java 方法的映射关系。使用 MyBatis&#xff0c;开发人员可以通过…

YOLOV8逐步分解(2)_DetectionTrainer类初始化过程

接上篇文章yolov8逐步分解(1)--默认参数&超参配置文件加载继续讲解。 1. 默认配置文件加载完成后&#xff0c;创建对象trainer时&#xff0c;需要从默认配置中获取类DetectionTrainer初始化所需的参数args&#xff0c;如下所示 def train(cfgDEFAULT_CFG, use_pythonFalse…