超级无敌详细的Mysql数据库笔记(基础篇版)

注:本篇笔记根据黑马程序员 MySQL数据库入门到精通的内容所创建,适合复习和结合该视频学习使用。

一.基础

1.关系型数据库(RDBMS)

  • 概念:建立在关系模型基础上,由多张相互连接的二维表组成的数据库。
  • 特点:使用表存储数据,格式统一,便于维护使用SQL语言操作,标准统一,使用方便。

2.SQL

SQL通用语法

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

SQL分类

分类 全称 说明
DDL Data Definition Language 数据定义语言,用来定义数据库对象(数据库,表,字段)
DML Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改
DQL Data Query Language 数据查询语言,用来查询数据库中表的记录
DCL Data Control Language 数据控制语言,用来创建数据库用户、控制数据库的访问权限

DDL

数据库操作

  • 查询所有数据库

    SHOW DATABASES;
    
  • 查询当前数据库

    SELECT DATABASE();
    
  • 创建

    #[]中的内容可选,字符集推荐utf8mb4
    CREATE DATABASE [IF NOT EXISTS]数据库名[DEFAULT CHARSET字符集][COLLATE 排序规则];
    
  • 删除

    DROP DATABASEIF EXISTS]数据库名;
    
  • 使用

    USE 数据库名;
    

表操作

  • 查询当前数据库所有表

    SHOW TABLES;
    
  • 查询表结构

    DESC 表名;
    
  • 查询指定表的建表语句

    SHOW CREATE TABLE 表名;
    
  • 创建表

    #[]中内容为可选内容
    CREATE TABLE 表名(
    	字段1 字段1类型 [COMMENT 字段1注释],
      	字段2 字段2类型 [COMMENT 字段2注释],
    	字段3 字段3类型 [COMMENT 字段3注释],
    	......
        字段n 字段n类型 [COMMENT 字段n注释1]
    )[COMMENT 表注释];
    
  • 添加字段

    ALTER TABLE 表名 ADD 字段名 类型(长度)[COMMENT 注释][约束];
    
  • 删除字段

    ALTER TABLE 表名 DROP 字段名;
    
  • 修改字段

    • 修改数据类型

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

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

    ALTER TABLE 表名 RENAME TO 新表名;
    
  • 删除表

    DROP TABLE [IF EXISTS] 表名;
    
  • 删除指定表,并重新创建该表(数据被清空)

    TRUNCATE TABLE 表名;
    

数据类型

类型 大小 描述
TINYINT 1 byte 小整数值
SMALLINT 2 bytes 大整数值
MEDIUMINT 3 bytes 大整数值
INT或INTEGER 4bytes 大整数值
BIGINT 8 bytes 极大整数值
FLOAT 4 bytes 单精度浮点数值
DOUBLE 8 bytes 双精度浮点数值
DECIMAL 小数值(精确定点数)
  • 注:以上都有对应的无符号和有符号数,即在类型后加signed和unsigned,特别注意decimal依赖于M(精度,总位数)和D(标度,小数位数)的值。

  • 例:

age tinyint unsigned
socre double(4,1) #范围: 0.0~100.0

类型 大小 描述
CHAR 0-255 bytes 定长字符串
VARCHAR 0-65535 bytes 变长字符串
TINYBLOB 0-255 bytes 不超过255个字符的二进制数据
TINYTEXT 0-255 bytes 短文本字符串
BLOB 0-65535 bytes 二进制形式的长文本数据
TEXT 0-65535 bytes 长文本数据
MEDIUMBLOB 0-16777215 bytes 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16777215 bytes 中等长度文本数据
LONGBLOB 0-4294967295bytes 二进制形式的极大文本数据
LONGTEXT 0-4294967295 bytes 极大文本数据
  • 注: char和varchar在使用时要规定字符串的最大长度,char为填满部分用空格填充,而varchar则为实际的长度大小。char性能相对varchar更高。
  • 例:
用户名 username varchar(50)
性别 gender char(1)

大小 范围 格式 描述
DATE 1000-01-01至9999-12-31 YYYY-MM-DD 日期值
TIME -838:59:59至838:59:59
HH:MM:SS 时间值或持续时间
YEAR 1901 至 2155 YYYY 年份值
DATETIME 1000-01-0100:00:00至9999-12-3123:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值
TIMESTAMP 1970-01-01 00:00:01至2038-01-19 03:14:07 YYYY-MM-DD HH:MM:SS 混合日期和时间值,时间戳

例:

 birthday date

DML

  • 添加数据 INSERT

    #给指定字段添加数据
    INSERT INTO 表名 (字段名1,字段名2,) VALUES(1,2,);
    #给全部字段添加数据
    INSERT INTO 表名 VALUES (1,2,);
    #批量添加数据
    INSERT INTO 表名 (字段名1,字段名2,) VALUES(1,2,),(1,2,),(1,2,);
    INSERT INTO 表名 VALUES (1,2,),(1,2,),(1,2,);
    

    注意:

    • 插入数据时,指定的字段顺序需要与值的顺序是-一对应的。
    • 字符串和日期型数据应该包含在引号中。
    • 插入的数据大小,应该在字段的规定范围内。
  • 修改数据 UPDATE

     #修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据。
     UPDATE 表名 SET 字段名1=1,字段名2=2,... [WHERE 条件];
    
  • 删除数据 DELETE

    #where条件同上
    DELETE FROM 表名 [WHERE 条件]
    

    注意:DELETE语句不能删除某一个字段的值(可以使用UPDATE将该字段设置为null)。

DQL

语法
SELECT
	字段列表
FROM
	表名列表
WHERE
	条件列表
GROUP BY
	分组字段列表
HAVING
	分组后条件列表
ORDER BY
	排序字段列表
LIMIT
	分页参数

注: 必须按照以上顺序书写。

各个部分解释

基本查询
  • 查询多个字段

    SELECT 字段1,字段2,字段3...FROM 表名;
    #尽量不要写*通配符,不直观,应遵循公司的开发规范
    SELECT * FROM 表名;
    
  • 设置别名

    #AS可省
    SELECT 字段1 [AS 别名1],字段2 [AS 别名2]... FROM 表名;
    
  • 去除重复记录

    SELECT DISTINCT 字段列表 FROM 表名;
    
条件查询
  • 语法

    SELECT 字段列表 FROM 表名 WHERE 条件列表;
    
  • 条件

    1. > , < , >= ,<= , = , !=或<>
    2. BETWEEN …AND… (在某个范围内,包含端点),IN(…) 多选一
    3. LIKE 占位符 (模糊匹配,_代表单个字符, % 代表任意个字符)
    4. IS NULL (等于NULL)
    5. AND 或 &&, OR 或 || ,NOT 或 !
聚合函数
  1. 介绍: 将一列数据作为一个整体,进行纵向计算。

  2. 常见集合函数

    函数 功能
    count 统计数目,null值不参与计算
    max 最大值
    min 最小值
    avg 平均值
    sum 求和
  3. 语法

    SELECT 聚合函数(字段列表) FROM 表名;
    
分组查询
  1. 语法

    SELECT 字段列表 FROM 表名[WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];
    
  2. where和having的qub

    • 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。
    • 判断条件不同:where不能对聚合函数进行判断,而having可以。
  3. 注意

    • 执行顺序: where >聚合函数>having
    • 分组之后,查询的字段一般为聚合函数和分组之后的字段,查询其他字段无任何意义。
排序查询
  1. 语法

    SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1,字段2 排序方式2;
    
  2. 排序方式: ASC(升序,默认), DESC(降序)

  3. 如果是多字 排序,当第一个字段值相同时,才会根据第二个字段进行排序。

分页查询
  1. 语法

    SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询记录数;
    
  2. 注意

    • 起始索引从0开始,起始索引=(查询页码-1)*每页显示记录数。

    • 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT。

    • 如果查询的是第一页数据,起始索引可以省略,直接简写为limit 10。

DCL

管理用户

这类SQL开发人员操作的比较少,主要是DBA(Database Administrator数据库管理员)使用。

  1. 查询用户

    USE mysql;
    SELECT * FROM user;
    

    注:用户的访问权限信息都是存储在系统数据库mysql中的user表中,且通过用户名和主机名来确定一个用户,本机localhost,任意主机%

  2. 创建用户

    CREATE USER '用户名'@'主机名’ IDENTIFIED BY '密码’;
    
  3. 修改用户密码

    #mysql_native_password 为mysql的本地密码处理方式
    ALTER USER'用户名'@'主机名’IDENTIFIED WITH mysql_native_password BY '新密码’;
    
  4. 删除用户

    DROP USER '用户名'@'主机名’;
    
权限控制
权限

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

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

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

  1. 查询权限

    SHOW GRANTS FOR '用户名'@'主机名';
    
  2. 授予权限

    GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名’;
    
  3. 撤销权限

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

3.函数

字符串函数

函数 功能
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个长度的字符串

语法:

SELECT 函数(参数);

数值函数

函数 功能
CEIL(x) 向上取整
FLOOR(x) 向下取整
MOD(x,y) 取模
RAND() 返回0-1内随机数
ROUND(x,y) 对x四舍五入,保留y位小数

日期函数

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

流程函数

函数 功能
lF(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默认值

4.约束

概念

约束是作用于表中字段上的规则,用于限制存储在表中的数据。目的是保证数据库中数据的正确、有效性和完整性。

分类

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

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

代码示例

要求:

字段名 类型 约束条件 约束关键字
id int 主键,并且自动增长 PRIMARY KEY, AUTO_INCREMENT
name varchar(10) 不为空,并且唯一 NOT NULL, UNIOUE
age int 大于0,并且小于等于120 CHECK
status char(1) 如果没有指定该值,默认为1 DEFAULT
gender char(1)

代码:

create table user(
	id int primary key auto_increment comment'主键',
    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 '用户表';

外键约束

1.添加外键

--第一种
CREATE TABLE 表名(
	字段名 数据类型,
    ...
	[CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) REFERENCES 主表	(主表列名)
);
--第二种   
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名);

2.删除外键

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

3.外键删除更新行为

行为 说明
NO ACTION 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 RESTRICT 一致)
RESTRICT 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除更新。(与 NO ACTION一致)
CASCADE 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。
SET NULL 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求该外键允许取null)。
SET DEFAUL 父表有变更时,子表将外键列设置成一个默认的值(Innodb,mysql的默认引擎不支持)

语法

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名(主表字段名) ON UPDATE 行为 ON DELETE 行为;

5.多表查询

多表关系

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

一对多(多对一):在多的一方建立外键,指向一的一方的主键

多对多:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

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

多表查询概述

1.概述:多表查询会产生笛卡尔乘积,即两个集合A集合 和 B集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)。

2.分类

连接查询

  • 内连接: 相当于查询A、B交集部分数据
  • 外连接:
    • 左外连接:查询左表所有数据,以及两张表交集部分数据
    • 右外连接:查询右表所有数据,以及两张表交集部分数据
  • 自连接:当前表与自身的连接查询,自连接必须使用表别名

子连接

内连接

隐式内连接

SELECT 字段列表 FROM1,2 WHERE 条件…;

#如
select emp.name,dept.name from emp ,dept where emp.dept id = dept.id;

显式内连接

SELECT 字段列表 FROM1 [INNER] JOIN2 ON 连接条件…;

#如
Select e.name, d.name from emp e inner join dept d on e.dept_id = d.id;

外连接

左外连接

SELECT 字段列表 FROM1 LEFT[OUTER] JOIN2 ON 条件...;

#查询emp表的所有数据,和对应的部门信息(左外连接)
select e.*,d,name from emp e left outer join dept d on e.dept id = d.id;

右外连接

SELECT 字段列表 FROM1 RIGHT [OUTER] JOIN2 ON 条件...;

#查询dept表的所有数据,和对应的员工信息(右外连接)
select d.*,e,* from emp e right outer join dept d on e.dept id = d.id;

注:一般用左外连接,因为二者可互相转换。

自连接

SELECT 字段列表 FROM 表A别名A JOIN 表A 别名B ON 条件...;

#1.查询员工及其 所属领导的名字
select a.name ,b.name from emp a,emp b where a.managerid = b.id;
#2.查询所有员工emp及其领导的名字emp,如果员工没有领导,也需要查询出来
select a.name '员T',b.name '领导' from emp a left join emp b on a.managerid = b.id;

注:自连接查询,可以是内连接查询,也可以是外连接查询。且自连接必须使用表别名

联合查询-union,union all

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

SELECT 字段列表 FROM 表A...
UNION [ALL]
SELECT 字段列表 FROM 表B

如: 将薪资低于5000的员工,和年龄大于50 岁的员工全部查询出来.

select *from emp where salary<5000
union all
select *from emp where age >50;

#发现结果出现重复
------------------------------------------
select *from emp where salary<5000
union 
select *from emp where age >50;

#结果无重复

总结:对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重。

子查询

1.概述

  • SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询

  •   SELECT *FROM t1 WHERE column1=(SELECT column1 FROM t2);
    

    子查询外部的语句可以是INSERT/UPDATE/DELETE/SELECT的任何一个。

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

    • 标量子查询(子查询结果为单个值)
    • 列子查询(子查询结果为一列)
    • 行子查询(子查询结果为一行)
    • 表子查询(子查询结果为多行多列)
  • 根据子查询位置,分为:WHERE之后、FROM之后、SELECT之后。

2.标量子查询

概述:子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询成为标量子查询。常用的操作符: = ,<>,> , >= , <=

案列:查询“销售部”的所有员工信息

#可分为两步:查询“销售部”部门ID,根据销售部部门ID,查询员工信息
select id from dept where name ='销售部';#得到id=4
select * from emp where dept_id = 4;

#结合两步,用标量子查询
select * from emp where dept id =(select id from dept where name ='销售部');

3.列子查询

子查询返回的结果是一列(可以是多行),这种子查询称为列子查询,常用的操作符: INNOTINANYSOMEALLL

解释:

  • IN—在指定的集合范围之内,多选一
  • NOT IN—不在指定的集合范围之内
  • ANY—子查询返回列表中,有任意一个满足即可
  • SOME—与ANY等同,使用SOME的地方都可以使用ANY
  • ALL—子查询返回列表的所有值都必须满足

案例:

  • 查询“销售部”和“市场部”的所有员工信息

    select * from emp where dept_id in (select id from dept where name ='销售部'or name ='市场部');
    
  • 查询比 财务部 所有人工资都高的员工信息

    select * from emp where salary > all ( select salary from emp where dept id = (select id from dept where name = '财务部') );
    

4.行子查询

概述:子查询返回的结果是一行(可以是多列),这种子查询称为行子查询常用的操作符: =、<>、INNOT IN

案例:查询与"张无忌”的薪资及直属领导相同的员工信息

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

5.表子查询

概述:子查询返回的结果是多行多列,这种子查询称为表子查询常用的操作符: IN

案例

  • 查询与“鹿杖客” “宋远桥”的职位和薪资相同的员工信息

    select * from emp where (job,salary) in ( select job, salary from emp where name = '鹿杖客'or name ='宋远桥’);
    
  • 查询入职日期是“2006-01-01”之后的员工信息,及其部门信息

    select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept id = d.id ;
    

6.事务

概述

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

操作

1.第一种方式

MySQL中的事务是默认自动提交的,我们也可以手动修改。

# @@autocommit为1为自动提交,为0为手动提交
SELECT @@autocommit,
SET @@autocommit=0

手动提交中,提交事务

COMMIT;

回滚事务

ROLLBACK;

2.第二种方式

开启业务

#表明手动提交
START TRANSACTIONBEGIN;

提交任务

COMMIT ;

回滚事务

ROLLBACK;

业务操作全部执行成功才提交,一旦出错就必须回滚业务。

四大特性

  • 原子性(Atomicity): 事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency): 事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(lsolation): 数据库系统提供的隔离机制,保证各个事务在不受外部并发操作影响的独立环境下运行。
  • 持久性(Durability): 事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

并发事务问题

多个事务并发执行时出现的问题

问题 描述
脏读 一个事务读到另外一个事务还没有提交的数据。
不可重复读 一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
幻读 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻影”。

事务隔离级别

隔离级别 赃读 不可重复读 幻读
Read uncommitted
Read committed ×
Repeatable Read(MySQL默认) × ×
Serializable × × ×

注:√ 表示会出现上述问题,× 表示不会出现

查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

设置事务隔离级别

#SESSION表示对当前会话有效,GLOBALBL表示对全部生效
SET [SESSIONI或GLOBAL] TRANSACTION ISOLATION LEVEL {四种隔离级别}

注意:事务隔离级别越高,数据越安全,但是性能越低。

你可能感兴趣的:(mysql,数据库,笔记)