MySQL学习(一)

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: MySQL学习

MySQL数据库笔记

第一部分 MySQL基础篇

第01章 数据库概述

1. 为什么要使用数据库

  • 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以“固化”,而持久化的实现过程大多通过各种关系数据库来完成。
  • 持久化的主要作用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。

2. 数据库与数据库管理系统

2.1 数据库的相关概念
  • DB:数据库(Database)
  • 即存储数据的“仓库”,其本质是一个文件系统。它保存了一系列有组织的数据。
  • DBMS:数据库管理系统(Database Management System)
  • 是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制。用户通过数据库管理系统访问数据库中表内的数据。
  • SQL:结构化查询语言(Structured Query Language)
  • 专门用来与数据库通信的语言。

3. RDBMS与非RDBMS

3.1 关系型数据库(RDBMS)
3.1.1 实质
  • 这种类型的数据库是最古老的数据库类型,关系型数据库模型是把复杂的数据结构归结为简单的二元关系 (即二维表格形式)。
  • 关系型数据库以行(row)列(column)的形式存储数据,以便于用户理解。这一系列的行和列被称为表(table),一组表组成了一个库(database)
  • SQL就是关系型数据库的查询语言。
3.1.2 优势
  • 复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
  • 事务支持使得对于安全性能很高的数据访问要求得以实现。
3.2 非关系型数据库(非RDBMS)
3.2.1 介绍

非关系型数据库,可看成传统关系型数据库的功能阉割版本,基于键值对存储数据,不需要经过SQL层的解析,性能非常高。同时,通过减少不常用的功能,进一步提高性能。

4. 关系型数据库设计规则

  • 一个数据库中可以有多个表,每个表都有一个名字,用来标识自己。表名具有唯一性。
  • 表具有一些特性,这些特性定义了数据在表中如何存储,类似Java和Python中 “类”的设计。
4.1 表、记录、字段
  • E-R(entity-relationship,实体-联系)模型中有三个主要概念是:实体集属性联系集
  • 一个实体集(class)对应于数据库中的一个表(table),一个实体(instance)则对应于数据库表中的一行(row),也称为一条记录(record)。一个属性(attribute)对应于数据库表中的一列(column),也称为一个字段(field)。
4.2 表的关联关系
  • 表与表之间的数据记录有关系(relationship)。现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。
  • 四种:一对一关联、一对多关联、多对多关联、自我引用

第02章 MySQL环境搭建(略)

1. MySQL演示使用

1.1 MySQL的编码设置

MySQL5.7中

问题再现:命令行操作sql乱码问题

mysql> INSERT INTO t_stu VALUES(1,'张三','男');
ERROR 1366 (HY000): Incorrect string value: '\xD5\xC5\xC8\xFD' for column 'sname' at row 1

问题解决

步骤1:查看编码命令

show variables like 'character_%';
show variables like 'collation_%';

步骤2:修改mysql的数据目录下的my.ini配置文件

default-character-set=utf8 #默认字符集 [mysqld]
# 大概在76行左右,在其下添加
...
character-set-server=utf8
collation-server=utf8_general_ci

步骤3:重启服务

步骤4:查看编码命令

show variables like 'character_%';
show variables like 'collation_%';

MySQL8.0中

在MySQL 8.0版本之前,默认字符集为latin1,utf8字符集指向的是utf8mb3。网站开发人员在数据库设计的时候往往会将编码修改为utf8字符集。如果遗忘修改默认的编码,就会出现乱码的问题。从MySQL 8.0开始,数据库的默认编码改为utf8mb4,从而避免了上述的乱码问题。

问题1:root用户密码忘记,重置的操作

1: 通过任务管理器或者服务管理,关掉mysqld(服务进程)

2: 通过命令行+特殊参数开启mysqld mysqld -- defaults-file="D:\ProgramFiles\mysql\MySQLServer5.7Data\my.ini" --skip-grant-tables

3: 此时,mysqld服务进程已经打开。并且不需要权限检查

4: mysql -uroot 无密码登陆服务器。另启动一个客户端进行

5: 修改权限表 (1) use mysql; (2)update user set authentication_string=password('新密码') where user='root' and Host='localhost'; (3)flush privileges;

6: 通过任务管理器,关掉mysqld服务进程。

7: 再次通过服务管理,打开mysql服务。

8: 即可用修改后的新密码登陆。

问题2:mysql命令报“不是内部或外部命令”

如果输入mysql命令报“不是内部或外部命令”,把mysql安装目录的bin目录配置到环境变量path中。

问题3: No database selected

解决方案一:就是使用“USE 数据库名;”语句,这样接下来的语句就默认针对这个数据库进行操作

解决方案二:就是所有的表对象前面都加上“数据库.”

问题4:命令行客户端的字符集问题

mysql> INSERT INTO t_stu VALUES(1,'张三','男');
ERROR 1366 (HY000): Incorrect string value: '\xD5\xC5\xC8\xFD' for column 'sname' at row 1

查看所有字符集:SHOW VARIABLES LIKE 'character_set_%';

解决方案,设置当前连接的客户端字符集 SET NAMES GBK;

问题5:修改数据库和表的字符编码

修改编码:

(1)先停止服务,(2)修改my.ini文件(3)重新启动服务

说明:

如果是在修改my.ini之前建的库和表,那么库和表的编码还是原来的Latin1,要么删了重建,要么使用alter语句修改编码。

mysql> create database 0728db charset Latin1;
Query OK, 1 row affected (0.00 sec)
mysql> use 0728db;
Database changed
mysql> show create table student\G
*************************** 1. row ***************************
Table: student 
Create Table: CREATE TABLE `student` ( `id` int(11) NOT NULL, `name` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
mysql> alter table student charset utf8; #修改表字符编码为UTF8
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table student\G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` ( `id` int(11) NOT NULL, `name` varchar(20) CHARACTER SET latin1 DEFAULT NULL, #字段仍然是latin1编码 PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> alter table student modify name varchar(20) charset utf8; #修改字段字符编码为UTF8
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
                                      
mysql> show create table student\G
*************************** 1. row ***************************
Table: student 
Create Table: CREATE TABLE `student` ( `id` int(11) NOT NULL, `name` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
mysql> show create database 0728db;
+--------+-----------------------------------------------------------------+
|Database| Create Database |
+------+-------------------------------------------------------------------+
|0728db| CREATE DATABASE `0728db` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+------+-------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter database 0728db charset utf8; #修改数据库的字符编码为utf8
Query OK, 1 row affected (0.00 sec)

第03章 基本的SELECT语句

1. SQL概述

1.1 SQL分类
  • DDL:数据定义语言。CREATE \ ALTER \ DROP \ RENAME \ TRUNCATE
  • DML:数据操作语言。INSERT \ DELETE \ UPDATE \ SELECT (重中之重)
  • DCL:数据控制语言。COMMIT \ ROLLBACK \ SAVEPOINT \ GRANT \ REVOKE

2. SQL语言的规则与规范

2.1 基本规则
  • SQL 可以写在一行或者多行。为了提高可读性,各子句分行写,必要时使用缩进
  • 每条命令以 ; 或 \g 或 \G 结束
  • 关键字不能被缩写也不能分行
  • 关于标点符号
  • 必须保证所有的()、单引号、双引号是成对结束的
  • 必须使用英文状态下的半角输入方式
  • 字符串型和日期时间类型的数据可以使用单引号(' ')表示
  • 列的别名,尽量使用双引号(" "),而且不建议省略as
2.2 SQL大小写规范 (建议遵守)
  • MySQL在Windows环境下是大小写不敏感的
  • MySQL在Linux环境下是大小写敏感的
  • 数据库名、表名、表的别名、变量名是严格区分大小写的
  • 关键字、函数名、列名(或字段名)、列的别名(字段的别名) 是忽略大小写的。
  • 推荐采用统一的书写规范:
  • 数据库名、表名、表别名、字段名、字段别名等都小写
  • SQL 关键字、函数名、绑定变量等都大写
2.3 注 释
单行注释:#注释文字(MySQL特有的方式)
单行注释:-- 注释文字(--后面必须包含一个空格。)
多行注释:/* 注释文字 */
2.4 命名规则(暂时了解)
  • 数据库、表名不得超过30个字符,变量名限制为29个
  • 必须只能包含 A–Z, a–z, 0–9, _共63个字符
  • 数据库名、表名、字段名等对象名中间不要包含空格
  • 同一个MySQL软件中,数据库不能同名;同一个库中,表不能重名;同一个表中,字段不能重名
  • 必须保证你的字段没有和保留字、数据库系统或常用方法冲突。如果坚持使用,请在SQL语句中使用`(着重号)引起来
  • 保持字段名和类型的一致性,在命名字段并为其指定数据类型的时候一定要保证一致性。假如数据类型在一个表里是整数,那在另一个表里可就别变成字符型了
2.5 数据导入指令

在命令行客户端登录mysql,使用source指令导入

mysql> source d:\mysqldb.sql

3. 基本的SELECT语句

3.0 SELECT...
SELECT 1; #没有任何子句
SELECT 1 + 1,3 * 2
FROM DUAL; #dual:伪表
3.1 SELECT ... FROM
  • 语法:
SELECT 标识选择哪些列
FROM 标识从哪个表中选择
  • 选择全部列:
SELECT * 
FROM departments;
  • 选择特定的列:
SELECT department_id, location_id
FROM departments;
3.2 列的别名
  • 重命名一个列
  • 便于计算
  • 紧跟列名,也可以在列名和别名之间加入关键字AS,别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写。
  • AS 可以省略
  • 建议别名简短,见名知意
SELECT last_name AS name, commission_pct comm 
FROM employees;
SELECT last_name "Name", salary*12 "Annual Salary"
FROM employees;
3.3 去除重复行

在SELECT语句中使用关键字DISTINCT去除重复行

SELECT DISTINCT department_id,salary 
FROM employees;

这里有两点需要注意:

  1. DISTINCT需要放到所有列名的前面,如果写成SELECT salary, DISTINCT department_id FROM employees会报错。
  2. DISTINCT其实是对后面所有列名的组合进行去重。如果你想要看都有哪些不同的部门(department_id),只需要写DISTINCT department_id即可,后面不需要再加其他的列名了。
3.4 空值参与运算
  • 所有运算符或列值遇到null值,运算的结果都为null
SELECT employee_id,salary,commission_pct, 12 * salary * (1 + commission_pct) "annual_sal" 
FROM employees;

在 MySQL 里面, 空值不等于空字符串。一个空字符串的长度是 0,而一个空值的长度是空。而且,在 MySQL 里面,空值是占用空间的。

3.5 着重号
  • 错误的
mysql> SELECT * FROM ORDER;
  • 正确的
mysql> SELECT * FROM `ORDER`;
mysql> SELECT * FROM `order`;
  • 结论

我们需要保证表中的字段、表名等没有和保留字、数据库系统或常用方法冲突。如果真的相同,请在SQL语句中使用一对``(着重号)引起来。

3.6 查询常数
SELECT '尚硅谷' as corporation, last_name
FROM employees;

4. 显示表结构

使用DESCRIBE 或 DESC 命令,表示表结构。

DESCRIBE employees;
DESC employees;

5. 过滤数据

  • 语法
  • 使用WHERE 子句,将不满足条件的行过滤掉
  • WHERE子句紧随FROM子句
SELECT 字段1,字段2
FROM 表名
WHERE 过滤条件
  • 举例
SELECT employee_id, last_name, job_id, department_id
FROM employees
WHERE department_id = 90;

第04章 运算符

1. 算术运算符

运算符

名称

作用

实例

+

加法运算符

计算两个值或表达式的和

SELECT A + B

-

减法运算符

计算两个值或表达式的差

SELECT A - B

*

乘法运算符

计算两个值或表达式的乘积

SELECT A * B

/ 或 DIV

除法运算符

计算两个值或表达式的商

SELECT A / B 或者 SELECT A DIV B

% 或 MOD

求模(求余)运算符

计算两个值或表达式的余数

SELECT A % B 或者 SELECT A MOD B

加法与减法运算符结论:

  • 一个整数类型的值对整数进行加法和减法操作,结果还是一个整数;
  • 一个整数类型的值对浮点数进行加法和减法操作,结果是一个浮点数;
  • 加法和减法的优先级相同,进行先加后减操作与进行先减后加操作的结果是一样的;
  • 在Java中,+的左右两边如果有字符串,那么表示字符串的拼接。但是在MySQL中+只表示数值相加。如果遇到非数值类型,先尝试转成数值,如果转失败,就按0计算。(补充:MySQL中字符串拼接要使用字符串函数CONCAT()实现)

乘法与除法运算符结论:

  • 一个数乘以整数1和除以整数1后仍得原数;
  • 一个数乘以浮点数1和除以浮点数1后变成浮点数,数值与原数相等;
  • 一个数除以整数后,不管是否能除尽,结果都为一个浮点数
  • 一个数除以另一个数,除不尽时,结果为一个浮点数,并保留到小数点后4位;
  • 乘法和除法的优先级相同,进行先乘后除操作与先除后乘操作,得出的结果相同。
  • 在数学运算中,0不能用作除数,在MySQL中,一个数除以0为NULL。
# 取模运算: % mod
SELECT 12 % 3,12 % 5, 12 MOD -5,-12 % 5,-12 % -5
FROM DUAL; # 结果的符号只与被模数有关
+--------+--------+-----------+---------+----------+
| 12 % 3 | 12 % 5 | 12 MOD -5 | -12 % 5 | -12 % -5 |
+--------+--------+-----------+---------+----------+
|      0 |      2 |         2 |      -2 |       -2 |
+--------+--------+-----------+---------+----------+

2. 比较运算符

比较运算符用来对表达式左边的操作数和右边的操作数进行比较,比较的结果为真则返回1,比较的结果为假则返回0,其他情况则返回NULL。

运算符

名称

作用

示例

=

等于运算符

判断两个值、字符串或表达式是否相等

SELECT C FROM TABLE WHERE A = B

<=>

安全等于运算符

安全地判断两个值、字符串或表达式是否相等

SELECT C FROM TABLE WHERE A <=> B

<> 或 !=

不等于运算符

判断两个值、字符串或表达式是否不相等

SELECT C FROM TABLE WHERE A <> B

<

小于运算符

判断前面的值、字符串或表达式是否小于后面的值、字符串或表达式

SELECT C FROM TABLE WHERE A < B

<=

小于等于运算符

判断前面的值、字符串或表达式是否小于等于后面的值、字符串或表达式

SELECT C FROM TABLE WHERE A <= B

>

大于运算符

判断前面的值、字符串或表达式是否大于后面的值、字符串或表达式

SELECT C FROM TABLE WHERE A > B

>=

大于等于运算符

判断前面的值、字符串或表达式是否大于等于后面的值、字符串或表达式

SELECT C FROM TABLE WHERE A >= B

等号运算符

  • 等号运算符(=)判断等号两边的值、字符串或表达式是否相等,如果相等则返回1,不相等则返回0。
  • 在使用等号运算符时,遵循如下规则:
  • 如果等号两边的值、字符串或表达式都为字符串,则MySQL会按照字符串进行比较,其比较的是每个字符串中字符的ANSI编码是否相等。
  • 如果等号两边的值都是整数,则MySQL会按照整数来比较两个值的大小。
  • 如果等号两边的值一个是整数,另一个是字符串,则MySQL会将字符串转化为数字进行比较。
  • 如果等号两边的值、字符串或表达式中有一个为NULL,则比较结果为NULL。

安全等于运算符(为NULL而生)

安全等于运算符(<=>)与等于运算符(=)的作用是相似的, 唯一的区别是‘<=>’可以用来对NULL进行判断。在两个操作数均为NULL时,其返回值为1,而不为NULL;当一个操作数为NULL时,其返回值为0,而不为NULL。

不等于运算符

不等于运算符(<>和!=)用于判断两边的数字、字符串或者表达式的值是否不相等,如果不相等则返回1,相等则返回0。不等于运算符不能判断NULL值。如果两边的值有任意一个为NULL,或两边都为NULL,则结果为NULL。

运算符

名称

作用

示例

IS NULL

为空运算符

判断值、字符串或表达式是否为空

SELECT B FROM TABLE WHERE A IS NULL

IS NOTNULL

不为空运算符

判断值、字符串或表达式是否不为空

SELECT B FROM TABLE WHERE A IS NOT NULL

LEAST

最小值运算符

在多个值中返回最小值

SELECT D FROM TABLE WHERE C LEAST(A, B)

GREATEST

最大值运算符

在多个值中返回最大值

SELECT D FROM TABLE WHERE C GREATEST(A, B)

BETWEEN ... AND ...

两值之间的运算符

判断一个值是否在两个值之间

SELECT D FROM TABLE WHERE C BETWEEN A AND B

ISNULL

为空运算符

判断一个值、字符串或表达式是否为空

SELECT B FROM TABLE WHERE A ISNULL

IN

属于运算符

判断一个值是否为列表中的任意一个值

SELECT D FROM TABLE WHERE C IN(A, B)

NOT IN

不属于运算符

判断一个值是否不是一个列表中的任意一个值

SELECT D FROM TABLE WHERE C NOT IN(A, B)

LIKE

模糊匹配运算符

判断一个值是否符合模糊匹配规则

SELECT C FROM TABLE WHERE A LIKE B

REGEXP

正则表达式运算符

判断一个值是否符合正则表达式的规则

SELECT C FROM TABLE WHERE A REGEXPB

RLIKE

正则表达式运算符

判断一个值是否符合正则表达式的规则

SELECT C FROM TABLE WHERE A RLIKEB

空运算符

空运算符(IS NULL或者ISNULL)判断一个值是否为NULL,如果为NULL则返回1,否则返回0。

非空运算符

非空运算符(IS NOT NULL)判断一个值是否不为NULL,如果不为NULL则返回1,否则返回0。

最小值运算符

语法格式为:LEAST(值1,值2,...,值n)。其中,“值n”表示参数列表中有n个值。在有两个或多个参数的情况下,返回最小值。

当参数是整数或者浮点数时,LEAST将返回其中最小的值;当参数为字符串时,返回字母表中顺序最靠前的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。

最大值运算符

语法格式为:GREATEST(值1,值2,...,值n)。其中,n表示参数列表中有n个值。当有两个或多个参数时,返回值为最大值。假如任意一个自变量为NULL,则GREATEST()的返回值为NULL。

当参数中是整数或者浮点数时,GREATEST将返回其中最大的值;当参数为字符串时,返回字母表中顺序最靠后的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。

BETWEEN AND运算符

BETWEEN运算符使用的格式通常为SELECT D FROM TABLE WHERE C BETWEEN A AND B,此时,当C大于或等于A,并且C小于或等于B时,结果为1,否则结果为0。

IN运算符

IN运算符用于判断给定的值是否是IN列表中的一个值,如果是则返回1,否则返回0。如果给定的值为NULL,或者IN列表中存在NULL,则结果为NULL。

NOT IN运算符

NOT IN运算符用于判断给定的值是否不是IN列表中的一个值,如果不是IN列表中的一个值,则返回1,否则返回0。列表中存在NULL,则结果为NULL。

LIKE运算符

LIKE运算符主要用来匹配字符串,通常用于模糊匹配,如果满足条件则返回1,否则返回0。如果给定的值或者匹配条件为NULL,则返回结果为NULL。

LIKE运算符通常使用如下通配符:

“%”:匹配0个或多个字符。
“_”:只能匹配一个字符。
#练习:查询last_name中包含字符'a'的员工信息
SELECT last_name
FROM employees
WHERE last_name LIKE '%a%';
#练习:查询last_name中以字符'a'开头的员工信息
SELECT last_name
FROM employees
WHERE last_name LIKE 'a%';
#练习:查询第3个字符是'a'的员工信息
SELECT last_name
FROM employees
WHERE last_name LIKE '__a%';

ESCAPE

  • 回避特殊符号的:使用转义符
  • 如果使用\表示转义,要省略ESCAPE。如果不是\,则要加上ESCAPE。
#练习:查询第2个字符是_且第3个字符是'a'的员工信息
#需要使用转义字符: \ 
SELECT last_name
FROM employees
WHERE last_name LIKE '_\_a%';
#或者  (了解)
SELECT last_name
FROM employees
WHERE last_name LIKE '_$_a%' ESCAPE '$';

REGEXP运算符

REGEXP运算符用来匹配字符串,语法格式为:expr REGEXP 匹配条件。如果expr满足匹配条件,返回1;如果不满足,则返回0。若expr或匹配条件任意一个为NULL,则结果NULL。

(1)‘^’匹配以该字符后面的字符开头的字符串。
(2)‘$’匹配以该字符前面的字符结尾的字符串。
(3)‘.’匹配任何一个单字符。
(4)“[...]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”或“b”或“c”。为了命名字符的范围,使用一 个‘-’。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。
(5)‘*’匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的‘x’字符,“[0-9]*”匹配任何数量的数字, 而“*”匹配任何数量的任何字符。

3. 逻辑运算符

运算符

作用

示例

NOT 或 !

逻辑非

SELECT NOT A

AND 或 &&

逻辑与

SELECT A AND B

OR 或 ||

逻辑或

SELECT A OR B

XOR

逻辑异或

SELECT A XOR B

逻辑非运算符

逻辑非(NOT或!)运算符表示当给定的值为0时返回1;当给定的值为非0值时返回0;当给定的值为NULL时,返回NULL。

逻辑与运算符

逻辑与(AND或&&)运算符是当给定的所有值均为非0值,并且都不为NULL时,返回1;当给定的一个值或者多个值为0时则返回0;否则返回NULL。

逻辑或运算符

逻辑或(OR或||)运算符是当给定的值都不为NULL,并且任何一个值为非0值时,则返回1,否则返回0;当一个值为NULL,并且另一个值为非0值时,返回1,否则返回NULL;当两个值都为NULL时,返回NULL。

注意:OR可以和AND一起使用,但是在使用时要注意两者的优先级,由于AND的优先级高于OR,因此先对AND两边的操作数进行操作,再与OR中的操作数结合。

逻辑异或运算符

逻辑异或(XOR)运算符是当给定的值中任意一个值为NULL时,则返回NULL;如果两个非NULL的值都是0或者都不等于0时,则返回0;如果一个值为0,另一个值不为0时,则返回1。

4. 位运算符

运算符

作用

示例

&

按位与(位AND)

SELECT A & B

|

按位或(位OR)

SELECT A | B

^

按位异或(为XOR)

SELECT A ^ B

~

按位取反

SELECT  ~A

>>

按位右移

SELECT  A >> 2

<<

按位左移

SELECT  B << 2

按位与运算符

按位与(&)运算符将给定值对应的二进制数逐位进行逻辑与运算。当给定值对应的二进制位的数值都为1时,则该位返回1,否则返回0。

按位或运算符

按位或(|)运算符将给定的值对应的二进制数逐位进行逻辑或运算。当给定值对应的二进制位的数值有一个或两个为1时,则该位返回1,否则返回0。

按位取反运算符

按位取反(~)运算符将给定的值的二进制数逐位进行取反操作,即将1变为0,将0变为1。

按位右移运算符

按位右移(>>)运算符将给定的值的二进制数的所有位右移指定的位数。右移指定的位数后,右边低位的数值被移出并丢弃,左边高位空出的位置用0补齐。

按位左移运算符

按位左移(<<)运算符将给定的值的二进制数的所有位左移指定的位数。左移指定的位数后,左边高位的数值被移出并丢弃,右边低位空出的位置用0补齐。

第05章 排序与分页

1. 排序数据

1.1 排序规则
  • 使用 ORDER BY 子句排序
  • ASC(ascend):升序
  • DESC(descend):降序
  • ORDER BY子句在SELECT语句的结尾。
# 单列排序
SELECT employee_id,last_name,salary
FROM employees
ORDER BY salary; # 如果在ORDER BY 后没有显式指名排序的方式的话,则默认按照升序排列。
# 我们可以使用列的别名,进行排序
SELECT employee_id,salary,salary * 12 annual_sal
FROM employees
ORDER BY annual_sal;
# 多列排序
SELECT employee_id,salary,department_id
FROM employees
ORDER BY department_id DESC,salary ASC;
  • 可以使用不在SELECT列表中的列排序。
  • 在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有值都是唯一的,将不再对第二列进行排序。

2. 分页

2.1 实现规则
  • MySQL中使用LIMIT实现分页
  • 格式:
LIMIT [位置偏移量,] 行数
  • “偏移量”参数指示MySQL从哪一行开始显示,是一个可选参数,如果不指定“位置偏移量”,将会从表中的第一条记录开始(第一条记录的位置偏移量是0,第二条记录的位置偏移量是1,以此类推);第二个参数“行数”指示返回的记录条数。
-- 前10条记录: 
SELECT * FROM 表名 LIMIT 0,10; 
或者
SELECT * FROM 表名 LIMIT 10;
-- 第11至20条记录: 
SELECT * FROM 表名 LIMIT 10,10;
-- 第21至30条记录: 
SELECT * FROM 表名 LIMIT 20,10;

MySQL 8.0中可以使用“LIMIT 3 OFFSET 4”,意思是获取从第5条记录开始后面的3条记录,和“LIMIT 4,3;”返回的结果相同。

  • 分页显式公式:**(当前页数-1)每页条数,每页条数
  • 注意:LIMIT子句必须放在整个SELECT语句的最后!

第06章 多表查询

1. 一个案例引发的多表连接

1.1 笛卡尔积(或交叉连接)的理解

笛卡尔乘积是一个数学运算。假设我有两个集合 X 和 Y,那么 X 和 Y 的笛卡尔积就是 X 和 Y 的所有可能组合,也就是第一个对象来自于 X,第二个对象来自于 Y 的所有可能。组合的个数即为两个集合中元素个数的乘积数。

SQL92中,笛卡尔积也称为交叉连接,英文是CROSS JOIN。在 SQL99 中也是使用 CROSS JOIN表示交叉连接。它的作用就是可以把任意表进行连接,即使这两张表不相关。

#查询员工姓名和所在部门名称 
SELECT last_name,department_name FROM employees,departments; 
SELECT last_name,department_name FROM employees CROSS JOIN departments;
  • 笛卡尔积的错误会在下面条件下产生
  • 省略多个表的连接条件(或关联条件)
  • 连接条件(或关联条件)无效
  • 所有表中的所有行互相连接
  • 为了避免笛卡尔积, 可以在WHERE加入有效的连接条件。

2. 多表查询分类讲解

分类1:等值连接vs非等值连接

拓展1:区分重复的列名

  • 多个表中有相同列时,必须在列名之前加上表名前缀。

拓展2:表的别名

  • 使用别名可以简化查询。
  • 列名前使用表名前缀可以提高查询效率。

需要注意的是,如果我们使用了表的别名,在查询字段中、过滤条件中就只能使用别名进行代替,不能使用原有的表名,否则就会报错。

拓展3:连接多个表

  • 连接n个表,至少需要n-1个连接条件。
#非等值连接的例子
SELECT e.last_name,e.salary,j.grade_level
FROM employees e,job_grades j
#where e.`salary` between j.`lowest_sal` and j.`highest_sal`;
WHERE e.`salary` >= j.`lowest_sal` AND e.`salary` <= j.`highest_sal`;

分类2:自连接vs非自连接

#自连接的例子:
#练习:查询员工id,员工姓名及其管理者的id和姓名
SELECT emp.employee_id,emp.last_name,mgr.employee_id,mgr.last_name
FROM employees emp ,employees mgr
WHERE emp.`manager_id` = mgr.`employee_id`;

分类3:内连接  vs  外连接

  • 内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
  • 外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。
  • 如果是左外连接,则连接条件中左边的表也称为主表,右边的表称为从表
  • 如果是右外连接,则连接条件中右边的表也称为主表,左边的表称为从表

3. SQL99语法实现多表查询

3.1 基本语法
  • 使用JOIN...ON子句创建连接的语法结构:
SELECT table1.column, table2.column, table3.column
FROM table1 JOIN table2
ON table1 和 table2 的连接条件
JOIN table3
ON table2 和 table3 的连接条件
3.2 内连接(INNER JOIN)的实现
  • 语法
SELECT 字段列表
FROM A表 INNER JOIN B表
ON 关联条件
WHERE 等其他子句;
SELECT last_name,department_name
FROM employees e INNER JOIN departments d
ON e.`department_id` = d.`department_id`;
3.3 外连接(OUTER JOIN)的实现
3.3.1 左外连接(LEFT OUTER JOIN)
  • 语法:
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE 等其他子句;
SELECT last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`;
3.3.2 右外连接(RIGHT OUTER JOIN)
  • 语法:
SELECT 字段列表 
FROM A表 RIGHT JOIN B表
ON 关联条件
WHERE 等其他子句;
SELECT last_name,department_name
FROM employees e RIGHT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`;

4. UNION的使用

UNION操作符

UNION 操作符返回两个查询的结果集的并集,去除重复记录。

UNION ALL操作符

UNION ALL操作符返回两个查询的结果集的并集。对于两个结果集的重复部分,不去重。

如果明确知道合并数据后的结果数据不存在重复数据,或者不需要去除重复的数据,则尽量使用UNION ALL语句,以提高数据查询的效率。

5. 7种SQL JOINS的实现

5.1 举例
# 中图:内连接
SELECT employee_id,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`;
# 左上图:左外连接
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`;
# 右上图:右外连接
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;
# 左中图:
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL;
# 右中图:
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;
# 左下图:满外连接
# 方式1:左上图 UNION ALL 右中图
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
UNION ALL
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;
# 方式2:左中图 UNION ALL 右上图
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
UNION ALL
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;
# 右下图:左中图  UNION ALL 右中图
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
UNION ALL
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;
5.2 语法格式小结
  • 左中图
#实现A - A∩B
select 字段列表
from A表 left join B表
on 关联条件
where 从表关联字段 is null and 等其他子句;
  • 右中图
#实现B - A∩B
select 字段列表
from A表 right join B表
on 关联条件
where 从表关联字段 is null and 等其他子句;
  • 左下图
#实现查询结果是A∪B
#用左外的A,union 右外的B
select 字段列表
from A表 left join B表
on 关联条件
where 等其他子句
union
select 字段列表
from A表 right join B表
on 关联条件
where 等其他子句;
  • 右下图
#实现A∪B - A∩B 或 (A - A∩B) ∪ (B - A∩B)
#使用左外的 (A - A∩B) union 右外的(B - A∩B)
select 字段列表
from A表 left join B表
on 关联条件
where 从表关联字段 is null and 等其他子句
union
select 字段列表
from A表 right join B表
on 关联条件
where 从表关联字段 is null and 等其他子句

6. SQL99语法新特性

6.1 自然连接
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`
AND e.`manager_id` = d.`manager_id`;
# NATURAL JOIN : 它会帮你自动查询两张连接表中`所有相同的字段`,然后进行`等值连接`。
SELECT employee_id,last_name,department_name
FROM employees e NATURAL JOIN departments d;
6.2 USING连接
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id;
# 指定数据表里的同名字段进行等值连接,只能配合JOIN一起使用。
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
USING (department_id);

【强制】超过三个表禁止 join。需要 join 的字段,数据类型保持绝对一致;多表关联查询时,保证被关联的字段需要有索引。


说明:即使双表 join 也要注意表索引、SQL 性能。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
30天前
|
SQL 关系型数据库 MySQL
|
30天前
|
SQL 存储 关系型数据库
|
存储 关系型数据库 MySQL
|
30天前
|
SQL 缓存 关系型数据库
|
存储 关系型数据库 MySQL
|
19天前
|
SQL 存储 关系型数据库
6本值得推荐的MySQL学习书籍
本文是关于MySQL学习书籍的推荐,作者在DotNetGuide技术社区和微信公众号收到读者请求后,精选了6本值得阅读的MySQL书籍,包括《SQL学习指南(第3版)》、《MySQL是怎样使用的:快速入门MySQL》、《MySQL是怎样运行的:从根儿上理解MySQL》、《深入浅出MySQL:数据库开发、优化与管理维护(第3版)》以及《高性能MySQL(第4版)》和《MySQL技术内幕InnoDB存储引擎(第2版)》。此外,还有12本免费书籍的赠送活动,涵盖《SQL学习指南》、《MySQL是怎样使用的》等,赠书活动有效期至2024年4月9日。
|
存储 关系型数据库 MySQL
|
存储 SQL 关系型数据库
|
2月前
|
SQL 存储 关系型数据库
学习mysql
学习mysql
39 5
|
10月前
|
存储 关系型数据库 MySQL