MySQL基础

基础

入门 MySQL

数据库三大范式

为了建立冗余较小,结构合理的数据库,设计数据库时必须遵循一定的规则。

在关系型数据库中这种规则就成为范式。

a. 第一范式

确保每列保持原子性,数据库中的所有字段都是不可分解的原子值。

b. 第二范式

确保表中的每列都和主键相关。

c. 第三范式

确保每列都和主键列之间相关,而不是间接相关

关系模型

关系数据库的表和表之间的关系 : 一对多 一对一 多对一

关系型数据库使通过 主键 和 外键 进行维护的

主键

定义:

在关系型数据库中,一张表中的每一行数据被称为一条记录,一条记录有多个字段组成。主键是用来区分两条记录的,在关系型数据库中不能存在两条相同的记录。

选取:

  1. 字段唯一
  2. 字段不能和业务有任何相关性。

一般使用id字段,其类型有:

  1. 自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数。(每添加一条自增1,所以不会重复。删除已经出现的id,不会重置id自增的当前初始值。)
  2. 全局唯一GUID类型:这是一种全局唯一的字符串作为主键,GUID算法使用网卡MAC地址,时间戳,随机数保证唯一性。

联合主键:

关系型数据库实际上允许多个字段唯一表示记录,多个字段都设置为主键,这种主键是联合主键。

联合主键不常用。

外键

定义:

通过主键我们可以确定一个表中的唯一的一条记录,但是如何将这个记录和其他表的某一条记录联系起来,为了表达一张表记录和其他表记录之间的关系,我们加入外键的概念。

外键不是通过列名实现的,而是通过定义外键约束实现的。(所以列名随意)

MySQL 语句:

FOREIGN KEY (列名)指定某列为外键, REFERENDCES classes(id) 指定这个外键将关联到classes表的id列(可以是classes表的主键,也可以是普通的列。)

缺点:外键的约束会降低数据库的性能,所以大部分互联网程序为了追求速度,并不设置外键约束,而是依靠自身保证逻辑的正确性。

删除外键约束,通过 ALTER TABLE 实现:

ALTER TABLE students
DROP FOREIGN KEY fk_class_id; 

★:删除外键约束,并没有删除外键这一列。删除外键这一列通过DROP COLUMN 实现。

多对多关系

一个老师对应多个班级,一个班级对应多个老师。

多对多关系实际上是通过 两个 一对多关系实现的,通过一个中间表,关联了两个一对多关系。

teachers表:

idname
1张老师
2王老师
3李老师

classes 表:

idname
1一班
2二班
中间表:`teacher_class` 关联两个表
idteacher_idclass_id
111
212
321
422
531

由上表可知:teacher id为1的,教学1班和2班,teacher id为 2的 教学 1班和2班,teacher id 为 3 的教学1班。

一对一

指 一个记录对应另一个表的唯一一个记录。

例如:学生表有自己唯一的联系方式,联系方式存在另一个表中。

既然是一对一为什么不直接增加一列? 因为目的是将常读取的数据放在一张表中,与不常用的数据分隔开,获取更高的性能

SQL

了解什么是SQL(Structured Query Language) 结构化查询语言, 是操作数据标准的特定的开发语言.

【CRUD】

C Create 创建

R Read 读取,查询

U Update 更新,修改

D Delete 删除

核心:
​ 数据库设计 C, 数据库查询 R

【重点】DQL 数据库查询语言

【重点】DML 数据库操作语言

【重点】DDL 数据库定义语言

DCL 数据库控制语言

DTL 数据库事务相关操作

MySQL概述

关系型数据库

MySQL 数据类型

数值类型

类型大小用途
TINYINT1Bytes小整数值
SMALLINT2Bytes大整数值
MEDIUMINT3Bytes大整数值
INT4Bytes大整数值
BIGINT8Bytes极大整数值
FLOAT4Bytes单精度浮点
DOUBLE8Bytes双精度浮点
DECIMAL对DECIMAL(M,D)小数值

日期和时间类型

类型大小格式用途
DATE3YYYY-MM-DD日期值
TIME3HH:MM:SS时间值或持续时间
YEAR1YYYY年份值
DATETIME8YYYY-MM-DD hh:mm:ss混合日期和时间值
TIMESTAMP4YYYY-MM-DD hh:mm:ss混合日期和时间值,时间戳

字符串类型

类型大小用途
CHAR0-255Bytes定长字符串
VARCHAR0-65535Bytes变长字符串
TINYBLOB0-255Bytes不超过255个字符的二进制字符串
TINYTEXT0-255Bytes短文本字符串
BLOB0-65535Bytes二进制形式的长文本数据
TEXT0-65535Bytes长文本数据
MEDIUMBLOB0-16777215Bytes二进制形式的中等长度文本数据
MEDIUMTEXT0-16777215Bytes中等长度文本数据
LONGBLOB0-4294967295Bytes二进制形式的极大文本数据
LONGTEXT0-4294967295Bytes极大文本数据

char(n) 和 varchar(n) 中括号中n 代表字符的个数,并不代表字节个数,比如 CHAR(30)就可以存储30个字符。

CHAR 和 VARCHAR 类型类似,但他们保存和检索的方式不同。他们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

BLOB 是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:TINYBLOB,BLOB, MEDIUMBLOB, LONGBLOB。他们的区别在于可容纳存储范围不同。

有四种TEXT类型:TINYTEXT ,TEXT, ,MEDIUMTEXT, LONGTEXT。对应的这四种BLOB类型,可存储的最大长度不同,可根据实际情况选择。

数据库管理基本操作 DML

【主要】增删改语句

登录mysql

cmd > mysql -hlocalhost -uroot -p123456
cmd > mysql -u root -p
Enter password: ******

展示当前数据库中所有的数据库

show databases;

创建数据库

create database dbName;

查询数据库创建过程中,SQL语句内容,查询创建数据库执行SQL语句情况

show create database dbName;
# +-------------+-----------------------------------------------------------------+
# | Database    | Create Database                                                      |
# +-------------+-----------------------------------------------------------------+
# | javaee_2218 | CREATE DATABASE `javaee_2218` /*!40100 DEFAULT CHARACTER SET utf8 */ |
# +-------------+-----------------------------------------------------------------+
# 可以提供的信息是数据库创建使用的语句,以及当前数据库默认编码集。这里要求默认编码集为 utf8

创建数据库的过程中,约束限制编码集。

create database dbName character set latin1;
create database dbName character set gbk;
# +-------------+-----------------------------------------------------------------+
# | Database    | Create Database                                                 |
# +-------------+-----------------------------------------------------------------+
# | javaee_2219 | CREATE DATABASE `javaee_2219` /*!40100 DEFAULT CHARACTER SET latin1 */ 
# +-------------+-----------------------------------------------------------------+
# +-------------+----------------------------------------------------------------+
# | Database    | Create Database                                                 |
# +-------------+-----------------------------------------------------------------+
# | javaee_2220 | CREATE DATABASE `javaee_2220` /*!40100 DEFAULT CHARACTER SET gbk */ |
# +-------------+-----------------------------------------------------------------+

添加表数据

insert into tableName(fieldName1, fieldName2...) values (value1, value2...)

更新数据库表数据

update tableName set fieldName = value, fieldName = value ... [where condition]

删除数据库

-- 删除指定数据库
drop database dbName;
-- 删除表
delete form tableName [where condition]

更改数据库视图

use dbName;
# Database changed 提示: 接下来所有的[数据库] 操作都是在当前数据库中
select database();
# 查询当前操作的数据库是哪一个

【重点】数据库查询语句 DQL

条件查询

-- 通配符查询
select * 
from tableName
where condition;
-- 字段查询
select fieldName [as 别名], filedName [别名]
from tableName
where condition;
-- distinct去重
select distinct fieldName
from tableName [where];

聚合函数

-- sum 总和
select sum(salary)
from table;

-- avg 求员工表所有员工的平均工资
select avg(coloumn)
from table;

-- max 找出员工表最高工资
select max(salary)
from table;

-- min 最低
select min(salary)
from table;

-- count 计数统计员工人数
select count(id) 
from table;

-- * 通配符(选择全部),确定当前员工表有多少员工
select *
from table;

-- 在SQL中,1表示true,0表示false,记录所有行
select count(1) 
from table;

分组查询

1. 语法
select 字段列表 from 表名 [where 条件] group by 分组字段名(可以多个分组字段名) [having 分组后过滤的条件]

select filedName secondName(别名,与查询内容不使用逗号隔开的名字) from 表名....
2. group by 多个分组字段

group by fieldName1, fieldName2… 中字段常被having使用。

-- 1. 首先按照 department_id 分组
-- 2. 然后按照 job_id 分组
-- 3. 计数员工人数 count(employee_id)
select department_id, job_id, count(employee_id)
from t_employees
group by department_id, job_id; -- group by 可以将目标分组字段一并完成,顺序为分组操作相关顺序。
image-20230319214213777
3. where 与 having 区别

执行时机不同: where是分组之前进行过滤,不满足where条件,不参与分组;

而having是对分组之后的结果进行过滤。

判断条件不同:where 不能使用聚合函数(sum ,count等),而having可以使用。

【注意】

执行顺序:where > 聚合函数 > having

分组之后,having查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。

分组过滤查询
select fieldName
from tbName
where condition
group by 分组字段
having 分组之后的限定条件; -- 可以使用 where 替换
-- having 是在 group by 分组之后的条件限定关键字 (需要使用group by 中的关键字)。

排序查询

select fieldName
from tableName
order by fieldName1 asc(升序,默认), fieldName2 desc(降序)
-- 多字段排序查询,第一个字段相同,第二个字段进行比较...
分页查询/限定查询【限定查询结果条数,分页操作下标从0开始】
select * 
from table 
limit 5; 
-- 限定查询结果为 5 条
-- limit offset, count
-- limit 10, 10 表示从下标10开始计数,数据行数10行
-- limit 0, 10 表示从下标 0 开始计数,数据行数10行
-- 分页,当数据量较大时,分页
-- 例如 一页有效数据 50个,一共10页
-- 格式总结:limit (pageCount - 1) * rowCount, rowCount; (多个查询)
-- pageCount 页码 rowCount 每一页多少行数据
-- 【项目中会完成】分页工具类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ke1TItJo-1679824328309)(.\MySQL.assets\image-20230321222742580.png)]

DQL 难点分析 【MySQL中下标,除了分页从0开始,其余都是从1开始】

from + 表名 从数据库的表中选择字段使用,与 select 字段无关。

select + 字段,从from的表中得到 字段对应的值 映射到最终结果表中。

where 约束 数据库中的表,所以可以使用表中所有字段,对表中数据进行约束。

【重点】因为having 是针对于 group by 分组后的表进行约束,所以只能查询group by 使用用来分组的字段值。

数据控制语言 DCL

用来管理数据库用户,控制数据库访问权限

查询用户

use mysql;
select * from user;

创建用户

create user '用户名'@'主机名' identified by '密码'
-- 主机名使用 % 说明在任意主机均可以访问该数据库
-- 'localhost' 表明只有在当前主机上才能访问该数据库

修改用户密码

alter user '用户名'@'主机名' identified with mysql_native_password by '新密码'

删除用户

drop user '用户名'@'主机名'
image-20230321224728010

权限控制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LHT1bIlE-1679824328310)(.\MySQL.assets\image-20230321225016736.png)]

-- 查询权限 'xm'@'%'
show grants for '用户名'@'主机名';
-- 授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名'
-- 权限列表 all(全部权限privileges)
-- *.* 所有数据库的所有表
-- 撤销权限
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名'
image-20230321225501733

函数

MySQL字符串应用

-- 拼接多个字符串
-- concat(str1, str2, str3...)
select concat('今天', '郑州', '天气不错~~~')

-- 指定字符串,指定下标位置开始,要求指定字符个数,使用新字符串替换
-- insert(oldStr, off, len, newStr)
-- 数据库字符串下标从1开始
select insert('0123456', 0, 2, 'zz'); -- 字符串操作没有生效
select insert('0123456', 1, 2, 'zz'); -- 从第一个开始,长度2个
--有效

-- 字符串内容转大写
select upper('abc')

-- 字符串内容转小写
select lower('ABC')

-- 截取字符串,参数是指定操作字符串,off是指定下标位置开始,len是计数字符串字符个数
-- substring(str,off,len)
image-20230321231046066
数值函数
image-20230321232303940

日期函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kLb3cb4P-1679824328311)(D:\Java学习\Java博客笔记\未完成\MySQL.assets\image-20230321232745608.png)]

-- 第一个时间减去第二个时间
datediff('2021-10-01', '2021-12-01');
-- -60

流程控制函数

流程控制函数,可以在SQL语句找那个实现条件筛选,提高语句的效率。

image-20230321234223284
-- if
select if(true, 'ok', 'error');

-- ifnull 'ok' 不为空返回 'ok'
select ifnull('ok','Default')

-- case when condition then return1 ...
-- 分数 >= 85 优秀 >= 60 及格  <60不及格
select  id, 
        name, 
        math, -- 替换成 case when math >= 85 then '优秀' when math >= 60 then '及格' else '不及格' end
        english,
        chinese
from score

-- case [expr] when ... then ... when ... then ...
case fieldName when value1 then return1  when value2 then return2

约束

概述

用在创建表时,约束是作用于表中字段上的规则,用于限制表结构中所存储的数据。

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

分类:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OSIkfqcJ-1679824328311)(.\MySQL.assets\image-20230322082038989.png)]

非空约束

not null

唯一约束

unique

主键约束

primary key

默认约束

default

自增约束 auto_increment (自增长)从1自动增长。

-- comment 用于注解
create table student1(
	id int not null unique auto_increment primary key  comment '学生ID',
    name varchar(32) default '唐三' comment '学生姓名',
    age int check(age > 0 and age <= 120) comment '年龄'
)

外键约束

在数据库层面,建立外键关联,保证数据的一致性和完整性。

语法
 -- 创建时添加
 create table 表名(
 	字段名 类型,
     ...,
     [constraint] [外键名称] foreign key (外键字段名) references 主表(主表列名)
 )
 -- 修改添加
 alter table tableName add constraint 外键名称 foreign key (tableName表中作为外键的字段名) references 主表(主表列名)
 
alter table 表名 drop foreign key 外键名称
image-20230322085222267
alter table tableName add constr aint 外键名称 foreign key (外键字段) references 主表名(主表字段名) on update cascade on delete cascade;

【重点】多表查询(内联,左链接,右链接)

多表关系:

  1. 一对一
  2. 一对多
  3. 多对多

使用外键关联。

解决多表查询操作,表与表之间存在相对于的数据约束关系,数据限制关系,数据联系。

例如:员工表中的部门id 和 部门表中的 部门id 字段数据一一对应,可以通过多表链接获取,(员工表中数据)和(部门表中的数据)

基本格式

select fieldName1, fieldName2
from tbName1
连接符 tbName2
on 条件;

笛卡尔积【避免】

使用 条件约束 避免笛卡尔积

-- 栗子
select fieldNames
from tableName1 [nickname], tableName2 [nickname];
-- 会出现笛卡尔积现象
-- 隐式内联使用where 语句可以优化
...
where table1.id = table2.id;  
--【注意】 如果表有别名那么不能使用表名了,只能使用别名操作。
-- 【导致笛卡尔积原因】因为没有任何的数据约束和限制,两个表查询目标字段数据一一匹配
-- 查询结果总行数 m * n
-- 应该使用 on+ 条件约束 对查询数据进行约束

select employee_id,first_name,department_name
from t_employees
inner join t_departments;

内链接(等值链接)

INNER JOIN:获取两个表中字段匹配关系的记录。

-- 隐式内连接
select fieldNames from tableName1, tableName2 where condition...;
-- 显式内连接
select fieldNames from tableName1 [inner] join tableName2 on condition;
image-20230322195552505

左外链接 【常用】

LEFT JOIN :匹配数据,获取左表(tableName1)中全部数据和两表的交集数据,即使右表没有数据。

select fieldNames from tableName1 left [outer] join tableName2 on condition;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sJIuUWtW-1679824328312)(D:\Java学习\Java博客笔记\未完成\MySQL.assets\image-20230322200825960.png)]

右外链接

RIGHT JOIN:匹配数据,获取右表中全部数据和两表交集数据。与LEFT JOIN 相反。

select fieldNames from tableName1 right [outer] join tableName2 on condition;
image-20230322200833463

自连接

自连接查询,可以是内查询,也可以是外查询

自查询表必须起别名。

select fieldNames from tableA [nicknameA] join tableB [nicknameB] on condition;
image-20230322201833925
select a.name '员工', b.name '领导' from emp a, emp b where a.managerid = b.id
-- 员工的 managerid => 领导的id 所以 a 表示员工表,b 表示领导表

联合查询-union,union all

对于union查询,就是把多次查询的结果直接合并起来,形成一个新的查询结果集。

select fieldNames from tableA ...
union [all]
select fieldNames from tableB ...;
-- A的查询结果 和 B的查询结果直接拼接,所以列数必须相同。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VWrNwWYe-1679824328312)(.\MySQL.assets\image-20230322202946395.png)]

子查询

基本格式

select fieldName
from tbNameA
where fieldName = (
	select fieldName
    from tbNameB
)
-- 子查询 (又称为嵌套查询)就是select 查询 嵌套 select 查询

子查询分类

根据子查询位置,分为:where 之后,from 之后,select 之后。

根据子查询结果不同分为:

  1. 标量子查询 (子查询结果为单个值)

    -- 子查询结果是 id 字段值
    -- Aid 和 Bid 有对应的关系
    select * from tbA where Aid = (
    	select Bid 
        from tbB 
        where name = 'xx'
    )
    
  2. 列子查询 (子查询结果为一列 (多个元素) 使用 in all any关键字)

    -- 找出和 xxx 同部门的员工
    select *
    from t_employees
    where department_id in (select distinct department_id
    						from t_employees
    						where first_name = 'xxx');
    -- field > all (子查询) 比所有的都大才可以返回
    -- field > any (子查询) 比任意一个大就可以返回
    
  3. 行子查询 (子查询结果为一行(可以是多列))

    -- 常用操作符 :=,<>,IN,NOT IN
    -- 查询与'xx' 的薪资及直属领导相同的员工信息
    select salary, managerid from emp where name = 'xx';
    select * from emp where salary = 10 and managerid = 1;
    -- 使用子查询
    select * from emp where (salary, managerid) = 
    (select salary, managerid from emp where name = 'xx');
    
  4. 表子查询 (子查询结果为多行多列)

    -- 子查询作为临时表,作为其他查询结果的数据来源
    -- 常用操作符 in
                
    -- 找出工资前五的员工信息
    select * 
    from t_employees
    order by salary desc;
                
    -- 将以上SQL结果,看作一个临时表,查询数据
    -- 【仅演示】语法特征,不作为开发操作必备条件
    select employee_id, first_name -- 必须是临时表中所包含的字段
    from (select * 
    	from t_employees
    	order by salary desc;) as tmp
    	limit 5;
    

事务

事务简介

事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,----这些操作要么同时成功,要么同时失败。

事务操作

事务栗子:

-- 栗子:转账操作 zs 给 ls 转账1000元
-- update tablename set fieldname = value, ...where condition
-- 1. 查询zs 账号余额
select * from account where name = 'zs';
-- 2. 将 zs 账户余额-1000
update account set money =  money - 1000 where name = 'zs'
-- 3. 将 ls 账户余额+1000
update account set money = money - 1000 where name = 'ls'

-- 查看/设置事务提交方式
select @@autocommit; -- 如果为 1 是自动提交事务,为 0 是手动提交事务。
set @@autocommit = 0; -- 设置为手动提交事务

-- 提交事务
commit;

-- 回滚事务
rollback;

方式一 手动提交事务
-- 栗子的事务修改 :方式一 手动提交事务
select @@autocommit;
set @@autocommit = 0;
-- 然后执行语句
-- 1. 查询zs 账号余额
select * from account where name = 'zs';
-- 2. 将 zs 账户余额-1000
update account set money =  money - 1000 where name = 'zs'
程序执行报错....故意设置错误
-- 3. 将 ls 账户余额+1000
update account set money = money - 1000 where name = 'ls'
-- 执行成功,提交以上事务操作
commit;
-- 执行出错,回滚事务
rollback;
方式二 【常用】自动提交事务 start transaction
-- 栗子的事务修改 :方式二 自动提交事务
set @@autocommit = 1
-- 开启事务
start transaction;
-- 1. 查询zs 账号余额
select * from account where name = 'zs';
-- 2. 将 zs 账户余额-1000
update account set money =  money - 1000 where name = 'zs'
程序执行报错....故意设置错误
-- 3. 将 ls 账户余额+1000
update account set money = money - 1000 where name = 'ls'
-- 事务执行成功,提交
commit;
-- 事务执行失败,回滚
rollback;

事务四大特性 ACID【面试问题】

  1. 原子性(atomicity):事务是不可分割的最小操作单位,要么全部成功,要么全部失败。
  2. 一致性(consistency):事务完成时,必须使所有的数据都保持一致。
  3. 隔离性(isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  4. 持久性(durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
image-20230322230801005

并发事务问题

image-20230322232731481
脏读

B 事务 读取到 A 事务没有提交的事务 之前更新数据库的值,称为脏读。

image-20230322233412447
不可重复读
image-20230322234510201
幻读

事务A 本来想插入数据库中没有的数据,但是事务B 先执行了数据的插入操作,导致事务A 在插入数据时发现数据已经存在,不能在插入数据了,称为幻读现象。

image-20230322234654408

事务隔离级别

image-20230322234721506
Read uncommitted (Oracle默认)

可能出现所有的事务并发问题。

Read committed

只能解决脏读问题。

Repeatable Read (MySQL 默认)

只可能出现幻读问题。

Serializable

解决所有并发问题。

代码设置
-- 查看事务隔离级别
select @@transaction_isolation;

-- 设置事务隔离级别
-- session 会话级别:针对于当前客户端会话窗口有效
-- global 全局级别:针对于所有客户端会话窗口有效
set [session|global] transaction isolation level {READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE}

-- 例如:当前会话设置为 read uncommitted 级别
set session transaction isolation level read uncommitted;
image-20230323002142555
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值