MySQL数据库--【初级篇】

MySQL数据库

本系列文章将针对MySQL数据库的由浅到深进行讲解


文章目录


前言

数据库作为应用广泛的数据存储方式之一,是目前全栈、后端、算法工程师必须掌握的一类工具,本文将进行一系列关于数据库的分析,包含并不限于MySQL等主流数据库。


一、MySQL介绍

作为目前主流使用的免费数据库,MySQL收到了许多学者和工程师的欢迎,目前也是使用较为广泛的数据库之一,MySQL属于MySQL AB公司开发的小型关系数据库,该公司已经被sun公司收购,而sun公司又被oracle公司收购,因此,目前MySQL是由oracle公司进行维护的。

二、安装MySQL

1.下载、安装

官方下载地址

     接下来的介绍将以windows版本为例

     安装只要一直点下一步就可以了。

     跳过安装配置(如果有需要之后我会继续发一篇相关的文章)直接进入操作。

2.什么是数据库?什么是数据库管理系统?什么是SQL?以及他们之间的关系

数据库: 英文单词DataBase,简称DB。按照一定格式存储数据的一些文件的组合。顾名思义:存储数据的仓库,实际上就是一堆文件,这些文件中存储了具有特定格式的数据。

数据库管理系统: DataBaseManagementSystem,简称DBMS。是专门用来管理数据库中数据的,数据库管理信息系统可以对数据库当中的数据进行增、删、改、查。

常见的数据库管理系统: MySQL、Oracle、MS、SqlServer、DB2、sybase、OceanBase等。

SQL: Structure Query Language(结构化查询语言)简称SQL,简单来讲程序员编写SQL语言,然后DBMS执行SQL语言,最终完成数据库中数据的增、删、改、查。

三者之间的关系:DBMS- -执行- -SQL- - 操作- - DB.

三、SQL概述

     上文中,已经描述过SQL语言的概念,接下来将对SQL语言进行详细的描述。

1.表的描述

     在进行SQL语言学习之间,应该先明白一个概念,就是数据库中最基本的单元是:表(table) , 数据库当中以表格的形式展示数据,任何一张表都有行和列。
     行(row):被称为数据/记录。
     列(column):被称为字段。
     在关系性数据库当中,为了确保数据的完整性和唯一性,在创建表时除了必须指定字段名称、字段类型、字段属性,还需要使用约束(constraint)、索引(index)、主键(primary key)、外键(foregin key)等功能属性。

2.表的数据类型

MySQL数据库中的列类型有三类:数值类、字符串类和日期/时间类。

  1. 数值类
数据列表类型 存储空间 说明 取值范围
TINYINT 1字节 非常小的整数 带符号值:-128~127
无符号值: 0~255
SMALLINT 2字节 较小的整数 带符号值:-32768~32767
无符号值:0~65535
MEDIUMNT 3字节 中等大小的整数 带符号值:-8288608~8388607
无符号值:0~16777215
INT 4字节 标准整数 带符号值:-2147483648~2147483647
无符号值:0~4294967295
FLOAT 4或8字节 单精度浮点数 最小非零值:±1.175494351E-38
最大非零值:±3.402823466E+38
BOUBLE 8字节 双精度浮点数 最小非零值:±2.2250738585072014E-308
最大非零值:±1.7976931348623157E+308
注意:为了节省存储空间和提高数据库处理效率,我们应该根据应用数据的取值范围来选择一个最合适的数据类型。如果把一个超出数据列取值范围的数存入该列,则MySQL就会截短该值!
  1. 字符串类
    字符串是数据的基本类型之一,MySQL支持以单引号或双引号来包围字符序列。下面将列举一些常用的字符串类型。
数据列表类型 存储空间 说明 取值范围
CHAR[M] M字节 定长字符串 M字节
VARCHAR[M] L+1字节 可变字符串 M字节
TINYBLOD,TINYTEXT L+1字节 非常小的BLOB和文本串 28 -1字节
BLOD,TEXT L+2字节 小BLOB和文本串 216 -1字节
ENUM(‘value1’,‘value2’…) 1或2字节 枚举:可赋予某个枚举成员 65535个成员
SET(‘value1’,‘value2’…) 1、2、3、4或8字节 枚举:可赋予多个集合成员 64个成员
在使用过程中应注意CHAR和VARCHAR的区别: 两者的长度范围都是0~255,它们之间的差别在于MySQL处理这个指示器的方式,CHAR把这个大小是为值得准确大小(也就是给了多大空间就只能放多大得数据);而VARCHAR类型则会把其是为最大值,并且只使用存储字符得实际上需要的字节数。BLOB和TEXT类型是可以存放任意大数据类型,只是前者区分大小写,后者不区分大小写。

注意:虽然VARCHAR和TEXT两者使用起来是变长的,但会使表中产生许多脆片要定期运行OPTIMIZE TABLE语句以保持其性能。所以在设计表得时候请谨慎。

  1. 日期和时间类
数据列表类型 存储空间 说明 取值范围
DATE 3字节 “YYYY-MM-DD”格式表示的日期值 1000-01-01~9999-12-31
TIME 3字节 “hh:mm:ss”格式表示的时间值 -838:59:59~838:59:59
TIME 8字节 “YYYY-MM-DD hh:mm:ss”格式 1000-01-01 00:00:00~9999-12-31 23:59:59
TIMESTAMP 4字节 “YYYYMMDDhhmmss”格式表示的时间戳 19700101000000~2037年的某个时刻
YEAR 1字节 “YYYY”格式的年份值 1901~2155
首先,时间戳的计算方式:现有时间-19700101000000。在存储过程中也可以使用整形数据类型来存储UNIX 时间戳。 MySQL默认的格式是:年-月-日 时-分-秒,建议默认格式存储,不然还需要str_to_date与date_format进行格式化,增加工作量。
  1. NULL值
    在MySQL允许NULL值的存在,意味着“没有值”,在数据库中可以插入也可以检索,三十无法进行算数运算,任何与NULL进行的算数运算,其结果都是NULL。
  2. 类型转换
    在MySQL的表达式中,如果某个数据值的类型与上下文所要求的类型不相符,MySQL则会根据将要进行的操作自动的对数据值进行类型转换。例如:
1+'2' #会转换成1+2=3
1+'abc' #会转换成1+0=1.由于abc不能转换成任何值,所以默认为零

3.SQL的优点及分类

优点:
1、简单易学,具有很强的操作性
2、绝大多数重要的数据库管理系统均支持SQL
3、高度非过程化;用SQL操作数据库时大部分的工作由DBMS自动完成

分类:
1、DDL(Data Definition Language) 数据定义语言,用来操作数据库、表、列等; 常用语句:CREATE、 ALTER、DROP
2、DML(Data Manipulation Language) 数据操作语言,用来操作数据库中表里的数据;常用语句:INSERT、 UPDATE、 DELETE
3、DCL(Data Control Language) 数据控制语言,用来操作访问权限和安全级别; 常用语句:GRANT、DENY
4、DQL(Data Query Language) 数据查询语言,用来查询数据 常用语句:SELECT

4.数据库操作

接下来列举一些关于数据库的连接、创建、查看、删除等操作。

数据库的启停:

在windows操作系统中使用命令启动数据库:
		net stop 服务器名;
		net start 服务器名;
		注意!在启停数据库的时候要以管理员身份启动窗口

数据库的基本操作:

登录mysql:mysql -h -u用户名 -p用户密码;
退出mysql:exit
创建数据库 : create database [IF NOT EXISTS]数据库名;
查看有哪些数据库:show databases;
删除数据库:drop database [IF EXISTS] 数据库名;

运行效果:

创建名为:TEST的数据库
MySQL数据库--【初级篇】
查看数据库:
MySQL数据库--【初级篇】

使用数据库:use database;

MySQL数据库--【初级篇】

查看当前使用的数据库:select database();

MySQL数据库--【初级篇】

删除数据库(删库跑路必备)
MySQL数据库--【初级篇】

5.数据库表的基本操作

上边提到,数据库当中表是基本数据结构,数据库所有的操作都是围绕表来展开的,因此,从此节开始都将围绕表的基础操作进行展示。以下的操作,在实际应用中可以使用插件(navicat)去完成,因此更多的作为了解内容即可。 首先使用(use 数据库名)进入数据库。

5.1 创建表(CREATE TABLE)

创建表主要是定义数据表的结构,包括数据表的名称,字段名,字段类型,属性及索引等,基本语法类型如下:
创建表:create table 表名{
		字段名1 字段类型 字段属性 字段约束,
		字段名2 字段类型 字段属性 字段约束,
		字段名3 字段类型 字段属性 字段约束,
		字段名4 字段类型 字段属性 字段约束,
		...
}表类型 表字符集;

MySQL数据库--【初级篇】
查看表的创建语句:

show create table 表名;

查看表结构:
MySQL数据库--【初级篇】
查看当前库中的表:

show tables

查看其他库中的表:

show tables from 数据库名称;

5.2 修改表 (ALTER TABLE)

修改表是指修改表的结构。在实际应用中,当发现某张表的结构不满足要求时,可以使用ALTER TABLE语句修改表的结构,包括,添加新的字段,删除原有字段,修改列的类型、属性及索引,甚至可以修改表的名称。修改表的语法如下:
ALTER TABLE 表名 ACTION;
其中ACTION是ALTER TABLE 的从句,包括为指定的表添加一个新列、为表添加一个索引、更改指定列的默认值、更改列类型、删除一列、删除索引、更改表名等语句。下面简单介绍几种常用的语句:
  1. 为指定的数据表添加一个新字段:

    ALTER TABLE 表名 ADD 字段名<建表语句>[FIRST|AFTER 列名]
    

    其中FIRST、AFTER是指在列头添加还是在列尾添加。
    MySQL数据库--【初级篇】

  2. 为指定的数据表更改原有字段的类型。

     ```sql
     ALTER TABLE 表名 CHANGE(MODIFY) 列名 <建表语句>
     ```
     
    
     ```sql
     ALTER TABLE users MODIFY telnum int(20) UNSIGNED;
     ALTER TABLE users CHANGE telnum telno INT(20) UNSIGNED;
     ```
     <font size=3>
     上述语句当中的区别在于CHANGE不光可以修改字段属性,还可以修改字段名;而MODIFY只可以修改字段属性。
    
  3. 为指定的数据表重命名

    ALTER TABLE 旧表名 RENAME AS 新表名;
    
    ALTER TABLE users RENAME AS userlist;
    
  4. 删除列

    ALTER TABLE 表名 DROP 字段名;
    

5.3 删除表(DROP TABLE)

DROP TABLE IF EXISTS 表名;

5.4 插入语句(INSERT)

当我们用了已经建好的数据表之后,就可以向表内插入数据了,下面讲的是使用SQL语句进行插入数据的方式,当然,Navicat当中可以使用excel等方式进行数据的导入,更为方便,但在后台接口中,我们更多的使用的是insert语句。 首先回顾以下之前我们建的users表结构: ![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210713091732324.png)
  1. insert 语句
INSERT INTO 表名(字段名1,字段名2,字段名3...) VALUES(值1,值2,值3...)

示例,向users中插入一条数据:

INSERT INTO users(id,username,userpassword,sex,birthday) VALUES(1,'sam','123','男','2021-7-13');

MySQL数据库--【初级篇】
MySQL数据库--【初级篇】
在使用insert语句时候,每个字段和其属性是一一对应的,因此在输入过程中注意数据的顺序。另外,也可以在输入时不输入字段名,直接跟VALUES(),此时默认对所有字段进行插入值,在填入数据时要注意。

INSERT INTO users VALUES(值1,值2...);

5.5 更新语句(UPDATE)

更新语句是对数据表中现有数据进行修改的语句。
UPDATE users SET 字段名1=值1,字段名2=值2... WHERE 条件;
注意,如果没有条件,那么意味着所有数据全部更新。 示例,更新users中‘sam’名字为‘zhangsan’:
UPDATE users SET username = 'zhangsan' WHERE id = '1';

MySQL数据库--【初级篇】

5.6 删除语句(DELETE)

DELETE语句,既可以删除一条记录,也可以删除一张表。
DELETE FROM 表名 WHERE 条件;
如果没有WHERE语句,则表示会删除一张表的所有数据(注意,表不会被删,删除表使用DROP语句),否则删除指定数据。 示例,新建一张名为student的表,而后删除。 新建:
CREATE TABLE student(
id int(10),
name varchar(20),
age int
);
INSERT INTO student(id,name,age) VALUES(1,'ZHANGSAN',18),(2,'LISI',19);

MySQL数据库--【初级篇】
删除‘LISI’的记录:

DELETE FROM student WHERE name = 'LISI';

删除student表:

DELETE FROM student;

还有一种删除语句:

TRUNCATE TABLE 表名;
两者的区别: (1)DELETE语句后可跟WHERE子句,可通过指定WHERE子句中的条件表达式只删除满足条件的部分记录;但是,TRUNCATE语句只能用于删除表中的所有记录。 (2)使用TRUNCATE语句删除表中的数据后,再次向表中添加记录时自动增加字段的默认初始值重新由1开始;使用DELETE语句删除表中所有记录后,再次向表中添加记录时自动增加字段的值为删除时该字段的最大值加1。 (3)DELETE语句是DML语句,TRUNCATE语句通常被认为是DDL语句。 (4)DELETE删除可以回滚,恢复数据,表中数据被删除,但是硬盘上的存储空间没有释放;TRUNCATE无法回滚,但删除更快。但是DELETE可以回滚的条件是MySQL中已经设置了binlog,设置后可以根据时间回滚。

5.7 查询语句(SELECT)重要!

在SQL语言的使用当中,结合实际来看,SELECT语句是使用频率最高,应用范围最广的语句,本文也将花费最大的篇幅来讲解SELECT语句的使用。

1. 查询语句

SELECT 字段名 FROM 表名;
其中,字段名可以跟‘AS 别名’来给字段添加别名显示;字段名可以直接使用数学运算(+,-,*,/)完成对该字段内的数据的数学运算。 在示例之前,我们先对users 表添加几条数据:
INSERT INTO users(id,username,userpassword,sex,birthday) VALUES(2,'LISI','123','女','2021-06-30'),(3,'wangwu','456','女','2021-05-30'),(4,'zhaoliu','789','男','2018-05-24');

查询表中全部内容
MySQL数据库--【初级篇】

2. 按条件查询

SELECT 
	字段1、字段2、。。。。
FROM 
	表名 
WHERE
	条件1、条件2、。。。。;

示例:查询’sex = ‘男’'的姓名记录:

SELECT
	username AS name
FROM
	users
WHERE
	sex='男';

MySQL数据库--【初级篇】
在上边的示例中,查询出了所有男的姓名,可以观察到在显示的时候,使用了AS语句对查询的结果进行另命名。

示例:计算id=6的人的十倍工资:

 SELECT sal*10 AS '工资' FROM users WHERE id='6';

MySQL数据库--【初级篇】

接下来,我们对条件语句进行进一步了解。
条件查询中WHERE支持的运算符,如下:

运算符 说明
= 等于
<>或!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
between…and… 两个值之间,等同于>=and<=
is null 为null(is not null 不为空)
and 并且
or 或者
in 包含,相当于多个or(not in 不在这个范围)
not not可以取非,主要用在is 或 in中
like 模糊查询,支持%或者下划线匹配
%匹配任意个字符
下划线,一个下划线只匹配一个字符

由于后边会涉及到多表查询等操作,所以从新使用新的数据库表,格式如下:
员工表:
MySQL数据库--【初级篇】
薪资等级表:
MySQL数据库--【初级篇】
部门表:
MySQL数据库--【初级篇】
下面我们对运算符做一些简单说明,其中常见的就不做示例了,如下:

  • between … and …. 两个值之间, 等同于 >= and <=

    查询薪资在2450和3000之间的员工信息?包括2450和3000
    第一种方式:>= and <= (and是并且的意思。)

    select empno,ename,sal from emp where sal >= 2450 and sal <= 3000;
    

    MySQL数据库--【初级篇】
    第二种方式:

    between … and …
    		select 
    			empno,ename,sal 
    		from 
    			emp 
    		where 
    			sal between 2450 and 3000;
    			
    			注意:
    				使用between and的时候,必须遵循左小右大。
    				between and是闭区间,包括两端的值。
    

    MySQL数据库--【初级篇】

  • is null
    查询哪些员工的津贴为null

    SELECT empno,ename,comm FROM EMP WHERE comm is null;
    

    MySQL数据库--【初级篇】
    注意,在MySQL中null不能使用等号衡量。而是使用is null,这是因为Null代表的是什么都没有,这里的什么都没有同时意味着Null不是一个值,因此,不能使用等号衡量。

  • and
    and 语句又译为‘交’,是指同时满足and左右两端条件。求集合的交集。
    查询工作岗位是MANAGER并且工资大于2500的员工信息?

    SELECT 
    	empno,ename,job,sal
    FROM
    	EMP
    WHERE
    	job='MANAGER' AND sal>2500;
    

    MySQL数据库--【初级篇】

  • or
    和and相反,or,是指满足其中一个条件即可。求集合的并集。
    查询工作岗位是MANAGER和SALESMAN的员工?

    select empno,ename,job from emp where job = 'MANAGER';
    select empno,ename,job from emp where job = 'SALESMAN';
    
    select 
    	empno,ename,job
    from
    	emp
    where 
    	job = 'MANAGER' or job = 'SALESMAN';
    

    MySQL数据库--【初级篇】
    这里要做一个说明,当and和or 同时出现在条件查询中时,and的优先级高于or的优先级。如果想让or限制性就需要给or语句加小括号,总的来讲,如果不确定执行的优先级,就给条件加小括号。

  • in
    in语句用于指定条件的范围吗,例如:
    查询工作岗位是MANAGER和SALESMAN的员工?

    select empno,ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
    select empno,ename,job from emp where job in('MANAGER', 'SALESMAN');
    
    这两个句子意义一样。
    
  • like模糊查询
    首先,like语句可以检索目标项和数据项所匹配的数据(类似于知网中关键字查询)。
    简单举个例子,查找名字为’SMITH’的数据:

    SELECT * FROM EMP WHERE ename like 'SMITH';
    

    MySQL数据库--【初级篇】
    这个查找中:ename like ‘SMITH’ 作用和 ename = ‘SMITH’ 一样,从这里并不能直接看出LIKE语句作用,接下来问题变为:
    查询名字中包含 ‘A’ 的所有员工信息?

    SELECT * FROM EMP WHERE ename like '%A%';
    

    MySQL数据库--【初级篇】
    了解了LIKE语句的意义后,接下来区分%和下划线的不同:
    %可以匹配任意长度的字符;
    下划线只能匹配单个字符;
    注意,两个方式出现在关键字左边及只检索左边,右边同理;出现在两边则全关键字检索。
    MySQL数据库--【初级篇】

3. 数据处理函数

数据处理函数又被称为单行处理函数。其特点是:一个输入对应一个输出。
常见的单行处理函数:

函数名 含义
lower 转成小写
upper 转成大写
substr 取子串,substr(待截取字符串,起始下标【从1开始】,结束下标)
length 取字符串长度
concat 进行字符串的拼接
trim 去除空格
str_to_date 字符串转换成日期
round 四舍五入,round(待处理数字,保留小数点的位数)
rand 生成随机数,rand()默认生成0-1之间的
ifnull 空值处理函数,ifnull(数据,替换数据)
case…when…then…else…end 当…时…其他…结束
SELECT UPPER(ename) AS name FROM EMP;

MySQL数据库--【初级篇】
名字首字母小写:

SELECT CONCAT(lower(substr(ename,1,1)),substr(ename,2,LENGTH(ename)-1)) AS name FROM EMP;

MySQL数据库--【初级篇】
case…when…then…else…end示例:
当员工的工作岗位是MANAGER的时候,工资上调10%,当工作岗位是SALESMAN的时候,工资上调50%,其它正常。(注意:不修改数据库,只是将查询结果显示为工资上调)

SELECT ename,job,sal AS oldsal,(case job WHEN job='MANAGER' THEN sal*1.1 WHEN job='SALESMAN' THEN sal*1.5 ELSE sal end) AS newsal FROM EMP;

MySQL数据库--【初级篇】

4. 聚合函数

聚合函数也叫分组函数、多行处理函数:输入多行,输出一行。

分组函数在使用的时候必须先进行分组,然后才能用。

函数名 说明
count 计数
sum 求和
avg 平均数
max 最大值
min 最小值

这五个函数的使用方法是相同的
示例:

SELECT COUNT(ename) AS '人数' FROM EMP;

MySQL数据库--【初级篇】

聚合函数使用起来很方便,但是有一些注意事项:
1.只有SELECT子句和HAVING子句、ORDER BY子句中能够使用聚合函数。不可以在WHERE语句中使用。
2.分组函数自动忽略NULL,你不需要提前对NULL进行处理。
3.分组函数中count(*)和count(具体字段)有什么区别?

  • count(具体字段):表示统计该字段下所有不为NULL的元素的总数。
  • count(**):统计表当中的总行数。(只要有一行数据count则++)
    因为每一行记录不可能都为NULL,一行数据中有一列不为NULL,则这行数据就是有效的。

5. 分组查询(GROUP BY)和HAVING语句

在实际使用时,有可能需要对列数据进行分组,然后再对分组数据进行操作。
分组查询句式:

		SELECT
			...
		FROM
			...
		GROUP BY
			...

统计每个部门人数:

SELECT COUNT(ename) AS '人数', JOB AS '部门'FROM EMP GROUP BY JOB;

MySQL数据库--【初级篇】
在我的理解中,group by 就是将目标列拆分为一个新表,而且将重复项去除了。
可以两个字段联合成一个字段看。
示例:每个部门不同岗位的最高薪资

SELECT deptno,job,max(sal) FROM EMP GROUP BY deptno,job;

MySQL数据库--【初级篇】
有时候分完组之后进行操作时,需要对数据进行进一步过滤,但是在WHERE语句中又无法使用聚合函数,可以使用HAVING语句对分组都的数据进行进一步过滤,HAVING不能单独使用,必须跟在GROUP BY之后。
要求显示每个部门最大薪资大于3000的数据。

SELECT deptno,max(sal) FROM EMP GROUP BY deptno HAVING max(sal) > 3000;

MySQL数据库--【初级篇】
在这里可以抛出一个问题,可以先将薪资大于3000的全部筛选出来,再继续进行分组。

SELECT deptno,max(sal) FROM EMP WHERE sal > 3000 GROUP BY deptno;

MySQL数据库--【初级篇】
同样可以达到效果,因此在使用having语句前请慎重,考虑是否必须使用having,因为where条件语句执行效率比having 高,在数据量大的时候体现比较明显。

6. 排序语句(ORDER BY)

排序语句很好理解,就是对查询的数据按照升序(降序)排列。

SELECT
	...
FROM
	...
WHERE
	...
GROUP BY
	...
ORDER BY
	字段名1 [ASC丨DESC] #ASC表示升序,是默认排序可以不写;DESC 降序,需要填写。

7. LIMIT 语句

limit语句的句式很简单,但是limit语句一定要在ORDER BY 语句之后使用!!!

SELECT
	...
FROM
	...
WHERE
	...
GROUP BY
	...
ORDER BY
	...
LIMIT startIndex,length #startIndex是指开始下标;length指长度。

limit作用:将查询结果集的一部分取出来。通常使用在分页查询当中(当然使用limit和offset进行分页,在分页数量很多的情况下,效率比较低,作为了解)。
示例:按照薪资降序,取出排名在前5名的员工?

#第一种方式,只填写一个数字是指:默认从第一个开始往后取五个值。
SELECT ename,sal FROM EMP ORDER BY sal LIMIT 5;
#第二种方式
SELECT ename,sal FROM EMP ORDER BY sal LIMIT 0,5;

MySQL数据库--【初级篇】
接下来说一下LIMIT语句在分页中的用法。
假设,从第0也开始,每页显示3条记录。那么:

页码 limit 记录编号
第1页 limit 0,3 [0,1,2]
第2页 limit 3,3 [3,4.5]
第3页 limit 6,3 [6,7,8]
第4页 limit 9,3 [9,10,11]
第5页 limit 12,3 [12,13,14]
第n页 limit (n-1)*3,3 [(n-1)*3, (n-1)*3+1, (n-1)*3+2]

从上表中可以总结一个规律,如果知道每页显示的记录数pagesize和页码pageno我们就可以使用LIMIT语句从数据库中读取数据,公式如下:
s t a r t I n d e x = ( p a g e n o − 1 ) ∗ p a g e s i z e startIndex = (pageno-1)*pagesize startIndex=(pageno−1)∗pagesize
也就是说,我们只需要从前端获取记录数pagesize和页码pageno就可以进行分页操作了。

8. 连接查询

连接查询是指对多张表中的数据同时进行查询,多表的连接是关系型数据模型的主要特点,也是区别于其他类型数据库管理系统的一个标志。
根据表的连接方式分类:内连接(等值连接、非等值连接、自连接)外连接(左外连接、右外连接)
在进行示例之前,我先解释一下笛卡尔积现象。主要是指:在连接两张表时,不增加任何条件,则表的匹配次数等两张表行数相乘。通过笛卡尔积现象表明,尽量减少表的连接次数。
如:select name, age from namelist, agelist;这时,每一个name都会和所有age进行匹配。
如何避免笛卡尔积现象:连接时增加条件。
示例:以下是等值连接,也就是建立等式关系。

SELECT
	别名1.字段1,别名2.字段2...
FROM
	表1 AS 别名1
JOIN
	表2 AS 别名2
ON
	别名1.某字段=表2.某字段

MySQL数据库--【初级篇】
员工表
MySQL数据库--【初级篇】
部门表
显示每个人所属的部门:
SELECT E.ename,D.dname FROM EMP AS E JOIN DEPT AS D ON E.DEPTNO=D.DEPTNO;

MySQL数据库--【初级篇】

以上SQL语句在ON之后建立了等号条件,因此称为等值连接,而非等值连接就是建立非等号连接(如:!=,>,<,between…and…等)。
内连接之自连接:即将一张表看作两张表,相互连接。
查询员工的上级领导,要求显示员工名和对应的领导名?

SELECT E1.ename,E2.ename FROM EMP AS E1 JOIN EMP AS E2 WHERE E1.MGR = E2.EMPNO;

MySQL数据库--【初级篇】
外联接:又分为右外连接和左外连接,其中的差异是以左表为主表还是以右表为主表,主表的内容会全部显示,右表按查询要求显示,右表无法匹配的则会用NULL填充,其实第一个示例(显示每个人所属部门),就可以使用左连接。
外连接句式:

SELECT 
	表1.字段,表2.字段
FROM
	表1 AS 别名1
LEFT[RIGHT] JOIN
	表2 AS 别名2
ON
	别名1.某字段=表2.某字段

显示每个人所属的部门:

SELECT E.ename,D.dname FROM EMP AS E LEFT JOIN DEPT AS D ON E.DEPTNO=D.DEPTNO;

MySQL数据库--【初级篇】
多表连接句式:

		select 
			...
		from
			a
		join
			b
		on
			a和b的连接条件
		join
			c
		on
			a和c的连接条件
		right join
			d
		on
			a和d的连接条件

其实就是a和b 先连接,之后在和c连接,之后在和d连接。理论上讲可以实现很多表连接,但是考虑到笛卡尔积现象导致的连接效率问题,在大厂中,一般不建议使用三张表以上的表连接查询。

9. 子查询

什么叫子查询呢?
举个例子,在SELECT语句中嵌套一个SELECT语句,被嵌套的SELECT语句称为子查询。
子查询可以出现的位置:

SELECT
	..(SELECT ..)..
FROM
	..(SELECT)..
WHERE
	..(SELECT)..

在子查询中只能返回一列,并将形成的结果作为父查询的条件在主句中进一步查询。SQL语言中允许多层嵌套查询,即一个子查询中还可以有其他子查询。嵌套查询中的求解方法是由里向外处理的,即每个子查询都是在上一级查询之前求解,子查询的结果用于建立其父查讯的查找条件。
示例一WHERE子查询

找出比最低工资高的员工姓名和工资?
实现思路:
第一步:查询最低工资是多少

SELECT min(sal) FROM EMP;

MySQL数据库--【初级篇】
第二步:找出>800的员工及对应薪资

SELECT ename,sal FROM EMP WHERE sal > 800;

第三步:合并

SELECT ename,sal FROM EMP WHERE sal > (SELECT min(sal) FROM EMP);

MySQL数据库--【初级篇】
在WHERE子查询中,还可以包含ANY()、ALL()、EXISTS()、以及算式运算方法,这里就不多叙述了。

示例二FROM子查询:
from后面的子查询,可以将子查询的查询结果当做一张临时表。

找出每个岗位的平均工资的薪资等级。

第一步:找出每个岗位的平均工资(按照岗位分组求平均值)

SELECT job,avg(sal) FROM EMP GROUP BY job;

第二步:把以上的查询结果就当做一张真实存在的表t。

SELECT T.*,S.grade FROM (SELECT job,avg(sal) AS avgsal FROM EMP GROUP BY job) AS T LEFT JOIN SALGRADE S ON T.avgsal between S.losal AND S.hisal;

MySQL数据库--【初级篇】
示例三SELECT子查询:
找出每个员工的部门名称,要求显示员工名,部门名?

SELECT e.ename,e.deptno,(SELECT d.dname FROM DEPT d WHERE e.deptno = d.deptno) AS dname FROM EMP e;

MySQL数据库--【初级篇】
注意,对于select后面的子查询来说,这个子查询只能一次返回1条结果,多于1条,就报错了!

10.UNION合并查询

在9中,讨论过笛卡尔积现象会降低查询效率,那么在连接查询中使用ON后加入条件来缓解笛卡尔积现象,本节中介绍得UNION合并查询,也可以有效缓解查询效率低得情况。
union的效率要比连接表要高,对于表连接来说,每接一次新表,则匹配的次数满足笛卡尔积,成倍翻。
union可以减少匹配次数,在减少匹配次数的情况下,完成两个结果集的拼接。
如:

a连接b连接c:
a 10条记录;
b 10条记录;
c 10条记录;
使用join 连接,匹配次数:10*10*10=1000
a连接b :10*10=100
union
a 连接c 10*10=100:
匹配次数:200.
注意:union在进行合并的时候,两个结果的列相同。
	select ename,job from emp where job = 'MANAGER'
	union
	select ename from emp where job = 'SALESMAN';

5.8关于DQL语句执行顺序

	select 
		...
	from
		...
	where
		...
	group by
		...
	having
		...
	order by
		...
	limit
		...
	
	执行顺序?
		1.from
		2.where
		3.group by
		4.having
		5.select
		6.order by
		7.limit..

5.9 约束

1. 什么是约束?

约束对应的英语单词:constraint
在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的
完整性、有效性!!!
约束的作用就是为了保证:表中的数据有效!!

2. 约束有哪些?

约束名 说明
PRIMARY KEY 主键约束(添加该约束得字段,主键值是每一行得唯一标识)
FOREIGN KEY 外键约束
NOT NULL 非空约束
UNIQUE 唯一性约束 (也就是添加该约束得字段值不能重复)
CHECK(mysql不支持,oracle支持) 检查约束
DEFAULT 默认值约束
  • 非空约束 not null;

  • 唯一约束 unique; 单独加在字段名后表示该字段唯一,不能有重复值
    如: name unique, 两个字段联合唯一:

    		create table linshi(
    		id int,
    		name varchar(255),
    		email varchar(255),
    		unique(name,unique)
    );
    
  • 主键约束 primary key
    主键特征:not null + unique
    主键又可以分为:自然主键、业务主键
    自然主键:主键值是一个自然数,和业务没关系。
    业务逐渐:主键值和业务紧密关联,如:用银行卡号做主键。
    auto_increment 自增;

  • 外键约束 foreign key

    foreign key(外键名) reference 父表名(主键名)
    
  • 检查约束
    mySQL不支持,oraclo支持。

5.10 数据库范式

数据库范式:数据库表的设计依据。
目的:避免表中数据的冗余,空间浪费。

  • 第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分;

  • 第二范式:在第一范式基础上,要求所有非主键字段完全依赖主键,不要产生部分依赖。

  • 第三范式:在第二范式基础上,要求所有非主键字段直接依赖主键,不要产生传递依赖。

sql中表越多,连接次数越多,效率越低,笛卡尔积现象。
实际中会减少表的连接次数,来换取执行效率。

5.11 视图

视图是一种根据查询(也就是SELECT表达式)定义得数据库对象,用于获取想要看到的得和使用的局部数据;
视图也被称为‘虚拟表’;
视图可以被用来从常规表或者其他视图中查询数据
视图有以下好处:

  • 访问数据变得简单
  • 可被用来对不同用户显示不同得表的内容

创建视图:
CREATE VIEW 视图名 as select * from emp;
删除视图:
DROP VIEW 视图名;

!!!对视图的增删改查会影响原表。
视图相当于简化了SQL语句,简化开发,利于维护。

总结

本篇内容写到这里,对于MySQL的基本操作就已经描述完了,当然还有许多没有涉及的,如:事务、索引、数据库的原理等等,这些东西篇幅较大,我计划每类分为一个单独的文章去讲述,希望我的整理的东西可以对各位有一定的帮助。

上一篇:MySQL 基础一


下一篇:MySQL常用函数