MySQL 基础篇笔记

MySQL 基础篇

数据库相关概念

  • 数据库(DataBase [DB] ):存储数据的仓库,数据是有组织的进行存储
  • 数据库管理系统(Data Management System [DBMS] ):操作和管理数据库的大型软件
  • SQL(Structured Query Language [SQL]):操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准


关系型数据库

建立在关系模型基础上,由多张相互连接的二维表组成的是数据库

特点:

  • 使用表存储数据,格式统一,便于维护
  • 使用 SQL 语言操作,标准统一,使用方便

在这里插入图片描述




SQL

SQL 通用语法

  1. SQL 语句可以单行或多行书写,以分号结束
  2. SQL 语法可以使用空格/缩进来增强语句的可读性
  3. MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写
  4. 注释
    • 单行注释:– 注释内容# 注释内容 (MySQL 特有)
    • 多行注释:/* 注释内容 */



SQL 分类

在这里插入图片描述

代表关键字
DQL: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY

DDL:  CREATE, ALTER, DROP

DML:  INSERT, UPDATE, DELETE

DCL:  GRANT, REVOKE 

TPL(数据事务管理语言 [Transaction Processing Language]) 确保被 DML 语句影响的表的所有行为及时更新: BEGIN, TRANSACTION, COMMIT, ROLLBACK。

CCL(指针控制语言 [Cursor Control Language]) 用于对一个或多个表的独行操作: DECLARE, FETCH INTO, UPDATE WHERE CURRENT 



DDL

数据库操作
查看所有数据库
SHOW DATABASES;

查看当前数据库
SELECT DATABASE();

创建数据库
CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则]

删除数据库
DROP DATABASE [IF EXISTS] 数据库名

使用数据库
USE 数据库名


表操作-查询
查询当前数据库所有表:
SHOW TABLES; 

查询表结构
DESC 表名; 

查询指定表多的建表语句
SHOW CREATE TABLE 表名


表操作-创建
CREATE TABLE 表名 (
	字段1 数据类型 [COMMENT 注释],
	字段2 数据类型 [COMMENT 注释],
	字段3 数据类型 [COMMENT 注释],
	....
	字段n 数据类型 [COMMENT 注释]
) [COMMENT 表注释];


表操作-数据类型

数值类型

在这里插入图片描述

精度就是多少个数字,标度就是小数点后几位

比如:123.12 标度精度是5,标度是 2

float:4 个字节,单精度(最多 5 位小数)

double:8 个字节, 双精度(最多 16 位小数)

decimal(m, d)【有效数字最多65, 小数位最多30】

无符号就是后面 + UNSIGNED


字符串类型

在这里插入图片描述

char 长度是0~255个字符

固定长度字符串,在定义时指定字符串列长。当保存时,在右侧填充空格以达到指定的长度。m表示列的长度,范围是 0~255 个字符。
例如,char(4) 定义了一个固定长度的字符串列,包含的字符个数最大为 4。当插入的字符长度大于4,则报错(除非超过4个长度之后都是空格字符,则空格字符会自动被删除用来保证插入的成功)。

varchar:长度是0~16383个字符

长度可变的字符串。varchar 的最大实际长度由最长的行的大小和使用的字符集确定,而实际占用的空间为字符串的实际长度加 1。
例如,varchar(50) 定义了一个最大长度为 50 的字符串,如果插入的字符串只有 10 个字符,则实际存储的字符串为 10 个字符和一个字符串结束字符。varchar在值保存和检索时尾部的空格仍保留。

char 性能高一点


日期时间类型

在这里插入图片描述



表操作-修改
添加字段
ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT 注释][约束]

修改字段类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度)

修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释][约束]

修改表名
ALTER TABLE 表名 RENAME TO 表名


表操作-删除
删除字段
ALTER TABLE 表名 DROP 字段名

删除表
DROP TABLE [IF EXISTS] 表名

删除指定表,并重新创建该表
TRUNCATE TABLE 表名



DML

DML-添加数据
给指定字段添加数据
INSERT INTO 表名 (字段名, 字段名2, ...) VALUES (1,2, ...);

给全部字段添加数据
INSERT INTO 表名 VALUES (1,2, ...);

批量添加字段
INSERT INTO 表名 (字段名, 字段名2, ...) VALUES (1,2,...),(1,2,...);
INSERT INTO 表名 VALUES (1,2,...),(1,2,...),(1,2,...);

字符串和日期类型数据应该包含在引号中



DML-修改数据
UPDATE 表名 SET 字段1 =1, 字段2 =2, ...[WHERE 条件]

没有 WHERE 就会修改整张表的数据



DML-删除数据
DELETE FROM 表名 [WHERE 条件]

没有 WHERE 会删除整张表的数据

DELETE 语句不能删除某一个字段的值(可以使用 UPDATE)




DQL

DQL-基本查询
查询多个字段
SELECT 字段1, 字段2, 字段3... FROM 表名
SELECT * FROM 表名;

设置别名
SELECT 字段 [AS 别名], 字段2[AS 别名2]... FROM 表名

去除重复记录
SELECT DISTINCT 字段列表 FROM 表名


DQL-条件查询
SELECT 字段列表 FROM 表名 WHERE 条件列表;

在这里插入图片描述

is not null 就是不是 NULL



DQL-聚合函数
SELECT 聚合函数(字段列表) FROM 表名;

在这里插入图片描述

所有null值不参与聚合函数运算



DQL-分组查询
SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤的条件]

where 与 having 区别

  • 执行实际不同:where 是分组之前进行过滤,不满足 where 条件,不参与分组。而 havcing 是分组之后对结果进行过滤
  • where 不能对聚合函数进行判断,而 having 可以

有 group by , select 后面只能出现聚合函数,和要分组的字段,其他不允许



DQL-排序查询
升序: ASC	(默认值)
降序:DESC

SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2... 

如果是多字段排序,当第一个字段相同才根据第二个字段进行排序



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


DQL 执行顺序

在这里插入图片描述



DCL

DLC-管理用户
查询用户
USE mysql
SELECT * FROM user;

创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

修改用户密码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY 密码;

删除用户
DROP USER '用户名'@'主机名';

可以在任意主机/ip地址访问 用 %



DLC-权限控制
查询权限
SHOW GRANT FOR '用户名'@'主机名';

授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';

撤销权限
REVOKE 权限列表 ON 数据库名 表名 FROM '用户名'@'主机名'

在这里插入图片描述

多个权限之间,使用逗号分隔

授权时,数据库名和表名可以使用 * 进行通配,代表所有




函数

字符串函数

在这里插入图片描述

-- hellomysql
select concat('hello','mysql') 拼接后;

-- hello
select lower('HELLO') 转小写;

-- HELLO
select upper('hello') 转大写;

-- ---01
select lpad('01', 5, '-');

-- 01---
select rpad('01', 5, '-');

-- hello world
select trim(' hello world ');

-- Hello
-- 下标从1开始
select substring('Hello MySQL', 1, 5);


数值函数

在这里插入图片描述

-- 2 向上取
select ceil(1.1);

-- 1 向下取
select floor(1.9);

-- 3 % 4 = 3
select mod(3, 4);

-- 0-1 之间随机数
select rand();

-- round 从小数的后一位四舍五入
select round(2.5447, 3);


日期函数

在这里插入图片描述

-- 返回当前日期: 2024-07-30
select curdate();

-- 返回当前时间: 12:04:52
select curtime();

-- 返回当前日期和时间: 2024-07-30 12:04:52
select now();

-- 获取指定 date 年份: 2024
select year(now());

-- 获取指定 date 月份: 7
select month(now());

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

-- 返回一个日期/往后推多少时间 2030-07-30 12:08:40
select date_add(now(), INTERVAL 6 YEAR);

-- 返回date1 和 date2 之间的天数 返回-1 前面日期-后面日期
select datediff(curdate(), '2024-7-31');


流程控制函数

在这里插入图片描述

-- true 返回 ok。
select if(true, 'ok', 'error');

-- 第一个值不为空,返回第一个值否则返回第二个:1
select ifnull(1, 2);

-- 查询 emp 的员工姓名和工作地址(北京/上海 ---> 一线, 其他 ----> 二线)
select
    name,
   (case workaddress
        when '北京' then '一线城市'
        when '上海' then '一线城市'
        else '二线城市'
    end) as '工作地址'
from emp;


-- 统计班级学院成绩
-- 85以上 优秀
-- 60以上 及格
-- 60以下 不及格
select
    id,
    name,
    
    (case when math >= 85 then '优秀' when math >= 60 then '及格' else '不及格' end) as '数学',
    
    (case when english >= 85 then '优秀' when english >= 60 then '及格' else '不及格' end) as '英语',
    
    (case when chinese >= 85 then '优秀' when chinese >= 60 then '及格' else '不及格' end) as '语文'
    
from score;




约束

在这里插入图片描述

约束的描述信息,在information_schema 库中的 table_constraints表中


列级约束

直接在字段后面是列级约束
create table test (
	id int 约束1 约束2.....,
	name varchar(20) 约束1 约束2....
);

表级约束

定义完,再约束是表记约束。比如联合不能重复的时候就要用到
create table test (
	id int,
	name varchar(20),
	//这里表示 id 和 name联合不能重复 
	unique(id, name)
);

例子

create table user (
    id int  primary key auto_increment 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 '性别'
) comment '用户表';

insert into user(name, age, status, gender) values ('Tom1', 19, '1','男'), ('Tom2', 25, '0', '男');

在这里插入图片描述

插入数据可以不用,写id字段,他会自动自增

多个约束之间不用逗号



外键约束

在这里插入图片描述


语法

在这里插入图片描述

-- 添加外键到 emp 表 别名为 fk_emp_dept_id 关联到父表dept 的 id 
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY REFERENCES dept(id)

-- 删除外键
ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept_id

-- 表中的外键
create table user (
    id int  primary key auto_increment 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 '性别',
    uid int,
    constraint fk_user_dept_id foreign key (uid) references dept(id)
) comment '用户表';

只要外键关联了记录,父表直接删除会报错,保证了数据的一致性和完整性

constraint 是起别名,foreign key…references 是外键


删除/更新行为
在这里插入图片描述

on update 是在更新时怎样,delete 是删除

ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY REFERENCES dept(id) ON UPDATE CASCADE ON DELETE CASCADE;



多表查询

笛卡尔积现象

在这里插入图片描述

用关联的字段消除笛卡尔积现象

-- dept 的 id 字段是 emp 的 dept_id 的外键
select * from emp , dept where emp.dept_id = dept.id;


内连接

在这里插入图片描述

SELECT emp.name, emp.dept_id FROM emp, dept WHERE emp.dept_id = dept.id;
SELECT emp.name, dept.id FROM emp INNER JOIN dept ON emp.dept_id = dept.id;

如果给表起了别名,就不能再通过表名限定字段了



外连接

在这里插入图片描述

外连接是除了满足条件的记录查询出来,再将其中一张表的记录查询出来,另一张表如果没有与之匹配的记录,自动模拟出 NULL 与其匹配



自连接

在这里插入图片描述

看成两张表找关联的字段



联合查询

把多次查询的结果合并起来,形成新的查询结果

在这里插入图片描述

把 all 去掉自动去重

多张表的字段数量和类型必须保持一致



子查询

标量子查询

子查询返回的结果是单个值。

-- 查询 "方东白" 入职之后的员工信息
select * from emp where datediff(entrydate, (select entrydate from emp where name = '方东白') ) > 0;
select entrydate from emp where name = '方东白'


列子查询

子查询返回的结果是一列(可以是多行)

常用操作符:IN, NOT IN, ANY, SOME, ALL

在这里插入图片描述



行子查询

子查询返回的结果是一行(可以是多行)

常用操作符:=, <>, IN, NOT, IN

select managerid, salary from emp where name = '张无忌';

--查询与张无忌薪资和直属领导相同的员工信息
select * from emp where (managerid, salary) = (select managerid, salary from emp where name = '张无忌');


表子查询

子查询返回的结果是多行多列,一张表

常用操作符 : IN

经常当临时表。或者 in

select * from emp where (job, salary) in (select job, salary from emp where name in ('鹿杖客', '宋远桥'));

job salary 这个组合要么满足下面,要么满足上面

在这里插入图片描述




事务

事物就是一个最小的工作单元,在数据库中,事物表示一件完整的事

例如:一个业务的完成可能需要多条DML语句共同配合才能完成,例如转账业务,需要执行两条DML语句,先更新张三账户的余额,再更新李四账户的余额,为了保证转账业务不出现问题,就必须保证要么同时成功,要么同时失败,怎么保证同时成功或者同时失败呢?就需要使用事务机制。

默认 mysql 事务在执行一条 DML 语句时会自动提交



事务操作

第一种方式:设置autocommit 为 0 手动提交

在这里插入图片描述


第二种方式手动开启事务

在这里插入图片描述



事务四大性质

**在这里插入图片描述
**

事务只针对DML语句有效:因为只有这三个语句是改变表中数据的。

  1. insert
  2. delete
  3. update


并发事务引发的问题

在这里插入图片描述

脏读

一个事务读取了,另一个事务未提交的数据。就是读取到了另一个事务中的脏数据。在这种情况下,如果事物回滚或者修改了这些数据,那么读取这些脏数据的事务所处理的数据就是不准确的。

不可重复读

一个事务内,多次读取同一个数据行。得到的结果可能不一样。这是由于其他事务对数据进行了修改操作。导致数据的不一致性

幻读

事务执行过程中,前后两次相同的查询条件得到的结果不一,可能会变多或变少



事务隔离级别

在这里插入图片描述

  • 隔离级别从低到高:读未提交 < 读提交 < 读可重复读 < 串行化

  • 现象的严重程度从低到高:幻读 < 不可重复读 < 脏读

mysql 默认是 重复读,Oracal 默认是 读提交


语法

在这里插入图片描述

select @@transaction_isolation -查看当前会话隔离级别
select @@gobal.transaction_isolation -查看全局的隔离级别

会话级:set session transaction isolation level 事务隔离级别
全局级:set global transaction isolation level 事务隔离级别

事务隔离级别:
1.read uncommitted
2.read committed
3.repeatable read
4.serializable

读未提交(READ UNCOMMITTED)

A事务与B事务,A事务可以读取到B事务未提交的数据。这是最低的隔离级别。几乎两个事务之间没有隔离。这种隔离级别是一种理论层面的,在实际的数据库产品中,没有从这个级别起步的。


读提交 (READ COMMITTED)

A事务与B事务,A事务可以读取到B事务提交之后的数据。Oracle数据库默认的就是这种隔离级别。


可重复读 (REPECTABLE READ)

A事务和B事务,A事务开启后,读取了某一条记录,然后B事务对这条记录进行修改并提交,A事务读取到的还是修改前的数据。这种隔离级别称为可重复读。MySQL数据库默认就是这种隔离级别。


串行化 (SERIALIZABLE)

这种隔离级别最高,避免了所有的问题,缺点是效率低,因为这种隔离级别会导致事务排队处理,不支持并发。



解决幻读

可重复读,能很大程度上避免了幻读问题,但是并不能完全解决。


快照读解决幻读

普通的 select 语句都是采用快照读。(类似就是把那个时间段的表数据,保留下来。)

原理:

​ 由 MVCC(多版本并发控制) 实现,实现的方式是开始事务后会创建一个 Read View 对象,后续查询语句利用整个 Read View,通过这个 Read View 就可以在 undo log 版本链找到快照查询执行时候的那个版本的数据。所以事务过程中每次快照查询数据都是一样的,即使中途有其他事务插入了新记录,是查询不出来这条数据的。避免了幻读


当前读解决幻读

当前读包括:update、delete、insert、select…for update。就是 DML 加上 for update。单独执行 DML 语句也会隐式执行当前读

原理:

select…for update加的锁叫做:next-key lock。我们可以称其为:间隙锁 + 记录锁。间隙锁用来保证在锁定的范围内不允许insert操作。记录锁用来保证在锁定的范围内不允许delete和update操作。提交后锁失效

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值