Skip to content
On this page

孙飞学习--MySql

1. 数据类型

1.1整数以及浮点数

age 年龄不会超过127 所以考虑使用``TINYINT 这个类型的范围为-128-127`;

又因为年龄无符号 就是不会出现``负数 我们可以使用无符号的TINYINT`;

综上所以 在MySql 里面定义年龄我们就可以

sql
age TINYINT UNSIGNED  (范围为 0-127)

score 成绩 假设成绩的取值范围为0-100,但是考虑到也有 60.0 , 75.5, 85.0这样的数值存在;

我们就可以考虑使用double类型来存储这个变量;

在SQL语句中 double 有两个参数 ,

  • 第一个: 数值的最长长度 score一般是4位 100.0
  • 第二个: 允许整数后几个数值存在 score 一般是1位小数
sql
score DOUBLE(4,1)

1.2字符串类型

varchar : 变长字符串 变量存储一个字符 就占一个字符 ; 最多存储10个字符 性能较差

sql
varchar(10)

char: 定长字符串 变量存储一个字符 也占10 个字符大小; 性能好'

sql
chat(10)

1.3日期类型

31DATE 3 范围1000-01-01 至 9999-12-31 格式 YYYY-MM-DD 描述 日期值

sql
birthday date;

2. 数据类型 课堂练习

根据需求创建表(设计的数据类型、长度)

设计一张员工信息表,要求如下:

  1. 编号(纯数字)
  2. 员工工号(字符串类型,长度不超过10位)
  3. 员工姓名(字符串类型,长度不超过10位)
  4. 性别 (男/女,存储一个汉字)
  5. 年龄(正常人年龄,不可能存储负数)
  6. 身份证号(工代身份证号均为18位,身份证中有X这样的字符)
  7. 入职时间(取值年月日即可)
sql
create table emp (
    id INT,  /*编号 */
    gonghao varchar(10) ,/*员工工号*/
    name varchart(10), /*姓名*/
    gender char(1) , /* 性别 */
    age TINYINT UNSIGNED, /* 年龄 */
    peoID char(18), /*身份证号码*/
    joinTime DATE , /* 入职时间 */
) comment  '员工表';

3. 添加&修改&删除

添加字段

alter table 表名 add 字段名 类型(长度) [comment 注释 ] [约束] ;

sql
/* 添加字段 */
alter table emp add nickName varchar(10) comment '昵称';

修改数据类型

alter table 表名 modify 字段名 新数据类型(长度)

sql
/* 将 emp 表的 nickName 字段 修改为 username , 类型位 varchart(30)*/
alter table emp change nickName   username varchar(30) comment ' 新昵称';

修改字段名 以及其数据类型

alter table 表名 change 旧字段名 新字段名 类型(长度) [comment 注释] [ 约束 ];

sql
alter table emp change nickName   username varchar(30) comment ' 新昵称';

删除字段

alter table 表名 DROP 字段名;

将emp表的字段username 这个字段 进行删除

sql
alter table emp drop username;

修改表名

alter table 表名 rename to 新表名

sql
/* 下面两种方式 都可以重命名表*/
alter goodLists rename to things;
alter goodLists rename things;

to 可加可不加

删除表

drop table [if exists] 表名;

if exists : 如果表存在就删除;不存在我也不不报错 (常用)

sql
drop table if exists things

truncate table 表名

删除指定表,并且重新创建该表 只有表结构 没有数据 (不常用)

sql
truncate table things

4. 总结

DDL- 数据库操作

  • 查看数据库 : show databases;
  • 创建数据库 : create database 数据库名;
  • 删除数据库: drop database 数据库名; 可选参数 if exits
  • 查看当前是在哪个数据库当中: select database();

DML- 表操作

  • 查看当前数据库有哪些表 : show tables;
  • 创建表:create table 表名 (字段 字段类型,字段,字段类型);可加参数 comment '注释'
  • 切换数据库: use 数据库名字;
  • 查看表详细 : desc 表名字;
  • 查看表的建表语句 : show create table 表名;
  • 删除表 : drop table 表名;

图像化界面DataGrip 的 下载 安装 使用

下载地址:

DataGrip:由 JetBrains 开发的数据库和 SQL 跨平台 IDE

安装好 是免费使用30天 我在pdd 花5 块 破解了一个 不想太麻烦了

DML

DML- 添加数据

  1. 给指定字段添加数据(顺序一一对应)
sql
insert into 表名 (字段名1 , 字段名 2, ...) values (值1,值2)
  1. 给全部字段添加数据
sql
inset into 表名 values ( 值1, 值2 )
  1. 批量添加数据
sql
insert into 表名 (字段名1 , 字段名 2, ...) values (值1,值2...),(值1,值2 ...)  -- 两种方式都可以 但一种更加直观;
inset into 表名 values ( 值1, 值2 ),(值1, 值2)...
  • 插入数据时,指定的字段顺序需要与值的顺序是一一对应的。
  • 字符串日期型数据应该包含在引号中。
  • 插入的数据大小,应该在字段的规定范围内
1.png

DML- 修改数据

DMl- 修改数据

sql
update 表名 set 字段名去 = 值1, 字段名2 =2,...[where 条件];

tips:

修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据;

DML- 删除数据

dml- 删除数据

sql
delete from 表名 where 条件

tips:

修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据;

2.png

DQL

DQL- 编写顺序

sql
SELECT 字段列表 select

FROM 表名列表  from

WHERE 条件列表  where

GROUP BY 分组字段列表 group by

HAVING 分组后条件列表 having

ORDER BY 排序字段列表 order by

LIMIT 分页参数 limit

DQL- 基础查询

SELECT 字段列表

FROM 表名列表

WHERE 条件列表

GROUP BY 分组字段列表

HAVING 分组后条件列表

ORDER BY 排序字段列表

LIMIT 分页参数

  1. 查询指定多个字段
sql
select 字段1,字段2,字段3,.... from 表名
  1. 查询返回所有字段
sql
select * from 表名设置别名
  1. 设置别名
sql
select 字段1 [ as 别名1],字段2[as 别名2]... from 表名

as可以省略不写

  1. 去除重复数据
sql
select distinct 字段列表 from 表名

3.png

DQL- 条件查询

sql
-- 查询 年龄 age > 18 的员工有哪些
select * from employee where age >18;
-- 查询 年龄 age < 18 的员工有哪些
select * from employee where age < 18;
-- 查询 年龄 age = 18 的员工有哪些
select * from employee where age = 18;

-- 查询 年龄 age >= 18 的员工有哪些
select * from employee where age >= 18;

-- 查询 年龄 age 不为null 的员工有哪些
select * from employee where age is not null;

 -- 查询年龄 age 不等于 30 的员工有哪些
select * from employee where age != 30;
select * from employee where age <> 30;

-- 查询 年龄在 20 - 25 之间的 员工有哪些
select * from employee where age >= 20 && age <= 25;
select * from employee where age >= 20 and age <= 25;
select * from employee where age between 20 and 25; -- 包头包尾

-- 查询年龄 = 18 并且 性别为 男 的 员工 有哪个
select * from employee where age = 18 and gender = '';

-- 查询年龄 = 25 或者 28 或者 32 并且性别为 男 的员工有哪些;
-- 因为该语句中使用了 OR 运算符来组合多个条件时,可能存在优先级问题,需要用括号明确指定条件的优先级。
select * from employee where gender = '' and (age = 25 or age = 28 or age = 32)  ;
select * from employee where gender = '' and (age in (25,28,32))  ;

-- 查询姓名 为3个汉字(3个字符)的员工有哪些;
select * from employee where name like '___'; -- ___ 代表三个字符

-- 查询身份证 最后一位是0 的员工有哪些; %0 : 表示前面有多是字符我不管,我只需要知道最后一个字符是0
select * from employee where idcard like '%0';

update employee set age = 18 where name = '张三';

4.png

DQL- 聚合函数

1.介绍:

​ 将一列数据作为一个整体,进行纵向计算

2.常见聚合函数 (不计算 字段值为null 的数据 )

函数功能
count统计数量
max最大值
min最小值
avg平均值
sum求和总数

3. 语法

sql
select 聚合函数 (字段列表) from 表名;

4. 练习题

5.png

DQL- 分组查询

1. 语法

​ ELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组 后过滤条件 ];

2. where与having区别 执行时机不同:

  • where是分组之前进行过滤,不满足where条件,不参与分组;

  • 而having是分组 之后结果进行过滤。 判断条件不同:where不能对聚合函数进行判断,而having可以

3. 注意事项:

  • 分组之后,查询的字段一般聚合函数分组字段,查询其他字段无任何意义。
  • 执行顺序: where > 聚合函数 > having 。
  • 支持多字段分组, 具体语法为 : group by columnA,columnB

4. 练习题

6.png

DQL- 排序查询

1. 语法😍

sql
select 字段名 from 表名 order by 字段 排序方式(asc,desc);

2. 排序方式😉

  • asc: 正序 || 升序;
  • desc: 倒序 || 降序;

3. 注意事项:😦

  • 如果是升序, 可以不指定排序方式ASC ;
  • 如果是多字段排序,当第一个字段值相同时,根据第二个字段进行排序 ;

4. 练习题😎

7.png

DQL- 分页查询

1. 语法😍

sql
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数 ;

2. 注意事项:😦

  • 起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数
  • 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT
  • 如果查询的是第一页数据起始索引可以省略,直接简写为 limit 10

3. 练习题😎

8.png

DQL 语句 练习

习题练习

查询年龄为20,21,22,23岁的员工信息

sql
select * from employee where age in (20,21,23);

查询性别为 男 ,并且年龄在 20-40 岁(含)以内的 姓名为三个字 的员工。

sql
select * from employee where gender = "" and (age between 20 and 40) and name like '___';

统计员工表中, 年龄小于60岁的 , 男性员工和女性员工的人数。

sql
select gender,count(*) from employee where age < 60 group by gender;

查询所有 年龄小于等于35岁员工 的 姓名 和 年龄 ,并对查询结果按 年龄升序 排序,如果 年龄相同按 入职时间 降序排序。

sql
select name,age,enterdate from employee where  age <=  35 order by age asc,enterdate desc;

查询 性别为 男,且 年龄在20-40 岁(含)以内 的 前5个员工信息 ,对 查询的结果 按 年龄升序排序 ,年龄相同 按入职时间升序排序 。

sql
select * from employee where gender = "" && age >= 20 && age <= 40 order by age asc,enterdate asc limit 0,5

DCL

DCL 英文全称是 Data Control Language(数据控制语言),用来管理数据库,用户,控制数据库的访问 权限.

DCL - 管理用户

  1. 查询用户
sql
use mysql;
select * from user;

10.png

其中 Host代表当前用户访问的主机, 如果为localhost, 仅代表只能够在当前本机访问,是不可以 远程访问的。

User代表的是访问该数据库的用户名。在MySQL中需要通过Host和User唯一标识一 个用户。

  1. 创建用户
sql
create user  '用户名' @ '主机名'   identified by ' 密码';
  1. 修改用户密码
sql
alter user  '用户名' @ '主机名'   identified  with mysql_native_password by '新密码'
  1. 删除用户
sql
drop user ' 用户名 ' @ '主机名'

11.png

注意事项:

  • 在MySQL中需要通过用户名@主机名的方式,来唯一标识一个用户。
  • 主机名可以使用 % 通配。
  • 这类SQL开发人员操作的比较少,主要是DBA( Database Administrator 数据库 管理员)使用。

DCL- 权限控制

MySQL中定义了很多种权限,但是常用的就以下几种:

权限说明
ALL, ALL PRIVILEGES所有权限
SELECT查询数据
INSERT插入数据
UPDATE修改数据
DELETE删除数据
ALTER修改表
DROP删除数据库/表/视图
CREATE创建数据库/表

上述只是简单罗列了常见的几种权限描述,其他权限描述及含义,可以直接参考官方文档。

  1. 查询权限
sql
show grants fro '用户名'@'主机名';
show grants for 'sunfei'@'localhost';
  1. 授予权限
sql
grant 权限列表 on 数据库名.表名 to '用户名' @'主机名';
grant all on text.* to 'sunfei'@'localhost';
  1. 撤销权限
sql
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
revoke all on text.* from 'sunfei'@'localhost';

注意事项:

  • 多个权限之间 使用逗号隔开
  • 授权时,数据库名 和 表名可以使用 * 进行通配, 代表所有

函数

函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着,这一段程序或代码在MySQL中 已经给我们提供了,我们要做的就是在合适的业务场景调用对应的函数完成对应的业务需求即可。 那 么,函数到底在哪儿使用呢?

**两个使用场景: **

1). 在企业的OA或其他的人力系统中,经常会提供的有这样一个功能,每一个员工登录上来之后都能 够看到当前员工入职的天数。 而在数据库中,存储的都是入职日期,如 2000-11-12,那如果快速计 算出天数呢?

2). 在做报表这类的业务需求中,我们要展示出学员的分数等级分布。而在数据库中,存储的是学生的 分数值,如98/75,如何快速判定分数的等级呢?

MySQL中的函数主要分为以下四类:

字符串函数、数值函数、日期函数、流程函数。

1. 字符串函数

Mysql 中已经内置了很多的字符串函数, 常用的几个如下 :

函数功能
concat(s1,s2,....sn)字符串拼接, 将S1,S2 ... Sn 拼接成一个字符串
lower ( Str )将字符串str 全部转换为小写
upper(str)将字符串str 全部转换为大写
lpad( str , n , pad )左填充,用字符串pad对str的左边进行填充,达到n个字符 串长度
rpad( str , n , pad )右填充,用字符串pad对str的右边进行填充,达到n个字符 串长度
trim( str )去掉头尾 空格
substring( str , start , len)返回从字符串str 从 start 位置起的 len 个 长度的字符串
  1. concat
sql
-- contact 字符串拼接
select concat('hello','world','myssql');  -- helloworldmyssql
  1. lower
sql
-- lower 转小写
select lower("HELLO"); -- hello
  1. upper
sql
-- upper 转大写
select upper("hello"); -- HELLO

4 lpad

sql
-- lpad   左填充
select lpad('fei',6,'sun');  -- sunfei
  1. rpad
sql
-- rapd   右填充
select rpad('sun',6,'fei');  -- sunfei
  1. trim
sql
-- trim 去除头尾空格
select trim('    123456 78   '); -- 123456 78
  1. substring
sql
-- substring  截取
select substring('hello HeiMa',1,5) -- hello

2. 数值函数

函数功能
ceil ( x )向上取整
floor ( x )向下取整
mod ( x , y )返回 X / Y 的 mo
rand ()返回0 - 1 内 随机数
round(x , y )求参数x 的 四舍五入的值,保留y 位小数
  1. ceil ( x )
sql
-- ceil
select ceil(10.2); -- 11
  1. floor ( x )
sql
-- floor
select floor(10.7); -- 10
  1. mod ( x , y )
sql
-- mod()
select mod(1,2);  -- 1
  1. rand ()
sql
-- rand
select rand();
  1. round(x , y )
sql
-- round
select round(3.1415926,1); -- 3.1

3. 日期函数

函数功能
CURDATE() || curdate()返回当前日期
CURTIME() || curtime()返回当前时间
NOW() || now()返回当前日期和时间
YEAR(date) || year()获取指定date的年份
MONTH(date) || month()获取指定date的月份
DAY(date) || day()获取指定date的日期
DATE_ADD(date, INTERVAL expr type)返回一个日期/时间值加上一个时间间隔expr后的 时间值
DATEDIFF(date1,date2) || datediff()返回起始时间date1 和 结束时间date2之间的天 数

具体代码

sql
-- 返回当前日期
select curdate(); -- 2023-04-13

-- 返回当前时间
select CURTIME(); -- 22:14:35

-- 返回当前日期和时间 上面两个的结合
select now();

-- 获取指定年份
select year(now()); -- 2023

-- 获取指定的月份
select month(now());  -- 4

-- 获取指定的日期
select day(now());   -- 13

-- 指定日期 + 数值 + 类型 年 月 日 == 未来日期
select DATE_ADD(NOW(),INTERVAL 70 DAY);

-- 获取两个时期相差的天数
select datediff('2023-04-13','2002-11-21'); -- 7448

4. 流程函数

流程函数也是很常用的一类函数,可以在SQL语句中实现条件筛选,从而提高语句的效率。

函数功能
IF(value , t , f)如果value为true,则返回t,否则返回 f
IFNULL(value1 , value2)如果value1不为空,返回value1,否则 返回value2
CASE WHEN [ val1 ] THEN [res1] ... ELSE [ default ] END如果val1为true,返回res1,... 否 则返回default默认值
CASE [ expr ] WHEN [ val1 ] THEN [res1] ... ELSE [ default ] END如果expr的值等于val1,返回 res1,... 否则返回default默认值

约束

1. 概述

概念: 约束是作用于表中字段上的规则,用于限制存储再表中的数据

目的 : 保证数据库中数据的正确, 有效性 和 完整性.

分类 :

约束描述关键字
非空约束限制该字段的数据不能为nullNOT NULL
唯一约束保证该字段的所有数据都是唯一,不重复的UNIQUE
主键约束主键是一行数据的唯一标识,要求非空且唯一PRIMARY KEY
默认约束保存数据时,如果未指定该字段的值,则采用默认值DEFAULT
检查约束保证字段值满足某个条件CHECK
外键约束用来让两张表的数据之间建立连接,保证数据的一致性和完整性FOREIGN KEY

注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。

2. 练习

案例需求: 根据需求,完成表结构的创建。需求如下:

字段名字段含义字段类型约束条件约束关键字
idID唯一 标识int主键,并且自动增长PRIMARY KEY, AUTO_INCREMENT
name姓名varchar( 10 )不为空,并且唯一NOT NULL , UNIQUE
age年龄int大于0 小于等于120(约束条件)CHECK
status状态char( 1 )如果没有指定该值,默认 1DEFAULT
gender性别char( 1 )

对应的建表 语句 为 :

sql
CREATE TABLE tb_user(
        id int AUTO_INCREMENT PRIMARY KEY COMMENT 'ID唯一标识',
        name varchar(10) NOT NULL UNIQUE COMMENT '姓名' ,
        age int check (age > 0 && age <= 120)  COMMENT '年龄' ,
        status char(1) default '1' COMMENT '状态',
        gender char(1) COMMENT '性别'
);

3. 外键约束

MySQL中的外键约束是指在一个表中定义了一个列或多个列作为外键,这些外键关联到另一个表的主键上。它可以用来保持数据的一致性和完整性。

举个例子,假设我们有两张表,一张是"orders"订单表,它包含如下列:订单号(order_id)、客户编号(customer_id)、订单日期(order_date)等信息;而另一张表是"customers"客户表,它包含如下列:客户编号(customer_id)、客户姓名(customer_name)、联系方式(contact)等信息。

现在我们想要在"orders"表中加入一个外键约束,使得每个订单必须与一个有效的客户关联起来。即每个订单必须有一个对应的客户编号在"customers"表中存在。这就可以通过在"orders"表中添加一个customer_id列,并将其设置为外键,关联到"customers"表的customer_id主键上实现。

当我们尝试在"orders"表中插入一个不存在于"customers"表中的客户ID时,由于外键约束的存在,MySQL会拒绝该操作并返回一个错误提示,从而保证了数据的一致性和完整性。

总的来说,外键约束可以帮助我们避免不必要的数据冗余,同时也是保持数据一致性和完整性非常重要的手段之一 .

语法:

添加外键

sql
create table{
	字段名 	数据类型	约束 		注释
	...	...	....
	[constraint]  [外键名称]	foreign  key [ 外键字段名 ]  	references	主表( 主表列名 )
}

添加外键

sql
alter table 表名 add constraint 外键名称  foreign key ( 外键字段名 )  references 主表 (主表列名)

删除外键

sql
alter table 表名 drop foreign key 外键名称;
sql
-- 删除emp 表外键fk_emp_dept_id.
alter table emp drop foreign key fk_emp_dept_id;

...

多表查询

1. 多表关系

项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结 构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:

  • 一对多(多对一)
  • 多对多
  • 一对一

下面就上面的情况举几个例子:

一对多

  • 案例: 部门 与 员工的关系
  • 关系: 一个部门对应多个员工,一个员工对应一个部门
  • 实现: 在多的一方建立外键,指向一的一方的主键

屏幕截图 2023-04-14 090501.png

多对多

  • 案例: 学生 与 课程的关系
  • 关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择
  • 实现: 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

屏幕截图 2023-04-14 090522.png

对应的SQL脚本:

sql
-- 创建学生表
create table student(
    id int auto_increment primary key comment '主键ID',
    name varchar(10) comment '姓名',
    no varchar(10) comment '学号'
) comment '学生表';
-- 向表中 插入数据
insert into student values (null, '黛绮丝', '2000100101'),(null, '谢逊',
'2000100102'),(null, '殷天正', '2000100103'),(null, '韦一笑', '2000100104');

-- 创建课程表
create table course(
    id int auto_increment primary key comment '主键ID',
    name varchar(10) comment '课程名称'
) comment '课程表';
-- 向课程表中插入数据
insert into course values (null, 'Java'), (null, 'PHP'), (null , 'MySQL') ,
(null, 'Hadoop');

-- 创建学生课程关系表
create table student_course(
    id int auto_increment comment '主键' primary key,
    studentid int not null comment '学生ID',
    courseid int not null comment '课程ID',
    -- 添加外键约束
    constraint fk_courseid foreign key (courseid) references course (id),
    constraint fk_studentid foreign key (studentid) references student (id)
)comment '学生课程中间表';

-- 向学生课程关系表中插入数据
insert into student_course values (null,1,1),(null,1,2),(null,1,3),(null,2,2),
(null,2,3),(null,3,4);

一对一

  • 案例: 用户 与 用户详情的关系
  • 关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另 一张表中,以提升操作效率
  • 实现: 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

屏幕截图 2023-04-14 090536.png

对应的sql 脚本为:

sql
-- 创建用户基本信息表
create table tb_user(
    id int auto_increment primary key comment '主键ID',
    name varchar(10) comment '姓名',
    age int comment '年龄',
    gender char(1) comment '1: 男 , 2: 女',
    phone char(11) comment '手机号'
) comment '用户基本信息表';

-- 创建用户详细信息表
create table tb_user_edu(
    id int auto_increment primary key comment '主键ID',
    degree varchar(20) comment '学历',
    major varchar(50) comment '专业',
    primaryschool varchar(50) comment '小学',
    middleschool varchar(50) comment '中学',
    university varchar(50) comment '大学',
    userid int unique comment '用户ID',
    -- 外键约束	
    constraint fk_userid foreign key (userid) references tb_user(id)
) comment '用户教育信息表';

-- 向用户基本信息表中插入数据
insert into tb_user(id, name, age, gender, phone) values
    (null,'黄渤',45,'1','18800001111'),
    (null,'冰冰',35,'2','18800002222'),
    (null,'码云',55,'1','18800008888'),
    (null,'李彦宏',50,'1','18800009999');
 
 -- 向用户详细表中插入数据
insert into tb_user_edu(id, degree, major, primaryschool, middleschool,
university, userid) values
    (null,'本科','舞蹈','静安区第一小学','静安区第一中学','北京舞蹈学院',1),
    (null,'硕士','表演','朝阳区第一小学','朝阳区第一中学','北京电影学院',2),
    (null,'本科','英语','杭州市第一小学','杭州市第一中学','杭州师范大学',3),
    (null,'本科','应用数学','阳泉第一小学','阳泉区第一中学','清华大学',4);

多表查询概述

Released under the MIT License.