孙飞学习--MySql
1. 数据类型
1.1整数以及浮点数
age 年龄不会超过127 所以考虑使用``TINYINT 这个类型的范围为
-128-127`;
又因为年龄
无符号 就是不会出现``负数 我们可以使用
无符号的TINYINT`;
综上所以 在MySql 里面定义年龄我们就可以
age TINYINT UNSIGNED (范围为 0-127)
score 成绩 假设成绩的取值范围为0-100
,但是考虑到也有 60.0 , 75.5, 85.0
这样的数值存在;
我们就可以考虑使用double类型
来存储这个变量;
在SQL语句中 double 有两个参数 ,
- 第一个: 数值的最长长度 score一般是4位
100.0
- 第二个: 允许整数后几个数值存在 score 一般是1位
小数
score DOUBLE(4,1)
1.2字符串类型
varchar
: 变长
字符串 变量存储一个字符 就占一个字符
; 最多存储10个字符
性能较差
varchar(10)
char
: 定长
字符串 变量存储一个字符 也占10 个字符大小; 性能好'
chat(10)
1.3日期类型
31DATE 3 范围1000-01-01 至 9999-12-31
格式 YYYY-MM-DD
描述 日期值
birthday date;
2. 数据类型 课堂练习
根据需求创建表(设计的数据类型、长度)
设计一张员工信息表,要求如下:
- 编号(纯数字)
- 员工工号(字符串类型,长度不超过10位)
- 员工姓名(字符串类型,长度不超过10位)
- 性别 (男/女,存储一个汉字)
- 年龄(正常人年龄,不可能存储负数)
- 身份证号(工代身份证号均为18位,身份证中有X这样的字符)
- 入职时间(取值年月日即可)
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 注释
] [约束
] ;
/* 添加字段 */
alter table emp add nickName varchar(10) comment '昵称';
修改数据类型
alter table
表名
modify字段名 新数据类型(长度)
/* 将 emp 表的 nickName 字段 修改为 username , 类型位 varchart(30)*/
alter table emp change nickName username varchar(30) comment ' 新昵称';
修改字段名 以及其数据类型
alter table
表名
change旧字段名
新字段名
类型(长度)
[comment 注释] [ 约束 ];
alter table emp change nickName username varchar(30) comment ' 新昵称';
删除字段
alter table
表名
DROP字段名
;
将emp表的字段username 这个字段 进行删除
alter table emp drop username;
修改表名
alter table
表名
rename to新表名
/* 下面两种方式 都可以重命名表*/
alter goodLists rename to things;
alter goodLists rename things;
to 可加可不加
删除表
drop table [if exists] 表名;
if exists : 如果表存在就删除;不存在我也不不报错 (常用)
drop table if exists things
truncate table 表名
删除指定表,并且重新创建该表 只有表结构 没有数据 (不常用)
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- 添加数据
- 给指定字段添加数据(
顺序一一对应
)
insert into 表名 (字段名1 , 字段名 2, ...) values (值1,值2)
- 给全部字段添加数据
inset into 表名 values ( 值1, 值2 )
- 批量添加数据
insert into 表名 (字段名1 , 字段名 2, ...) values (值1,值2...),(值1,值2 ...) -- 两种方式都可以 但一种更加直观;
inset into 表名 values ( 值1, 值2 ),(值1, 值2)...
- 插入数据时,指定的字段顺序需要与值的顺序是
一一对应
的。字符串
和日期型数据
应该包含在引号
中。- 插入的数据大小,应该在
字段的规定范围内
。
DML- 修改数据
DMl- 修改数据
update 表名 set 字段名去 = 值1, 字段名2 = 值 2,...[where 条件];
tips:
修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据;
DML- 删除数据
dml- 删除数据
delete from 表名 where 条件
tips:
修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据;
DQL
DQL- 编写顺序
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 分页参数
- 查询指定多个字段
select 字段1,字段2,字段3,.... from 表名
- 查询返回所有字段
select * from 表名设置别名
- 设置别名
select 字段1 [ as 别名1],字段2[as 别名2]... from 表名
as可以省略不写
- 去除重复数据
select distinct 字段列表 from 表名
DQL- 条件查询
-- 查询 年龄 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 = '张三';
DQL- 聚合函数
1.介绍:
将一列数据作为一个整体,进行纵向计算
2.常见聚合函数 (不计算 字段值为null
的数据 )
函数 | 功能 |
---|---|
count | 统计数量 |
max | 最大值 |
min | 最小值 |
avg | 平均值 |
sum | 求和总数 |
3. 语法
select 聚合函数 (字段列表) from 表名;
4. 练习题
DQL- 分组查询
1. 语法
ELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组 后过滤条件 ];
2. where与having区别 执行时机不同:
where是
分组之前进行过滤
,不满足where条件,不参与分组;而having是
分组 之后
对结果
进行过滤
。 判断条件不同:where不能对聚合函数进行判断
,而having可以
。
3. 注意事项:
- 分组之后,查询的
字段一般
为聚合函数
和分组字段
,查询其他字段无任何意义。
- 执行顺序: where > 聚合函数 > having 。
- 支持多字段分组, 具体语法为 : group by columnA,columnB
4. 练习题
DQL- 排序查询
1. 语法😍
select 字段名 from 表名 order by 字段 排序方式(asc,desc);
2. 排序方式😉
-
asc
: 正序 || 升序; -
desc
: 倒序 || 降序;
3. 注意事项:😦
- 如果是升序, 可以
不指定
排序方式ASC
; - 如果是多字段排序,当
第一个字段值相同
时,才
会根据第二个字段进行排序
;
4. 练习题😎
DQL- 分页查询
1. 语法😍
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数 ;
2. 注意事项:😦
- 起始索引从
0
开始,起始索引 = (查询页码 - 1)* 每页显示记录数
。 - 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是
LIMIT
。 - 如果查询的是
第一页数据
,起始索引可以省略
,直接简写为limit 10
。
3. 练习题😎
DQL 语句 练习
习题练习
查询年龄为20,21,22,23岁的员工信息
select * from employee where age in (20,21,23);
查询性别为 男 ,并且年龄在 20-40 岁(含)以内的 姓名为三个字 的员工。
select * from employee where gender = "男" and (age between 20 and 40) and name like '___';
统计员工表中, 年龄小于60岁的 , 男性员工和女性员工的人数。
select gender,count(*) from employee where age < 60 group by gender;
查询所有 年龄小于等于35岁员工 的 姓名 和 年龄 ,并对查询结果按 年龄升序 排序,如果 年龄相同按 入职时间 降序排序。
select name,age,enterdate from employee where age <= 35 order by age asc,enterdate desc;
查询 性别为 男,且 年龄在20-40 岁(含)以内 的 前5个员工信息 ,对 查询的结果 按 年龄升序排序 ,年龄相同 按入职时间升序排序 。
select * from employee where gender = "男" && age >= 20 && age <= 40 order by age asc,enterdate asc limit 0,5
DCL
DCL 英文全称是 Data Control Language(数据控制语言),用来管理数据库,用户,控制数据库的访问 权限.
DCL - 管理用户
- 查询用户
use mysql;
select * from user;
其中 Host
代表当前用户访问的主机
, 如果为localhost, 仅代表只能够在当前本机访问
,是不可以 远程访问
的。
User代表的是访问该数据库的用户名
。在MySQL中需要通过Host和User
来唯一标识
一 个用户。
- 创建用户
create user '用户名' @ '主机名' identified by ' 密码';
- 修改用户密码
alter user '用户名' @ '主机名' identified with mysql_native_password by '新密码'
- 删除用户
drop user ' 用户名 ' @ '主机名'
注意事项:
- 在MySQL中需要通过用户名@主机名的方式,来唯一标识一个用户。
- 主机名可以使用 % 通配。
- 这类SQL开发人员操作的比较少,主要是DBA( Database Administrator 数据库 管理员)使用。
DCL- 权限控制
MySQL中定义了很多种权限,但是常用的就以下几种:
权限 | 说明 |
---|---|
ALL, ALL PRIVILEGES | 所有权限 |
SELECT | 查询数据 |
INSERT | 插入数据 |
UPDATE | 修改数据 |
DELETE | 删除数据 |
ALTER | 修改表 |
DROP | 删除数据库/表/视图 |
CREATE | 创建数据库/表 |
上述只是简单罗列了常见的几种权限描述,其他权限描述及含义,可以直接参考官方文档。
- 查询权限
show grants fro '用户名'@'主机名';
show grants for 'sunfei'@'localhost';
- 授予权限
grant 权限列表 on 数据库名.表名 to '用户名' @'主机名';
grant all on text.* to 'sunfei'@'localhost';
- 撤销权限
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 个 长度的字符串 |
- concat
-- contact 字符串拼接
select concat('hello','world','myssql'); -- helloworldmyssql
- lower
-- lower 转小写
select lower("HELLO"); -- hello
- upper
-- upper 转大写
select upper("hello"); -- HELLO
4 lpad
-- lpad 左填充
select lpad('fei',6,'sun'); -- sunfei
- rpad
-- rapd 右填充
select rpad('sun',6,'fei'); -- sunfei
- trim
-- trim 去除头尾空格
select trim(' 123456 78 '); -- 123456 78
- substring
-- 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 位小数 |
- ceil ( x )
-- ceil
select ceil(10.2); -- 11
- floor ( x )
-- floor
select floor(10.7); -- 10
- mod ( x , y )
-- mod()
select mod(1,2); -- 1
- rand ()
-- rand
select rand();
- round(x , y )
-- 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之间的天 数 |
具体代码
-- 返回当前日期
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. 概述
概念: 约束是作用于表中字段上的规则,用于限制存储再表中的数据
目的 : 保证数据库中数据的正确, 有效性 和 完整性.
分类 :
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段的数据不能为null | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一,不重复的 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
检查约束 | 保证字段值满足某个条件 | CHECK |
外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。
2. 练习
案例需求: 根据需求,完成表结构的创建。需求如下:
字段名 | 字段含义 | 字段类型 | 约束条件 | 约束关键字 |
---|---|---|---|---|
id | ID唯一 标识 | int | 主键 ,并且自动增长 | PRIMARY KEY, AUTO_INCREMENT |
name | 姓名 | varchar( 10 ) | 不为空 ,并且唯一 | NOT NULL , UNIQUE |
age | 年龄 | int | 大于0 小于等于120(约束条件) | CHECK |
status | 状态 | char( 1 ) | 如果没有指定该值,默认 1 | DEFAULT |
gender | 性别 | char( 1 ) | 无 |
对应的建表 语句 为 :
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会拒绝该操作并返回一个错误提示,从而保证了数据的一致性和完整性。
总的来说,外键约束可以帮助我们避免不必要的数据冗余,同时也是保持数据一致性和完整性非常重要的手段之一 .
语法:
添加外键
create table{
字段名 数据类型 约束 注释
... ... ....
[constraint] [外键名称] foreign key [ 外键字段名 ] references 主表( 主表列名 )
}
添加外键
alter table 表名 add constraint 外键名称 foreign key ( 外键字段名 ) references 主表 (主表列名)
删除外键
alter table 表名 drop foreign key 外键名称;
-- 删除emp 表外键fk_emp_dept_id.
alter table emp drop foreign key fk_emp_dept_id;
...
多表查询
1. 多表关系
项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结 构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:
- 一对多(多对一)
- 多对多
- 一对一
下面就上面的情况举几个例子:
一对多
- 案例: 部门 与 员工的关系
- 关系: 一个部门对应多个员工,一个员工对应一个部门
- 实现: 在多的一方建立外键,指向一的一方的主键
多对多
- 案例: 学生 与 课程的关系
- 关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择
- 实现: 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
对应的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)
对应的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);