大话 MySQL 数据库 -- 强推收藏!
数据库简介
数据库的基本概念:用于存储和管理数据的仓库。英文名为 DataBase ,简称为 DB。
数据库特点:
- 1.持久化存储数据,其本身是一个文件系统。
- 2.方便存储和管理数据。
- 3.使用了统一的方式操作数据库。
数据库的分类:
- 网状结构数据库:以节点形式存储和访问。
- 层次结构数据库:以定向有序的树状结构实现存储和访问。
- 关系结构数据库:Oracle、DB2、MySQL 等,以表格(Table)存储,多表间建立关系联系,通过分类、合并、连接、选取等运算实现访问。
- 非关系型数据库:Redis 等,多数使用哈希表,表中以键值对(key-value)的方式实现特定的键和一个指针指向的特定数据。
MySQL
MySQL应用:对于数据库的操作,需要进入MySQL环境下进行指令输入,并在一句指令的末尾使用分号(;)结束。
基本命令
1.查看MySQL中的所有数据库
SHOW DATABASES;
2.创建自定义数据库
CREATE DATABASE db1; # 创建名为db1的数据库
CREATE DATABASE db2 CHARACTER SET utf8; # 创建名为db2的数据库并设置编码集为utf8,注意在SQL中utf-8没有-,写为utf8
CREATE DATABASE db3 IF NOT EXISTS db3; # 如果db3数据库不存在,就创建
3.查看数据库创建信息
SHOW CREATE DATABASE db2;
回车就可以看到:
4.修改数据库
ALTER DATABASE db2 CHARACTER SET utf8; # 将db2的编码集修改为utf8
修改完成后再次执行上方查看数据库创建信息的代码,就可以看到:
5.删除数据库
DROP DATABASE db2;
删除数据库db2之后,再执行上方查看所有数据库的命令,就没有db2这个数据库了:
6.查看当前使用的数据库
SELECT DATABASE();
由于当前没有使用的数据库,执行上述代码可以看到:
7.使用数据库
USE db1;
执行上述语句并且再次查看当前使用的数据库就可以看到在使用db1了:
图形化界面工具SQLyog
没有安装该工具的小伙伴可以点击这里,提取码:6cpi ,下载安装喔!
刚安装好的小伙伴的用户名和密码是不能填的,要先点击新建,再填入用户名和密码,点击连接就可以了。
这就是SQLyog的界面了,有想修改字体大小的小伙伴可以点击工具-首选项-字体编辑设置就可以设置字体大小了。
数据查询
数据库表的基本结构:
关系结构数据库是以表格(Table)进行数据存储,表格由行和列组成。执行查询语句返回的结果集是一张虚拟表。
下面的演示都是基于这个表:点击,提取码:rszj ,小伙伴可以下载这个数据库,并导入到提前创建好的数据库中:
1.基本查询:
语法:SELECT 列名 FORM 表名
关键字 | 描述 |
---|---|
SELECT | 指定要查询的列 |
FORM | 指定要查询的表 |
1.1 查询部分列:将要查询的部分列的列名写上
1.2 查询所有列:可以将所有列的列名写上,也可以用 * 代替
# 查询部分列
SELECT EMPLOYEE_ID,FIRST_NAME,email FROM t_employees;
# 查询所有列,用*或者所有列名
SELECT * FROM t_employees;
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID FROM
t_employees;
选中要执行的代码,按F9或者右键执行查询里面的执行查询或者点击左上角的执行查询按钮,如图:
分别执行查询部分列和所有列,可以看到如下结果:
1.3 对列中的数据进行运算
注:运算操作的是虚拟表中的数据,原来表格数据不会改变。
算数运算符 | 描述 |
---|---|
+ | 两列做加法 |
- | 两列做减法 |
* | 两列做乘法 |
/ | 两列做除法 |
1.4 列的别名(修改表头)
列 AS ‘列名’
# 对表中的数据进行运算,+-*/,而%是占位符号,不是取模。
SELECT EMPLOYEE_ID,FIRST_NAME,SALARY*12 FROM t_employees;
# 修改表头
SELECT EMPLOYEE_ID AS '员工编号',FIRST_NAME AS '姓氏',SALARY*12 AS '年薪' FROM t_employees;
执行以上代码,可以看到:
1.5 查询结果去重
DISTINCT 列名
# 去掉重复的
SELECT DISTINCT manager_id FROM t_employees;
2.排序查询
语法:SELECT 列名 FROM 表名 ORDER BY 排序列 [排序规则]
排序规则 | 描述 |
---|---|
ASC | 升序排列 |
DESC | 降序排列 |
2.1 依据单列排序
# 依据员工工资排序
SELECT employee_id,first_name,salary FROM t_employees ORDER BY CAST(salary AS SIGNED) DESC;
SELECT employee_id,first_name,salary FROM t_employees ORDER BY CONVERT(salary,DECIMAL) ASC;
注:员工工资是字符串类型,这里需要将字符串类型转换为数字类型才可以正确排序。
可以使用 CAST(salary AS SIGNED),也可以使用 CONVERT(salary,DECIMAL)。
2.2 依据多列进行排序
# 依据员工工资排序,工资相同时,按照编号升序排序
SELECT employee_id,first_name,salary FROM t_employees
ORDER BY CAST(salary AS SIGNED) DESC,CAST(employee_id AS SIGNED) ASC;
运行以上代码,就可以看到这些工资相同的按照编号排序了:
3.条件查询
语法:SELECT 列名 FROM 表名 WHERE 条件
WHERE 条件筛选符合条件的查询结果,条件为布尔表达式。
3.1 等值判断(=)
# 查询工资为11000的员工
SELECT employee_id,first_name,salary
FROM t_employees
WHERE salary = 11000;
注:在MySQL中一个等号(=)就代表等值判断
3.2 逻辑判断(and,or,not)
# 查询工资是11000并且commission_pct是0.30的员工
SELECT employee_id,first_name,salary,commission_pct
FROM t_employees
WHERE salary = 11000 AND commission_pct = 0.30;
# 查询工资是11000或者commission_pct是0.30的员工
SELECT employee_id,first_name,salary,commission_pct
FROM t_employees
WHERE salary = 11000 OR commission_pct = 0.30;
# 查询工资不等于11000的员工
SELECT employee_id,first_name,salary,commission_pct
FROM t_employees
WHERE NOT salary = 11000;
3.3 不等值判断(>,<,>=,<=,!=,<>)
# != 和 <> 都是不等于的意思,查询工资不等于11000的员工
SELECT employee_id,first_name,salary,commission_pct
FROM t_employees
WHERE salary <> 11000;
3.4 区间判断(between and)
# 查询工资在6000到10000的员工
SELECT employee_id,first_name,salary
FROM t_employees
WHERE salary BETWEEN 6000 AND 10000;
3.5 NULL值判断(IS NULL,IS NOT NULL)
# 查询出经理信息为null的员工信息
SELECT employee_id,first_name,manager_id
FROM t_employees
WHERE manager_id IS NULL;
3.6 枚举判断(IN(值1,值2,值3…))
# 查询department_id是60或70或80或90的员工
SELECT employee_id,first_name,department_id
FROM t_employees
WHERE department_id IN(60,70,80,90);
3.7 模糊查询
LIKE_ 表示任意单个字符
语法:列名 LIKE ‘张_’ (查询姓氏是张,且名字只有两个字的人)
LIKE% 表示任意长度的任意字符
语法:列名 LIKE ‘张%’ (查询姓氏是张的人)
# 查询名字以S开头的员工
SELECT employee_id,first_name,department_id
FROM t_employees
WHERE first_name LIKE 'S%';
# 查询名字以S开头并且长度为4的员工
SELECT employee_id,first_name,department_id
FROM t_employees
WHERE first_name LIKE 'S____';
3.8 分支结构查询
CASE
WHEN 条件一 THEN 结果一
WHEN 条件二 THEN 结果二
WHEN 条件三 THEN 结构三
ELSE 结果
END
# 按员工工资进行分等级
SELECT employee_id,first_name,salary,
CASE
WHEN salary >= 10000 THEN 'A'
WHEN salary >= 8000 AND salary < 10000 THEN 'B'
WHEN salary >= 6000 AND salary < 8000 THEN 'C'
ELSE 'D'
END AS '薪资级别'
FROM t_employees;
4.时间查询
语法:SELECT 时间函数(参数列表)
时间函数 | 描述 |
---|---|
SYSDATE() | 当前系统时间(年月日时分秒) |
CURDATE() | 当前日期 |
WEEK(DATE) | 获取指定日期为一年中的第几周 |
YEAR(DATE) | 获取指定日期的年份) |
HOUR(TIME) | 获取指定时间的小时值 |
MINUTE | 获取指定时间的分钟值 |
DATEDIFF(DATE1,DATE2) | 获取DATE1,DATE2之间相隔的天数 |
ADD(DATE,N) | 计算DATE加上N天后的日期 |
SELECT SYSDATE();
SELECT CURDATE();
SELECT CURTIME();
SELECT WEEK('2020-10-4');
SELECT YEAR('2020-10-4');
SELECT DATEDIFF('2020-10-4','2020-9-4');
SELECT ADDDATE('2020-10-4',10);
5.字符串查询
语法:SELECT 字符串函数(参数列表)
字符串函数 | 说明 |
---|---|
CONCAT(str1,str2…) | 将多个字符串连接 |
INSERT(str,pos,len,newStr) | 将str中指定pos位置开始len长度的内容替换为newStr |
LOWER(str) | 将指定字符串转换为小写 |
UPPER(str) | 将指定字符串转换为大写 |
SUBSTRING(str,num,len) | 将str字符串指定num位置开始截取len个内容 |
# 多个字符串拼接
SELECT CONCAT('My','S','QL');
SELECT CONCAT(first_name,last_name) AS '姓名' FROM t_employees;
# 将指定字符串转换为小写
SELECT LOWER('MySQL'); # mysql
# 将指定字符串转换为大写
SELECT UPPER('MySQL'); # MYSQL
# 字符串的替换,这里注意字符串下标从1开始
SELECT INSERT('这是一个数据库',3,2,'MySQL'); # 这是MySQL数据库
# 字符串截取
SELECT SUBSTRING('JavaMySQLOracle',5,5); # MySQL
6.聚合函数
语法:SELECT 聚合函数(列名) FROM 表名;
聚合函数 | 说明 |
---|---|
SUM() | 求一列的和 |
AVG() | 求平均值 |
MAX() | 求最大值 |
MIN() | 最小值 |
COUNT() | 求总行数 |
# 求所有员工的工资之和
SELECT SUM(salary) FROM t_employees;
# 求所有员工的平均工资
SELECT AVG(salary) FROM t_employees;
# 求最高工资
SELECT MAX(CAST(salary AS SIGNED)) FROM t_employees;
# 求最低工资
SELECT MIN(CAST(salary AS SIGNED)) FROM t_employees;
# 求该表有多少行
SELECT COUNT(salary) FROM t_employees;
7.分组查询
语法:SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组依据(列);
关键字GROUP BY必须在WHERE 之后生效
# 查询各部门的总人数
SELECT department_id,COUNT(employee_id)
FROM t_employees
GROUP BY department_id;
# 查询各部门的平均工资
SELECT department_id,AVG(salary)
FROM t_employees
GROUP BY department_id;
# 查询各个部门各个岗位的人数
SELECT department_id,job_id,COUNT(employee_id)
FROM t_employees
GROUP BY department_id,job_id;
查询各个部门各个岗位的人数运行结果如下:
注:分组查询中,select显示的列只能是分组依据列,或者是聚合函数列,不能出现其他列。
8.分组过滤查询
语法:SELECT 列名 FROM 表名 GROUP BY 分组列 HAVING 过滤规则
关键字HAVING是过滤规则,对分组后的数据进行过滤
# 统计60,70,80部门的最高工资
SELECT department_id,MAX(salary)
FROM t_employees
GROUP BY department_id
HAVING department_id IN (60,70,80);
执行过程:
- group确定分组依据department_id
- having过滤出60,70,80的部门
- select查看部门编号和执行max函数
9.限定查询
SELECT 列名 FROM 表名 LIMIT 起始行,查询行数
关键字 | 说明 |
---|---|
LIMIT start,count | 限定查询结果的起始行和总行数 |
# 查询表中前5行数据
SELECT * FROM t_employees LIMIT 0,5;
# 指定任意的查询范围,从表中的第3条数据开始,查询10条
SELECT * FROM t_employees LIMIT 2,10;
注:起始行从0开始,代表了第一行,第二个参数代表了从指定行开始查询几行
10.查询总结
SQL语句编写顺序:
SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组 HAVING 过滤条件 ORDER BY 排序列(asc|desc)LIMIT 起始行,总条数
SQL语句执行顺序:
1.FROM:指定数据来源表
2.WHERE:对查询数据做第一次过滤
3.GROUP BY:分组
4.HAVING:对分组后的数据做第二次过滤
5.SELECT:查询各字段的值
6.ORDER BY:排序
7.LIMIT:限定查询结果
11.子查询
SELECT 列名 FROM 表名 WHERE 条件(子查询结果)
# 查询工资大于Bruce的员工
# 先查询到Bruce的工资
SELECT * FROM t_employees WHERE first_name = 'Bruce'; # 从查询结果中看到Bruce工资是6000
# 再查询大于Bruce工资的员工
SELECT * FROM t_employees WHERE salary > 6000;
# 使用子查询,将两行合并,将子查询的结果作为外部查询的条件
SELECT * FROM t_employees
WHERE salary > (SELECT salary FROM t_employees WHERE first_name = 'Bruce');
12.子查询(作为枚举查询条件)
SELECT 列名 FROM 表名 WHERE 列名 IN(子查询结果)
# 查询与名字为King的员工在同一部门的员工
# 原来的查询方式
SELECT * FROM t_employees WHERE last_name = 'King';
SELECT * FROM t_employees WHERE department_id IN (80,90);
# 子查询,将子查询多行一列的结果作为外部查询的枚举查询条件,做第二次查询
SELECT * FROM t_employees
WHERE department_id IN (SELECT department_id FROM t_employees WHERE last_name = 'King');
# 查询高于60部门所有人的工资的员工信息
SELECT * FROM t_employees
WHERE salary > ALL(SELECT salary FROM t_employees WHERE department_id = 60);
13.子查询(作为一张表)
SELECT 列名 FROM (自查询的结果集)WHERE 条件;
# 查询表中工资排名前五的员工信息
SELECT employee_id,first_name,salary
FROM(SELECT employee_id,first_name,salary FROM t_employees ORDER BY CAST(salary AS SIGNED) DESC) AS temp
LIMIT 0,5;
注:子查询是一张临时表时,要为其赋予一张临时表名
14.合并查询
SELECT * FROM 表名1 UNION SELECT * FROM 表名2
SELECT * FROM 表名1 UNION ALL SELECT * FROM 表名2
合并两张表的结果并且去除重复记录:
SELECT * FROM sheet1 UNION SELECT * FROM sheet2;
合并两张表的结果保留重复记录:
SELECT * FROM sheet1 UNION ALL SELECT * FROM sheet2;
15.表连接查询
SELECT 列名 FROM 表1 连接方式 表2 ON 连接条件
内连接查询(INNER JOIN):
# 内连接查询,共有19种jobs,分别与每一个人对应起来,等于给第一个表扩展了几列数据
SELECT * FROM t_employees
INNER JOIN t_jobs
ON t_employees.`JOB_ID` = t_jobs.`JOB_ID`;
三表连接查询:
# 查询所有员工工号,部门名称,所在国家ID
SELECT employee_id,t_employees.department_id,t_locations.location_id FROM t_employees
INNER JOIN t_departments
ON t_employees.department_id = t_departments.department_id
INNER JOIN t_locations
ON t_locations.location_id = t_departments.location_id;
左外连接(LEFT JOIN ON):
# 查询所有员工信息,以及所对应的部门名称(没有部门的员工,部门以null填充)
SELECT employee_id,first_name,salary,department_name FROM t_employees
LEFT JOIN t_departments
ON t_departments.department_id = t_employees.department_id;
左外连接是以左表为主表,依次向右匹配,匹配到返回结果,匹配不到返回null值填充
右外连接(LEFT JOIN ON):
# 查询所有部门信息,以及此部门中所有员工信息(没有员工的部门,员工信息以null填充)
SELECT employee_id,first_name,salary,department_name FROM t_employees
RIGHT JOIN t_departments
ON t_departments.department_id = t_employees.department_id;
右外连接是以右表为主表,依次向左匹配,匹配到返回结果,匹配不到返回null值填充
DML操作
1.新增(INSERT)
INSERT INTO 表名(列1,列2,列3……) VALUES(值1,值2,值3……)
添加一条信息:
# 新增
INSERT INTO t_jobs(job_id,job_title,min_salary,max_salary)
VALUES('Python','Python_Programmer',10000,20000);
2.修改(UPDATE)
UPDATE 表名 SET 列1=新值1,列2=新值2,……WHERE条件
# 修改编号为100的员工工资为25000
UPDATE t_employees SET salary = 25000 WHERE employee_id = '100';
注:SET 后有多个列名=值,绝大多数情况下都要加WHERE条件,指定修改,否则为整表修改
3.删除(DELETE)
DELETE FROM 表名 WHERE 条件;
删除一条信息:
# 删除编号为135的员工
DELETE FROM t_employees WHERE employee_id = '135';
# 删除某条指定的员工信息
DELETE FROM t_employees WHERE first_name = 'Peter' AND last_name = 'Hall';
注:删除时若不加 WHERE 条件,则删除的是整表信息
4.清空整表数据(TRUNCATE)
TRUNCATE TABLE 表名;
数据表操作
1.数据类型
MySQL 支持多种类型,大致可以分为三类:数值,日期 / 时间和字符串(字符)类型。
1.1 数值类型
- int:4字节,大整数值
- double:8字节,双精度浮点数值
- double(M,D):8字节,双精度浮点数值,M表示长度,D表示小数位数
- DECIMAL(M,D):小数值
1.2 日期类型
- DATE:YYYY-MM-DD,日期值
- DATETIME:YYYY-MM-DD HH:MM:SS,日期和时间值
1.3 字符串类型
- CHAR:定长字符串 char(10) 10个字符
- VARCHAR:变长字符串 varchar(10) 10个字符
- BLOB(binary large object):二进制形式的长文本数据
- TEXT:长文本数据
2.数据表的创建(CREATE)
CREATE TABLE 表名(
列名 数据类型 约束,
列名 数据类型 约束,
……
列名 数据类型 约束 (最后一列的末尾不加逗号)
)charset=utf8 (可根据需要指定表的字符集编码)
# 创建一张表 ``规避关键字冲突
CREATE TABLE `subject`(
subjectId INT,
subjectName VARCHAR(20),
subjectHours INT
)CHARSET = utf8;
SELECT * FROM `subject`;
# 插入数据
INSERT INTO `subject`(subjectId,subjectName,subjectHours)
VALUES(001,'Math',24);
查看该表:
3.数据表的修改(ALTER)
ALTER TABLE 表名 操作;
3.1 向现有表中添加列
# 向上面subject表中添加一列数据
ALTER TABLE `subject` ADD gradeId INT;
3.2 修改表中的列
# 修改表中课程长度为10个字符
ALTER TABLE `subject` MODIFY subjectName VARCGAR(10);
注:修改表中的某列时,也要写全列的名字,数据类型,约束
3.3 删除表中的列
# 删除表中gradeId列
ALTER TABLE `subject` DROP gradeId;
注:删除列时,一次只能删除一列
3.4 修改列名
# 修改表中subjectHours 为classHours
ALTER TABLE `subject` CHANGE subjectHours classHours INT;
注:修改列名时,在给定列新名称时,要指定列的类型和约束
3.5 修改表名
修改上面`subject`表的名字为sub
ALTER TABLE `subject` TO sub;
4.数据表的删除(DROP)
DROP TABLE 表名;
DROP TABLE sub;
约束
1.实体完整性约束
表中的一行数据代表一个实体(entity),实体完整性的作用即是标识每一行数据不重复、实体唯一。
1.1 主键约束
PRIMARY KEY 唯一,标识表中的一行数据,此列的值不可重复,且不能为null
# 给foodId添加主键约束
CREATE TABLE food(
foodId INT PRIMARY KEY,
foodKind VARCHAR(20),
foodPrice INT
)CHARSET = utf8;
SELECT * FROM food;
INSERT INTO food(foodId,foodKind,foodPrice) VALUES(1,'noodle',7);
INSERT INTO food(foodId,foodKind,foodPrice) VALUES(1,'rice',6); # 报错,主键1已经存在。
1.2 唯一约束
UNIQUE 唯一,标识表中的一行数据,不可重复,可以为NULL
# 食物种类唯一
CREATE TABLE food(
foodId INT PRIMARY KEY,
foodKind VARCHAR(20) UNIQUE,
foodPrice INT
)CHARSET = utf8;
1.3 自动增长列
AUTO_INCREMENT 编号自动增长
# 自动增长列,使主键编号自动增长
CREATE TABLE food(
foodId INT PRIMARY KEY AUTO_INCREMENT,
foodKind VARCHAR(20) UNIQUE,
foodPrice INT
)CHARSET=utf8;
INSERT INTO food(foodKind,foodPrice) VALUES('noodle',7);
INSERT INTO food(foodKind,foodPrice) VALUES('rice',7);
INSERT INTO food(foodKind,foodPrice) VALUES('jiaozi',7);
2.域完整性约束
2.1 非空约束
NOT NULL 非空,此列必须有值
# 设置食物种类不能为空
CREATE TABLE food(
foodId INT PRIMARY KEY AUTO_INCREMENT,
foodKind VARCHAR(20) UNIQUE NOT NULL,
foodPrice INT
)CHARSET=utf8;
2.2 默认值约束
default 值 为列赋予默认值,当新增数据不指定值时,书写default,以指定的默认值进行填充。
# 没有指出价钱时,默认值10填充
CREATE TABLE food(
foodId INT PRIMARY KEY AUTO_INCREMENT,
foodKind VARCHAR(20) UNIQUE NOT NULL,
foodPrice INT DEFAULT 10
)CHARSET=utf8;
INSERT INTO food(foodId,foodKind) VALUES(1,'noodle');
2.3 引用完整性约束
语法:CONSTRAINT 引用名 FOREIGN KEY (列名) REFERENCE 被引用表名 (列名)
FOREIGN KEY 引用外部表某个列的值
# 创建专业表
CREATE TABLE Speciality(
id INT PRIMARY KEY AUTO_INCREMENT,
SpecialName VARCHAR(20) UNIQUE NOT NULL
)CHARSET=utf8;
INSERT INTO Speciality(SpecialName) VALUES('Java');
INSERT INTO Speciality(SpecialName) VALUES('C');
SELECT * FROM Speciality;
# 创建科目表
CREATE TABLE `subject`(
subjectId INT PRIMARY KEY AUTO_INCREMENT,
subjectName VARCHAR(20) UNIQUE NOT NULL,
specialId INT NOT NULL,
CONSTRAINT fk_subject_specialId FOREIGN KEY(specialId) REFERENCES Speciality(id)
)CHARSET=utf8;
INSERT INTO `subject`(subjectName,specialId) VALUES('JavaSE',1);
INSERT INTO `subject`(subjectName,specialId) VALUES('C-Pointer',2);
SELECT * FROM `subject`;
执行以上代码,可以看到:
相当于给这两门课程都指明了所属的专业,JavaSE属于Java。
事务
1.模拟转账
实际中的转账是转账方账户扣钱,收账方账户加钱,我们用数据库来模拟现实转账
创建这样一个表,模拟两个人的账户:
1.1 模拟转账
UPDATE ACCOUNT SET money = money - 1000 WHERE id = 1;
UPDATE ACCOUNT SET money = money + 1000 WHERE id = 2;
转账时可能出现错误,导致在第一行减钱操作成功了,但第二行加钱却没有成功。
2.事务的概念
事务是一个原子操作,是一个最小执行单元,可以由一个或多个SQL语句组成,在同一个事务当中,所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败时,整个事务都执行失败。
3.事务的边界
开始:
连接到数据库,执行一条DML语句,上一个事物结束后,又输入一条DML语句,即事务的开始。
结束:
- 提交:commit
- 回滚:rollback
4.事务的原理
数据库会为每一个客户端都维护一个空间独立的缓存区(回滚段),一个事务中所有的增删改查语句执行结果都会缓存在回滚段中,只有当事务中所有SQL语句都正常结束(commit),才会将回滚段中的数据同步到数据库,否则无论因为哪种原因失败,整个事务都将回滚(rollback)。
5.事务的特性
- Atomicity(原子性)
表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败- Consistency(一致性)
表示一个事务内有一个操作失败时,所有更改过的数据必须回滚到修改前状态- Isolation(隔离性)
事务查看数据操作时数据所处的状态,要么是另一并发事务修改它为之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。- Durability(持久性)
持久性事务完成之后,它对于系统的影响是永久性的
6.事务应用
# 1 开启事务
START TRANSACTION;
# 2 事务内数据操作语句
UPDATE ACCOUNT SET money = money - 100 WHERE id = 1;
UPDATE ACCOUNT SET money = money + 100 WHERE id = 2;
# 3 事务内语句都成功了,执行 COMMIT
COMMIT;
# 4 事务内如果出现错误,执行 ROLLBACK
ROLLBACK;
执行上述代码时,只执行id=1的减钱的操作,id=2不操作,查表,可以看到id=1的钱少了100,再执行rollback,查表,可以看到id=1的钱又回来了。这样就大致的模拟了当转账过程中出现错误导致没有加钱的情况。
权限管理
1.创建用户
CREATE USER 用户名 IDENTIFIED BY 密码
# 创建一个 zhangsan 用户
CREATE USER `zhangsan` IDENTIFIED BY `123`;
2.授权
GRAND ALL ON 数据库.表 TO 用户名;
# 将 companyDB 下的所有权限表都赋给zhangsan
GRANT ALL ON companydb* TO zhangsan;
3.撤销权限
REVOKE ALL ON 数据库.表名 FROM 用户名;
# 将zhangsan的 companyDB 下的所有权限撤销
REVOKE ALL ON companydb.* FROM zhangsan;
4.删除用户
DROP USER 用户名
# 删除用户张三
DROP USER `zhangsan`;
视图
1.概念
视图,虚拟表,从一个或多个表中查询出来的表,作用和真实表一样,包含一系列带有行和列的数据。视图中,用户可以使用SELECT语句查询数据,也可以使用INSERT,UPDATE,DELETE修改记录。
2.视图的创建
语法:CREATE VIEW 视图名 AS 查询数据源表语句;
# 创建t_empInfo视图,其视图从t_employees表中查询出员工编号,员工姓名,员工邮箱,工资
CREATE VIEW t_empInfo
AS
SELECT employee_id,first_name,email,salary FROM t_employees;
SELECT * FROM t_empInfo;
3.视图的修改
方法一:CREATE OR REPLACE VIEW 视图名 AS 查询语句
方法二:ALTER VIEW 视图名 AS 查询语句
# 方式1:如果视图存在则进行修改,反之,进行创建
CREATE OR REPLACE VIEW t_empInfo
AS
SELECT employee_id,first_name,email,salary FROM t_employees;
# 方式2:直接对已经存在的视图进行修改
ALTER VIEW t_empInfo
AS
SELECT employee_id,first_name,email,salary FROM t_employees;
4.视图的删除
DROP VIEW 视图名
# 删除t_empInfo视图
DROP VIEW t_empInfo;
注:删除视图不会影响原表
SQL语言分类
- 数据查询语言DQL(Data Query Language):select、where、order by、group by、having。
- 数据定义语言DDL(Data Definition Language):create、alter、drop。
- 数据操作语言DML(Data Manipulation Language):insert、update、delete。
- 事务处理语言TPL(Transaction Process Language):commit、rollback。
- 数据控制语言DCL(Data Control Language):grant、revoke。
我是快斗,请多多指教!
本文地址:https://blog.csdn.net/qq_46127363/article/details/108913424
上一篇: Java注释,标识符,数据类型,类型转换
下一篇: MySQL自动停机的问题处理实战记录