mysql gt resource_实用干货,MYSQL这么用就对啦

27fd1b10d42de4ebd61a710a8b4f5d9f.png

本文主要梳理了 SQL 的基础用法,会涉及到以下方面内容:

SQL大小写的规范数据库的类型以及适用场景SELECT 的执行过程WHERE 使用规范MySQL 中常见函数子查询分类如何选择合适的 EXISTS 和 IN子查询

d4461ddd3ccdb32c8445eaec46da0cb6.png

了解 SQL

SQL 是我们用来和数据打交道的方式之一,如果按照功能划分可分为如下 4 个部分:

DDL,数据定义语言。定义数据库对象,数据表,数据列。也就是,对数据库和表结构进行增删改操作。DML,数据操作语言。对数据表的增删改。DCL,数据控制语言。定义访问权限和安全级别。DQL,数据查询语言。用来查询数据。

平时在编写 SQL 时,可能发现许多 SQL 大小写不统一,虽然不会影响 SQL 的执行结果,但保持统一的书写规范,是提高效率的关键,通常遵循如下的原则:

表名,表别名,字段名,字段别名等用小写。SQL 保留字,函数名,绑定变量等用大写。数据表,字段名采用下划线命名。

目前排名较前的 DBMS:

b167352ebd304b279c74970208c968d8.png

关系型数据库:建立在关系模型上的数据库,在建表时,通常先设计 ER 图表示之间的关系。键值型数据库:以 key-value 的形式存储数据,优点是查找速度快,缺点是无法像关系型数据库一样使用如 WHERE 等的过滤条件。常见场景是作为内容缓存。文档型数据库,在保存时以文档作为处理信息的基本单位。搜索引擎:针对全文检索而设计。核心原理是 “倒排索引”。列式数据库:相对于如 MySQL 等行式存储的数据库,是以列将数据存在数据库中,由于列具有相同的数据类型,所以可以更好的压缩,从而减低系统的 I/O,适用于分布式文件系统,但功能相对有限。图形数据库,利用图的数据结构存储实体之间的关系。比如社交网络中人与人的关系,数据模型为节点和边来实现。认识SELECTSELECT一般是在学习SQL接触的第一个关键字,基础的内容就不提了,这里整理常用的规范:起别名SELECTnameAS n FROM student查询常数, 增加一列固定的常数列:SELECT'学生信息'as student_info, nameFROM student去重重复行SELECTDISTINCT age FROM student需要注意的是DISTINCT是对后面的所有列进行去重,下面这种情况就会对age和name的组合进行去重。SELECTDISTINCT age,nameFROM student排序数据,ASC代表升序,DESC代表降序如先按照name排序,name相等的情况下按照age排序。SELECTDISTINCT age FROM student ORDERY BYname,age DESC限制返回的数量SELECTDISTINCT age FROM student ORDERY BYnameDESCLIMIT5SELECT 的执行顺序了解了SELECT的执行顺序,才能更好地写出更有效率的 SQL。对于SELECT顺序有两个原则:关键字的顺序不能颠倒:SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...SELECT会按照如下顺序执行:FROM > WHERE > GROUP BY > HAVING > SELECT的字段 > DISTINCT > ORDER BY > LIMIT

SELECTDISTINCT student_id, name, count(*) asnum#顺序5FROM student JOIN class ON student.class_id = class.class_id #顺序1WHERE age > 18 #顺序2GROUP BY student.class_id #顺序3HAVING num > 2 #顺序4ORDER BY num DESC #顺序6LIMIT 2 #顺序7

在逐一分析下这个过程前,我们需要知道在上面的每一个步骤中都会产生一个虚拟表,然后将这个虚拟表作为下一个步骤中作为输入,但这一过程对我们来说是不可见的:

从FROM语句开始,对student和class表进行CROSS JOIN 笛卡尔积运算,得到虚拟表 vt 1-1;通过 ON 筛选,在 vt1-1 的基础上进行过滤然后得到表 vt 1-2;添加外部行。如使用左连接,右连接和全连接时,就会涉及到外部行,会在 vt1-2 的基础上增加外部行,得到 vt1-3。如果超过两张表,就会重复上面的步骤。在拿到最终的 vt1 的表数据后,会执行 WHERE 后面的过滤阶段,得到表 vt2.接着到 GROUP 阶段,进行分组得到 vt3.接着到 HAVING 阶段,对分组的数据进行过滤,得到 vt4.后面进入 SELECT 阶段,提取需要的字段,得到 vt5-1,接着通过 DISTINCT 阶段,过滤到重复的行,得到 vt5-2.然后对指定的字段进行排序,进入 ORDER BY 阶段,得到 vt6.最后在 LIMIT 阶段,取出指定的行,对应 vt7,也就是最后的结果。如果涉及到函数的计算比如 sum() 等,会在 GROUP BY分组后,HAVING 分组前,进行聚集函数的计算。涉及到表达式计算,如 age * 10 等,会在 HAVING 阶段后,SELECT 阶段前进行计算。

通过这里,就可以总结出提高 SQL 效率的第一个方法:

使用 SELECT 时指定明确的列来代替 SELECT * . 从而减少网络的传输量。使用 WHERE 进行过滤

使用 WHERE 筛选时,常有通过比较运算符,逻辑运算符,通配符三种方式。

对于比较运算符,常用的运算符如下表。

1a2dbafaafa6d94ff2eb8fd66d1d6d83.png

对于逻辑运算符来说,可以将多个比较运行符连接起来,进行多条件的筛选,常用的运算符如下:

001fad26760b55523624b5156bdc4487.png

需要注意的是,当AND和OR同时出现时,AND的优先级更高会先被执行。当如果存在 () 的话,则括号的优先级最高。使用通配符过滤:like:(%)代表零个或多个字符,(_)只代表一个字符函数和编程语言中的定义的函数一样,SQL同样定义了一些函数方便使用,比如求和、平均值、长度等。常见的函数主要分为如下四类,分类的原则是根据定义列时的数据类型:算术函数:

f0500f5841c36afa547a19501549b2fc.png

字符串函数

ab846580e7aa018e5239048cfdcf2a6c.png

需要注意的是,在使用字符串比较日期时,要使用DATE函数比较。日期函数

9a13b2dee78b90a7312dda1b9329a558.png

转换函数:

2172332acfa4e012a02a462eca829be4.png

CAST函数在转换数据类型时,不会四舍五入,如果原数值是小数,在转换到整数时会报错。在转换时可以使用DECIMAL(a,b) 函数来规定小数的精度,比如DECIMAL(8,2) 表示精度为8 位 - 小数加整数最多 8 位。小数后面最多为 2 位。然后通过 SELECT CAST(123.123 AS DECIMAL(8,2)) 来转换。聚集函数通常情况下,我们会使用聚集函数来汇总表的数据,输入为一组数据,输出为单个值。常用的聚集函数有 5 个:

ce4baf7abc409fea0aa84d59535d97da.png

如何进行分组在统计结果时,往往需要对数据按照一定条件进行分组,对应就是GROUP BY语句。比如统计每个班级的学生人数:SELECT class_id, COUNT(*) as student_count FROM student \GROUPBY class_id;GROUP BY 后也可接多个列名,进行分组,比如按照班级和性别分组:SELECT class_id, sex, COUNT(*) as student_count FROM \student GROUPBY class_id, sex;HAVING 过滤和 WHERE 的区别和 WHERE 一样,可以对分组后的数据进行筛选。区别在于 WHERE 适用于数据行,HAVING 用于分组。而且 WHERE 支持的操作,HAVING 也同样支持。比如可以筛选大于2人的班级:SELECT class_id, COUNT(*) as student_count FROM student \ GROUPBY class_id \ HAVING student_count > 20;子查询在一些更为复杂的情况中,往往会进行嵌套的查询,比如在获取结果后,该结果作为输入,去获取另外一组结果。在 SQL 中,查询可以分为关联子查询和非关联子查询。假设有如下的表结构:-- ----------------------------DROP TABLE IF EXISTS `student`;CREATE TABLE `student` (`id`int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) NOT NULL DEFAULT '',`age`int(3) NOT NULL,`sex` varchar(10) NOT NULL DEFAULT '',`class_id`int(11) NOT NULL COMMENT '班级ID', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;-- ------------------------------ Records of Student-- ----------------------------INSERT INTO `student` VALUES ('1', '胡一', 13, '男', '1');INSERT INTO `student` VALUES ('3', '王阿', 11, '女', '1');INSERT INTO `student` VALUES ('5', '王琦', 12, '男', '1');INSERT INTO `student` VALUES ('7', '刘伟', 11, '女', '1');INSERT INTO `student` VALUES ('7', '王意识', 11, '女', '2');-- ----------------------------DROP TABLE IF EXISTS `student_activities`;CREATE TABLE `student_activities` (`id`int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) NOT NULL DEFAULT '',`stu_id`int(11) NOT NULL COMMENT '班级ID', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;INSERT INTO `student_activities` VALUES ('1', '博物馆', 1);INSERT INTO `student_activities` VALUES ('3, '春游', 3);非关联子查询子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件接着执行。这里想要查询和胡一相同班级的同学名称:SELECTnameFROM student WHERE class_id = \(SELECT class_id FROM student WHEREname='胡一')这里先查到胡一的班级,只有一次查询,再根据该班级查找学生就是非关联子查询。关联子查询如果子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部再举个例子, 比如查询比每个班级中比平均年龄大的学生姓名信息:SELECTnameFROM student as s1 WHERE age > (SELECTAVG(age) FROM student as s2 where s1.class_id = s2.class_id)这里根据每名同学的班级信息,查找出对应班级的平均年龄,然后做判断。子查询每次执行时,都需要根据外部的查询然后进行计算。这样的子查询就是关联子查询。EXISTS子查询在关联子查询中,常会和EXISTS 一起使用。用来判断条件是否满足,满足的话为True,不满足为 False。比如查询参加过学校活动的学生名称:SELECTNAMEFROM student as s where \EXISTS(SELECT stu_id FROM student_activities as sa where sa.stu_id=s.id)同样NOT EXISTS就是不存在的意思,满足为FALSE , 不满足为True.比如查询没有参加过学校活动的学生名称:SELECTNAMEFROM student as s where \NOTEXISTS(SELECT stu_id FROM student_activities as sa where sa.stu_id=s.id)集合比较子查询可以在子查询中,使用集合操作符,来比较结果。

4d7b821f7717bf1b75700333d4605004.png

还是上面查询参加学校活动的学生名字的子查询, 同样可以使用 IN:SELECTnameFROM student WHEREidIN (SELECT stu_id FROM student_activities)EXISTS 和 IN 的区别既然 EXISTS 和 IN 都能实现相同的功能,那么他们之间的区别是什么?现在假设我们有表A和表B,其中 A、B 都有字段 cc,并对 cc 建立了 b+ 索引,其中 A 表 n 条记录,B 表 m 条索引。将其模式抽象为:SELECT * FROM A WHERE cc IN (SELECT cc FROM B)SELECT * FROM A WHERE EXIST (SELECT cc FROM B WHERE B.cc=A.cc)对于 EXISTS 来说,会先对外表进行逐条循环,每次拿到外表的结果后,带入子查询的内表中,去判断该值是否存在。伪代码类似于下面:for i in Afor j in Bif j.cc == i.cc:return result首先先看外表 A,每一条都需要遍历到,所以需要 n 次。内表 B,在查询时由于使用索引进而查询效率变成 log(m) B+ 的树高,而不是 m。进而总效率:n * log(m)所以对于 A 表的数量明显小于 B 时,推荐使用 EXISTS 查询。再看 IN ,会先对内表 B 进行查询,然后用外表 A 进行判断,伪代码如下:for i in Bfor j in Aif j.cc == i.cc:return result由于需要首先将内表所有数据查出,所以需要的次数就是 m. 再看外表 A ,由于使用了 cc 索引,可将 n 简化至 log(n), 也就是 m * log(n).所以对于 A 表的数据明显大于 B 表时,推荐使用 IN 查询。总结一下对于 IN 和 EXISTS时,采用小表驱动大表的原则。这里再扩展下 NOT EXISTS 和 NOT IN 的区别:SELECT * FROM A WHERE cc NOTIN (SELECT cc FROM B) SELECT * FROM A WHERENOT EXIST (SELECT cc FROM B WHERE B.cc=A.cc)对于 NOT EXITS 来说,和 EXISTS 一样,对于内表可以使用 cc 的索引。适用于 A 表小于 B 表的情况。但对于 NOT IN 来说,和 IN 就有区别了,由于 cc 设置了索引 cc IN (1, 2, 3) 可以转换成 WHERE cc=1 OR cc=2 OR cc=3 , 是可以正常走 cc 索引的。但对于 NOT IN 也就是转化为 cc!=1 OR cc!=2 OR cc!=3 这时由于是不等号查询,是无法走索引的,进而全表扫描。也就是说,在设置索引的情况下 NOT EXISTS 比 NOT IN 的效率高。但对于没有索引的情况,IN 和 OR 是不同的:一、操作不同1、in:in是把父查询表和子查询表作hash连接。2、or:or是对父查询表作loop循环,每次loop循环再对子查询表进行查询。二、适用场景不同1、in:in适合用于子查询表数据比父查询表数据多的情况。2、or:or适合用于子查询表数据比父查询表数据少的情况。三、效率不同1、in:在没有索引的情况下,随着in后面的数据量越多,in的执行效率不会有太大的下降。2、or:在没有索引的情况下,随着or后面的数据量越多,or的执行效率会有明显的下降。总结这篇文章中主要归纳了一些 SQL 的基础知识:在使用 SELECT 查询时,通过显式指定列名,来减少 IO 的传输,从而提高效率。并且需要注意 SELECT 的查询过程会从 FROM 后开始到 LIMIT 结束,理解了整体的流程,可以让我们更好的组织 SQL.之后详细介绍了 WHERE 进行过滤的操作符和常用的函数,这里要注意在比较时间时要使用 DATE 函数,以及如何对数据进行分组和过滤。最后着重介绍了子查询,IN 和 EXISTS 的适用场景。

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

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

相关文章

python 查看当前目录_Python学习第156课--ls的运用、环境变量以及PATH

【每天几分钟,从零入门python编程的世界!】之前简单的介绍了Linux中几个简单的命令。这节再深入一点介绍下 ls 的运用。lsls相当于是list的简写,它的作用是把我们当前目录中的文件列举出来。ls -l把当前目录下的文件以及它的具体信息列举出来…

python对数组的操作_Python对数组的基本操作

# codingutf-8Created on 2014-3-29author: Administrator创建并打印数组arr ["aex", "bfe", "mpilgrim", "zddd", "example"];print(arr);#[aex, bfe, mpilgrim, zddd, example]print(arr[2]);#mpilgrim数组的负索引li[-n…

莫烦python博客_《莫烦Python》笔记 -- numpy部分

个人感觉,在numpy里,从说法上,数组与矩阵可以互换1.1 numpy & pandas有什么用?1.2 numpy & pandas的安装安装Anaconda2.1 numpy属性import numpy as np# 将一个列表转化为矩阵array np.array([[1,2,3],[2,3,4]])# 查看矩…

java 内存情况_java查看jvm内存使用情况

java查看jvm内存使用情况(2012-03-22 15:50:54)标签:jvm内存虚拟机分配itjava.lang.Runtime类提供了查看当前JVM内存的使用情况。每个java实例(即虚拟机实例)只有一个Runtime的实例,通过Runtime.getRuntime()可以得到当前虚拟机中的Runtime实例对象。Run…

java 密码生成器_Java课程设计-随机密码生成器

1.团队课程设计博客链接2.个人负责模板设计程序运行界面,数据的输入,判断数据输入类型的错误,判断密码类型是否选择。3.自己的代码提交记录截图4自己负责模块或任务详细说明(一)总体设计1.系统主要功能(1)输入生成密码长度;(2)判断…

pyecharts本地文件_python数据可视化-pyecharts插件使用文档

pyecharts是百度开源的可视化插件,可以将设计的可视化图表以html格式保存,配合jupyter可以一键生成动态的html数据分析报告。pyecharts和matplotlib的区别在于,pyecharts有更加强大交互的可视化和嵌入html的功能,pyecharts缺点在于…

gdal获取像元的灰度值java_GDAL利用地理坐标读取图像像元值

最近的一个项目需要在电子海图中下载已知水深点,导出点的地理坐标(经纬度)。然后在arcgis中打开这些地理坐标输出为shp,利用GDAL读取不同波段的点对应的像元值,从而构建水深和像元值的对应关系。其实想要根据经纬度得到像元值有两种方法。1.通…

kibana java script_Elasticsearch:创建 Runtime field 并在 Kibana 中使用它 - 7.11 发布 - TGCode...

在之前的文章 “Elasticsearch:使用 Runtime fields 对索引字段进行阴影处理以修复错误 – 7.11 发布”,我展示了如何使用 runtime field 来 shadow 一个已有的在 mapping 中的字段,比如 duration。在今天的练习中,我将展示如何创…

java根据uml图写出实现代码,根据java代码生成UML图

根据java代码生成UML图根据java代码生成UML图这里介绍一个简单易用的eclipse插件ModelGoon,用来对已有代码生成UML图,下面以之前文章中的spring mvc工程为例如何安装和使用这个插件;这个spring mvc工程的代码在githbu上,地址是&am…

highcharts php 动态数据,php动态传数据到highcharts的方法

本文主要介绍了通过php动态传数据到highcharts的相关知识。具有很好的参考价值。1:在平时工作中,在对数据进行展示的时候,是直接通过后台提供的接口来获取json串,用来展示。今天别人问怎么在本地演示一下请求的动态数据。2&#x…

php tar.gz文件,PHP解压tar.gz格式文件的方法,_PHP教程

PHP解压tar.gz格式文件的方法,本文实例讲述了PHP解压tar.gz格式文件的方法。分享给大家供大家参考,具体如下:1、运用php自带压缩与归档扩展(phar)$phar new PharData(song.tar.gz);//路径 要解压的文件 是否覆盖$phar->extractTo(c:/tmp,…

创建数组表格PHP苹果价格,如何从PHP数组创建HTML表?

Cats萌萌这是我的&#xff1a;<?php function build_table($array){ // start table $html . htmlspecialchars($key) . . htmlspecialchars($value2) .

python打包exe报错编码问题,使用Python打包含有pymssql成exe所躺的坑

一、如何打包Python打包exe文件简单运用pyinstaller库就行了1)安装pyinstaller库(自行安装)2)winR打开运行窗口输入“powershell”3)输入pyinstaller -F 路径\文件名.py(打包py文件的路径&#xff0c;py不能省略)看到successfully即为打包成功&#xff0c;但不一定能运用的&…

php超大树形分页,PHP+MySql千万级数据limit分页优化方案

PHPMySql千万级数据limit分页优化方案1年前阅读 2750评论 0喜欢 0### 原因徒弟突然有个需求&#xff0c;就是他发现limit分页&#xff0c;页数越大之后&#xff0c;mysql的消耗越大&#xff0c;查询时间越长&#xff0c;当突破百万级数据之后&#xff0c;一个简单的翻页都需要5…

linux自启动配置文件,Linux中如何设置服务自启动?

有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务&#xff0c;主要用三种方式进行这一操作&#xff1a;ln -s 在/etc/rc.d/rc*.d目录中建立/etc/init.d/服务的软链接(*代表0&#xff5e;6七个运行级别之一)chkonfig 命令行运行级别设置nts…

linux系统下升级node,linux下安装指定版本的nodejs(升级到指定版本)

原因最近需要全栈开发但是服务器是linux系统&#xff0c;服务本身通过yum安装软件包&#xff0c;不过yum安装的nodejs版本太低。所以需要自己安装。方案下载编译好的文件解压后直接运行即可&#xff0c;不过我们需要全局运行node命令。只需要把目录设置为全局即可(建立软链接 l…

Linux bash卸载软件,Ubuntu卸载软件的4种方法

前言本文重点介绍Ubuntu卸载软件的4种方法。他们分别是图形化界面的synaptic、自动解决依赖关系的apt-get&#xff0c;处理依赖关系更强大的aptitude&#xff0c;还有安装本地deb包的dpkg。方法一: Ubuntu使用synaptic图形化界面管理软件oucanrongzcwyou:~$ sudo apt-get insta…

linux系统atom安装教程,Ubuntu/Linux Mint上安装Atom文本编辑器

Atom是一款由Github开发的开源文本编辑器&#xff0c;虽然目前该软件依然在Beta阶段&#xff0c;但我们依然可以在你的Ubuntu/Linux Mint上使用它。据Atom官方博客介绍&#xff0c;与Atom类似的编辑器Sublime和TextMate都深受开发者欢迎&#xff0c;但在扩展性上都有所限制&…

labview 远程连接linux,SSH交互式通信总结:expect、plink、putty、sshpass、ALAB SSH

关于在linux脚本中远程执行命令的问题&#xff0c;笔者在以前文章中可以使用expect工具来完成交互式通信。在windows平台下可以使用plink或者putty工具。免密也可以设置SSH秘钥&#xff0c;参考文章-Linux怎么远程执行指令呢-SSH秘钥。但是在linux下需要一一对应设置&#xff0…

tcping在linux用法,tcping的安装和使用

Tcping 网上比较少资料是关于linux对tcp端口ping测试的方法&#xff0c;我这里简单介绍2种方法&#xff1a; 1.yum安装&#xff0c;编译安装方法 1-1.wget http://linuxco.de/tcping/tcping-1.3.5.tar.gz ###下载tcping1-2 tar zxvf tcping-1.3.5.tar.gz ####解压缩tcping-1.3.…