五、MySQL中的数据类型
- 整型
整数类型 | 字节数 | 最小值(有符号/无符号) | 最大值(有符号/无符号) |
TINYINT | 1 | -128/0 | 127/255 |
SMALLINT | 2 | -32768/0 | 32767/65535 |
MEDOIMINT | 3 | -8388608/0 | 8388607/1677215 |
INT,INTEGER | 4 | -2147483648/0 | 2147483647/4299497295 |
BIGINT | 8 | -9223372036854775808/0 | 9223372036854775807/18446744073709551616 |
设置无符号类型:UNSIGNED
- 浮点型
- float:4个字节
- FLOAT(M,D) M显示的位数(0~255),D表示精确到第几位(带四舍五入),该写法为非标准写法,建议迁移库的时候不要使用
- double:8个字节
- DOUBLE(M,D) :同FLOAT(M,D)
- DOUBLE 和FLOAT 在不指定精度时,默认会按照实际精度,但最终的精度是由操作系统所决定的
- 双精度需要指明标度和精度
- real:实际上就是DOUBLE ,如果SQL服务器模式为REAL_AS_FLOAT real就是FLOAT(0·30)
- 定点数
- decimal
DECIMAL(M,D):处理规格和浮点型是相同的,M取值范围是0~65,D取值范围为(0~30)
DECIMAL:mysql内部使用字符串存放,定点型占M+2字节,但是不能大于M的最大存储范围,没有指明精度的时候默认为整数位10,小数位0 - numeric
NUMERIC:等价于DEIMAL
- 日期时间类型
- date:日期 YYYY-MM-DD
- time:时间 HH:MM:SS
- datetime:日期时间 YYYY-MM-DD HH:MM:SS
- year:年份 YYYY和YYl
- timestamp:时间戳 YYYY-MM-DD HH:MM:SS
注意:注册类时间,发布类时间不建议使用datetime类型,建议使用时间戳,因为datetime不利于时间计算
- 字符串
- char(存较短字符串用)固定长度类型)
- char(m) ,m是最大长度,如果不指定m,则默认m = 1,在数据列里每个值占用M个字符,如果长度小于m对应在右边会用空格补充
- varchar(可变长,必须指定长度,没有默认值)
- char是定长的,其处理效率上比VARCHAR高得多,但是比较浪费空间
- text文本类型,可以存储文本段,不建议使用,text加默认值不起作用
- 在什么情况下使用char
- 存储信息较短
- 固定长度的也可使用
- 频繁的修改用char类型,varchar在每次改变的是都会区计算
- 二进制类型
- blob
二进制大对象容量是可变的,通过容量不同可以分为四种blob类型
- TINYBLOB
- BLOB
- MEDIUBLOB
- LONGBLO B
- binary
- 两者区别类似于char 和varchar ,不同的是他们存储的不是字符串,存储的是二进制串,所以blob和binary没有字符集,排序通过比较列值中的字节数
- NULL类型
- 特征:MySQL中所有的类型都可以为NULL
- 空字符串和0不是NULL
- 所有运算符和NULL运算都是NULL
- NULL的判断只能用IS NULL 和IS NOT NULL
- NULL影响查询速度,所以在SQL优化中尽可能的避免使用NULL
- Q:为什么建表时,加NOT NULL DEFAULT ''/ DEFAULT 0
A:不想让表中使用NULL
Q:为什么不想使用NULL值
A:①不好比较,NULL是一种类型,比较时只能用专门的 IS NULL 和IS NOT NULL,碰到运算符,一律返回NULL
② 效率不高,影响提高所索引的效果
- 枚举:enum,在mysql中是一个字符串对象,值来源于表创建时,在列规定中显示枚举,可以插入空字符串和null值
- 集合:set 和枚举很像,可以包含0-64个成员。set和枚举不同的是,set是通过存储的成员个数来决定字节数,set一次性可以选择多个成员,enum一次只能选择一个
六、约束
定义:就是一种限制,为了保持数据一致性
1 主键约束:PRIMARY KEY
- 使得字段具有唯一性和非空性
2 非空约束:NOT NULL
- 保证字段的值不能为空
3 唯一约束:UNIQUE
- 保证该字段的值是唯一的
4 默认约束:DEFAULT
- 给字段添加默认值
5 检查约束:CHECK
- MySQL中不支持
6 外键约束:
- 用来保证两张表的参照完整性
分类:
- 列级约束:除外键约束外都可作为列级约束
- 表级约束:出了默认和非空约束,其他都可以作为表级约束
CREATE TABLE stu_info(
snum INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(15) NOT NULL,
gender CHAR CHECK(gender IN('男','女')),
person_id VARCHAR(20) UNIQUE,
join_timet TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
teacher_id INT REFERENCES teacher(teacher_id)
)
CREATE TABLE teacher (
teacher_id INT PRIMARY KEY,
tname VARCHAR(20) NOT NULL
)
USE student
CREATE TABLE stu_info(
snum INT AUTO_INCREMENT,
sname VARCHAR(15) NOT NULL,
gender CHAR CHECK(gender IN('男','女')),
person_id VARCHAR(20),
join_timet TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
teacher_id INT ,
CONSTRAINT pk PRIMARY KEY (snum),-- pk时可以省略的
CONSTRAINT fk UNIQUE(sname),
CONSTRAINT gk FOREIGN KEY(teacher_id) REFERENCES teacher(teacher_id)
)
CREATE TABLE teacher (
teacher_id INT PRIMARY KEY,
tname VARCHAR(20) NOT NULL
)
#查看表索引
SHOW INDEX FROM stu_info
#创建表之后添加约束
/*
添加表级别约束
ALTER TABLE 表名 ADD[CONSTRAINT 约束名] 约束类型 [KEY](字段名)
添加列级别约束
ALTER TABLE 表名 MODIFY COLUMN 列名 类型 约束类型 [KEY]
*/
#创建表之后添加主键约束(主键有默认的索引名,故无需添加索引名)
ALTER TABLE stu_info ADD CONSTRAINT PRIMARY KEY(sid)
ALTER TABLE stu_info MODIFY COLUMN sid INT PRIMARY KEY
#创建表之后添加唯一约束
ALTER TABLE stu_info ADD CONSTRAINT uk UNIQUE (sname)
#创建表之后添加外键约束
ALTER TABLE stu_info ADD CONSTRAINT fk FOREIGN(teacher_id)
#添加非空约束
ALTER TABLE stu_info MODIFY COLUMN sname VARCHAR(20) NOT NULL
#删除主键约束,主键唯一,故可不用指定字段
ALTER TABLE stu_info DROP PRIMARY KEY
#删除唯一约束(删除唯一约束的时候,是通过删除索引来完成的)
ALTER TABLE stu_info DROP INDEX uq
#删除外键约束(删除外键约束时不会删除其索引,所以通常来说需要删除对应的索引)
ALTER TABLE stu_info DROP FOREIGN KEY fk
ALTER TABLE stu_info DROP INDEX fk
#删除默认约束
ALTER TABLE stu_info MODIFY COLUMN join_time TIMESTAMP
#删除非空约束
ALTER TABLE stu_info MODIFY COLUMN sname VARCHAR(20) NULL
#mysql中提供了自增长列,
AUTO_INCREMENT -- 通常放在主键或者唯一键上,一张表只能出现一个自增列
-- 说明:如果一张表中使用了自增长列,如果使用 DELETE 删除的表中的所有数据,则下次添加时自增长
-- 会从断电开始,TRUNCATE则不会
#设置自增列的步长
SET AUTO_INCREMENT_INCREMENT = 2;
七、事务(tcl事务控制语言)
7.1 概述
定义:一个或者一组sql组成的一个执行单元,数据的添加、修改、删除、查询。表和库没有事务这个说法
特性:acid特性
- 原子性:数据库事务具有不可分割性,要么都成功,要么都失败
- 一致性:事务的前后应该保持一致
- 隔离性:某个事务的操作对其他事务是不可见的
- 持久性:当事务提交之后,其影响应该保留下来,不能撤销
#查看引擎
SHOW ENGINES
7.2 事务开启
自动事务/隐式事务:事务的提交是自动的
#查看AUTOCOMMIT变量
SHOW VARIABLES LIKE 'AUTOCOMMIT'
切换为手动事务
SET AUTOCOMMIT = FALSE -- FALSE 可替换为 0
事务开启
START TRANSACTION;
结束事务
COMMIT 提交事务
ROLLBACK 回滚事务
事务回滚演示
#事务回滚演示
SET autocommit = FALSE;
SHOW VARIABLES autocommit;
#开启事务,结束事务之前的语句都是事务
START TRANSACTION;
INSERT INTO stu_info(sname,gender,person_id,teacher_id)
VALUES('ljq','m','1',1);
INSERT INTO stu_info(sname,gender,person_id,teacher_id)
VALUES('ljq',m,'12321421324',1); -- 有错语句
#结束事务
-- COMMIT; #提交事务
-- ROLLBACK; #回滚事务到事务开启之前的状态,事务一旦提交不能回滚
7.3事务的隔离级别
实质是多线程并发问题
- 脏读(脏数据):对于两个事务:T1、T2,T1读取了T2更新但是还没有提交的数据,如果此时T2回滚,T1读取的数据是临时无效数据
- 不可重复度:对于两个事务:T1、T2,T1读取了一个字段,T2更新了一个字段并提交,此时T1在读取相同字段时值会改变
- 幻读:主要针对于修改和插入,T1、T2两个事务,T1从表中修改了一条数据,T2从表中添加数据,添加的数据满足T1修改数据的条件,则对应T1会修改T2未提交的数据,TI在修改的时候会发现多出了几条修改的数据
隔离级别 | 描述 |
read-uncommitted | 允许事务去读其他食物未提交的数据。脏读,不可重复读,幻读都无法解决 |
read-committed- | 只允许读其他食物已经提交的数据,可解决脏读,但是依旧不能处理不可重复,幻读问题 |
repeatable-read | 确保事务可以多次从一个字段中读取相同的值,解决了不可重复读的问题,依旧会出现幻读 |
serializable | 确保事务可以从一个表中读取相同的行,事务持续期间禁止其他事务执行插入、更新、删除操作,可以解决幻读问题,但一般没人用 |
#查看当前的默认隔离级别
SELECT @@TX_ISOLATION;
#修改隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; #SESSION 加上之后可以立马生效
事务回滚
#关于 ROLLBACK
set autocommit = FALSE;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT @@tx_isolation;
START TRANSACTION;
SAVEPOINT b; -- 设置回滚点
DELETE FROM stu_info;
SELECT * FROM stu_info;
ROLLBACK TO b; -- 回滚到b
SELECT * FROM stu_info; --再次查看表
说明:
- 在innodb存储引擎中事务隔离级别前三个默认使用行级锁,serializable加标记锁
- trancate清除表的时候无法回滚
#创建表时指定引擎
CREATE TABLE score(
id int;
)ENGINE = INNODB DEFAULT CHARACTER=utf8
serializable实验
- T1
Microsoft Windows [版本 10.0.17763.652]
(c) 2018 Microsoft Corporation。保留所有权利。
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 60
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> set session transaction isolation level serializable
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
ERROR 1046 (3D000): No database selected
mysql> set session transaction isolation level serializable
-> exit
-> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'exit' at line 2
mysql> exit
Bye
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 63
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use student
Database changed
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
+------+-----------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-----------+--------+-----------+---------------------+------------+
| 1 | 杩炴帴 | n | we | 2019-07-29 15:13:00 | 1 |
| 2 | 閮痉绾? | m | 13 | 2019-07-29 15:18:06 | 1 |
+------+-----------+--------+-----------+---------------------+------------+
2 rows in set (0.00 sec)
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
+------+-----------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-----------+--------+-----------+---------------------+------------+
| 1 | 杩炴帴 | n | we | 2019-07-29 15:13:00 | 1 |
| 2 | 閮痉绾? | m | 13 | 2019-07-29 15:18:06 | 1 |
+------+-----------+--------+-----------+---------------------+------------+
2 rows in set (0.00 sec)
mysql> update stu_info set sname = 'ljq';
Query OK, 2 rows affected (0.07 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> update stu_info set sname = 'ln';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> update stu_info set sname = 'lnn';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> update stu_info set sname = 'ln';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
+------+-------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-------+--------+-----------+---------------------+------------+
| 1 | ln | n | we | 2019-07-29 15:13:00 | 1 |
| 2 | ln | m | 13 | 2019-07-29 15:18:06 | 1 |
+------+-------+--------+-----------+---------------------+------------+
2 rows in set (0.00 sec)
mysql> select * from stu_info;
+------+-------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-------+--------+-----------+---------------------+------------+
| 1 | ln | n | we | 2019-07-29 15:13:00 | 1 |
+------+-------+--------+-----------+---------------------+------------+
1 row in set (0.00 sec)
- T2
Microsoft Windows [版本 10.0.17763.652]
(c) 2018 Microsoft Corporation。保留所有权利。
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 61
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 62
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use student
Database changed
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from stu_info where snum = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
mysql> delete from stu_info where snum = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> delete from stu_info where snum = 2;
Query OK, 1 row affected (29.15 sec)
mysql> select * from stu_info;
+------+-------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-------+--------+-----------+---------------------+------------+
| 1 | ln | n | we | 2019-07-29 15:13:00 | 1 |
+------+-------+--------+-----------+---------------------+------------+
1 row in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
八、视图
8.1概述
视图的定义:保存一组sql语句的逻辑。不保存数据,只保存一组sql的逻辑
创建视图的语法
CREATE VIEW 视图名
AS
编写的sql
视图一般只用来查找
SELECT * FROM 视图名
视图的用法和表一样
创建视图
#创建视图
#查询各部门员工的姓名,角色,部门名称,工资级别
CREATE VIEW salarys
AS
SELECT
d.stuff_name,
dt.department_id
FROM
department d JOIN department_type dt ON d.department_id = dt.department_id;
8.2修改视图
#修改视图
#方法一
CREATE OR REPLACE VIEW 视图名
AS
新的sql语句
#方法二
ALTER VIEW SALARYS
AS
新的sql语句
#更改视图一
CREATE OR REPLACE VIEW salays
AS
SELECT * FROM department;
#更改视图二
ALTER VIEW salays
AS
SELECT * FROM department;
8.3 删除视图
DROP VIEW 视图1,视图2…
#删除视图
DROP VIEW salarys;
8.4 查询视图
#查询视图法一
SELECT
*
FROM
视图名
#查询视图法二(看详细的语法)
SHOW CREATE VIEW salarys;
#查看视图法三
DESC salarys;
#查询视图法一
SELECT
*
FROM
salays;
#查询视图法二(可以看详细的语法)
SHOW CREATE VIEW salarys;
#查看视图法三
DESC salarys;
总结:视图一般情况下只做查询,保存sql的逻辑,不做数据保存
九 存储过程和函数
9.1变量
和Java中的变量是一样的,都需要声明,赋值之后才能使用
- 系统变量:系统提供的,不需要自定义
- 全局变量
- 会话变量
查看系统变量的语法
#查所有全局变量|会话变量
SHOW GLOBAL|SESSION VARIABLES -- 若不指明是GLOBAL|SESSION默认查询SESSION
#通过模糊查询方式查找
SHOW GLOBAL|SESSION VARIABLES LIKE '%auto%'
#查看指定的变量
SELECT @@GLOBAL|SESSION.系统变量名
#为变量赋值
SET GLOBAL|SESSION 系统变量名 = 值
SET @@GLOBAL|SESSION.系统变量名 = 值
作用范围:服务器每一次启动,都会为全局变量赋默认初始值,如果修改了全局变量的值,只在本次服务的生命周期内有效,重启服务器将恢复默认值
- 自定义变量
- 用户变量:针对于一次有效的数据库连接
#声明变量
语法:
SET @用户变量名=值
SET @用户变量名:=值
SELECT @用户变量名:=值
#赋值法一
SET @用户变量名=值
SET @用户变量名:=值
SELECT @用户变量名:=值
SET @count_people = 0
#赋值法二
SELECT 字段 INTO @变量名 FROM 表(查询的字段值只能由一个)
SELECT COUNT(*) INTO @count_people FROM employee
#查看变量
SELECT @count_people;
- 局部变量:只在begin end中有效,而且只能使用在begin end 中第一行
#声明
DECLARE 变量名称 类型;
DECLARE 变量名称 类型 DEFAULT 默认值;
#赋值
SET 局部变量名 = 值;
SET 局部变量:=值;
SELECT 字段 INTO 局部变量名 FROM 表; -- 表中被查询的字段只能有一个
SELECT 字段1,字段2 INTO 局部变量1,局部变量2 FROM 表
#查看变量:局部变量无法查看
9.2 存储过程
9.2.1 存储过程概述:
- 定义:一组预先编译好的sql语句集
- 优点:语句提高重用性,减少冗余度,减少了sql编译次数,以及减少了与服务器连接交互的次数
9.2.2 语法
- 参数列表包含三个部分:参数的模式,参数名,参数类型
#参数列表示意
IN deptname VARCHAR(20)
- 参数模式
- IN:需要调用者传入,类似于java中的形参
- OUT:作为返回值,类似于java中的return
- INOUT:调用者传入参数,对应的可以有返回值
- 语法
#创建语法
DELIMITER $ -- 定义结束标记
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(sql语句); -- 存储过程体中的每条语句结尾必须加分号
END $ -- 利用结束标记结束
-- 如果存储体过程中只有一句话,则对应的BEGIN END可以省略
-- 存储过程结尾需要使用delimiter标记,重新设置存储过程的结束标记
#存储过程的调用
CALL 存储过程名(实参)
#定义存储结构
DELIMITER $
CREATE PROCEDURE isr()
BEGIN
INSERT INTO stu_info(sname) VALUE('LDJ');
END $
#运行
CALL isr();
#定义存储结构
DELIMITER $
CREATE PROCEDURE findall(INOUT d INT)
BEGIN
SELECT * FROM stu_info;
SELECT COUNT(*) INTO d FROM teacher;
SELECT @a;
END $
#运行
CALL findall(@a);
#通过部门名称查询对应的员工信息
DELIMITER $
CREATE PROCEDURE empinfo(IN deptname VARCHAR(20))
BEGIN
SELECT
d.stuff_id,d.stuff_name,d.department_id
FROM department d RIGHT JOIN department_type dt
ON d.department_id = dt.department_id
WHERE dt.department_name = deptname;
END $
#调用函数
CALL empinfo('研发部')
- 带IN的存储过程
#通过查询员工部门是否有指定的员工角色
DELIMITER $
CREATE PROCEDURE empinfospecify(IN deptname VARCHAR(20),IN roletype VARCHAR(20))
BEGIN
DECLARE result INT DEFAULT 0;
SELECT COUNT(*) INTO result
FROM department d
LEFT JOIN department_type dt
ON d.department_id = dt.department_id
LEFT JOIN stuff_role sr
ON d.stuff_salary BETWEEN sr.MIN AND sr.MAX
WHERE deptname = dt.department_name AND roletype = sr.role;
SELECT IF(result > 0,'存在','不存在');
END $
#调用函数
CALL empinfospecify('研发部','员工');
- 带OUT的存储过程
#传入员工姓名返回对应的部门名称
DELIMITER $
CREATE PROCEDURE finddeptname(IN stuffname VARCHAR(20),OUT deptname VARCHAR(20))
BEGIN
SELECT dt.department_name INTO deptname
FROM department d LEFT JOIN department_type dt
ON d.department_id = dt.department_id
WHERE stuffname = d.stuff_name;
END $
#调用函数
CALL finddeptname('LJQ',@deptname);
SELECT @deptname;
- 带IN的存储过程
#传入两个工资并计算年薪
DELIMITER $
CREATE PROCEDURE salaryear(INOUT salary1 INT,INOUT salary2 INT)
BEGIN
SET salary1 = salary1*12;
SET salary2 = salary2*12;
END $
#调用函数
SET @salary1 = 1000;
SET @salary2 = 2343;
CALL salaryear(@salary1,@salary2);
SELECT @salary1,@salary2;
9.3 其他存储过程的命令
#删除存储过程
DROP PROCEDURE 存储过程名;
#查看存储过程
SHOW CREATE PROCEDURE 存储过程名;
9.4 函数
- 基础概念
- 定义:是一组运行编译好的sql语句集
- 优点:提高重用性,减少冗余度,减少SQL编译次数,以及和服务器连接交互的慈湖
- 函数和存储过程中的区别
- 存储过程可以没有返回或多个返回,函数有且只有一个返回
- 存储过程中适合做批量插入,函数适合做处理数据后返回的结果
- 语法
#创建函数语法
DELIMITER $
CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型 -- 注意这个是RETURNS不是RETURN
BEGIN
函数体 -- 函数体必须有return语句进行返回,其中的return不起到中断作用,放哪里都可以,建议放最后
END
#调用函数
SELECT 函数名(参数列表)
#查看函数 SHOW CREATE FUNCTION 函数名
#删除函数 DROP FUNCTION 函数名
```mysql
#返回员工个数
DELIMITER $
CREATE FUNCTION stuffcount() RETURNS INT
BEGIN
DECLARE c INT DEFAULT 0;
SELECT COUNT(*)INTO c FROM department;
RETURN c;
END $
#调用
SELECT stuffcount()
#查看函数
SHOW CREATE FUNCTION stuffcount
#删除函数
DROP FUNCTION stuffcount
9.5 循环结构
- WHILE
#WHILE语法
循环名:WHILE 循环条件
DO
循环体;
END 循环名;
#批量插入到teacher表中,如果大于20条则停止
DELIMITER $
CREATE PROCEDURE pro_insert(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
pIn:WHILE i<=insertCount DO
INSERT INTO teacher(tname) VALUES(CONCAT('教师',i));
SET i=i+1;
END WHILE pIn;
END $
#调用存储空间
CALL pro_insert(10);
- LOOP
#LOOP语法 没有循环条件可以用来模拟死循环
循环名:LOOP
循环条件;
END LOOP 循环名;
- REPEAT
#REPEAT语法
循环名:REPEAT
循环体;
UNTIL 循环结束条件
END REPEAT 循环名
- 循环控制
- ITERATE 类似于continue
- LEAVE 类似于 break
十、数据库的三范式
- 第一范式:必须要有主键,强调的十列的原子性,即列不能再分割为其他列
- 第二范式:非主键列必须完全依赖于主键列,完全依赖要求不允许存在非主主键依赖于主键中的某一部分属性(主键有可能是多个属性构成)。满足第二范式的条件是满足第一范式,
- 第三范式:非主键列必须直接雨来主键列,不能存在传递依赖
十一、附录
- department 表
stuff_id | stuff_name | stuff_salary | department_id | manager | join_date |
1 | LDJ | 5000 | 1 | 2 | 2019/7/24 |
2 | JQQ | 9000 | 2 | 4 | 2019/7/24 |
3 | LXX | 4237 | 0 | 6 | 2019/7/24 |
4 | LXN | 24333 | 2 | 2 | 2019/7/24 |
5 | LNN | 12323 | 2 | 3 | 2032/8/1 |
6 | LN | 2343 | 0 | | 2019/7/24 |
7 | LJQ | 123213 | 1 | 3 | 2019/7/24 |
8 | LJJ | 2343 | 2 | 2 | 2019/7/24 |
9 | JQ_LN | 30033 | 0 | 2 | 2019/7/24 |
10 | JQQ | 223 | | | 2019/7/24 |
12 | LPP | 3000 | | 0 | 2019/7/26 |
14 | LKA | 3000 | | 0 | 2019/7/26 |
15 | LBB | 3000 | | 0 | 2019/7/26 |
16 | XQQ | 3000 | | 0 | 2019/7/26 |
18 | XJJ | 5000 | | 0 | 2019/7/26 |
20 | LSS | 3333 | 2 | 1 | 2019/7/26 |
- department_type 表
department_name | department_id |
人事部 | 0 |
研发部 | 1 |
后勤部 | 2 |
- stuff_role 表
MAX | MIN | role |
14999 | 5000 | 员工 |
100000 | 15000 | 经理 |
4999 | 0 | 临时工作者 |
1 | | 暂无 |
- teacher 表
teacher_id | tname |
1 | 231 |
- stu_info表
五、MySQL中的数据类型
- 整型
整数类型 | 字节数 | 最小值(有符号/无符号) | 最大值(有符号/无符号) |
TINYINT | 1 | -128/0 | 127/255 |
SMALLINT | 2 | -32768/0 | 32767/65535 |
MEDOIMINT | 3 | -8388608/0 | 8388607/1677215 |
INT,INTEGER | 4 | -2147483648/0 | 2147483647/4299497295 |
BIGINT | 8 | -9223372036854775808/0 | 9223372036854775807/18446744073709551616 |
设置无符号类型:UNSIGNED
- 浮点型
- float:4个字节
- FLOAT(M,D) M显示的位数(0~255),D表示精确到第几位(带四舍五入),该写法为非标准写法,建议迁移库的时候不要使用
- double:8个字节
- DOUBLE(M,D) :同FLOAT(M,D)
- DOUBLE 和FLOAT 在不指定精度时,默认会按照实际精度,但最终的精度是由操作系统所决定的
- 双精度需要指明标度和精度
- real:实际上就是DOUBLE ,如果SQL服务器模式为REAL_AS_FLOAT real就是FLOAT(0·30)
- 定点数
- decimal
DECIMAL(M,D):处理规格和浮点型是相同的,M取值范围是0~65,D取值范围为(0~30)
DECIMAL:mysql内部使用字符串存放,定点型占M+2字节,但是不能大于M的最大存储范围,没有指明精度的时候默认为整数位10,小数位0 - numeric
NUMERIC:等价于DEIMAL
- 日期时间类型
- date:日期 YYYY-MM-DD
- time:时间 HH:MM:SS
- datetime:日期时间 YYYY-MM-DD HH:MM:SS
- year:年份 YYYY和YYl
- timestamp:时间戳 YYYY-MM-DD HH:MM:SS
注意:注册类时间,发布类时间不建议使用datetime类型,建议使用时间戳,因为datetime不利于时间计算
- 字符串
- char(存较短字符串用)固定长度类型)
- char(m) ,m是最大长度,如果不指定m,则默认m = 1,在数据列里每个值占用M个字符,如果长度小于m对应在右边会用空格补充
- varchar(可变长,必须指定长度,没有默认值)
- char是定长的,其处理效率上比VARCHAR高得多,但是比较浪费空间
- text文本类型,可以存储文本段,不建议使用,text加默认值不起作用
- 在什么情况下使用char
- 存储信息较短
- 固定长度的也可使用
- 频繁的修改用char类型,varchar在每次改变的是都会区计算
- 二进制类型
- blob
二进制大对象容量是可变的,通过容量不同可以分为四种blob类型
- TINYBLOB
- BLOB
- MEDIUBLOB
- LONGBLO B
- binary
- 两者区别类似于char 和varchar ,不同的是他们存储的不是字符串,存储的是二进制串,所以blob和binary没有字符集,排序通过比较列值中的字节数
- NULL类型
- 特征:MySQL中所有的类型都可以为NULL
- 空字符串和0不是NULL
- 所有运算符和NULL运算都是NULL
- NULL的判断只能用IS NULL 和IS NOT NULL
- NULL影响查询速度,所以在SQL优化中尽可能的避免使用NULL
- Q:为什么建表时,加NOT NULL DEFAULT ''/ DEFAULT 0
A:不想让表中使用NULL
Q:为什么不想使用NULL值
A:①不好比较,NULL是一种类型,比较时只能用专门的 IS NULL 和IS NOT NULL,碰到运算符,一律返回NULL
② 效率不高,影响提高所索引的效果
- 枚举:enum,在mysql中是一个字符串对象,值来源于表创建时,在列规定中显示枚举,可以插入空字符串和null值
- 集合:set 和枚举很像,可以包含0-64个成员。set和枚举不同的是,set是通过存储的成员个数来决定字节数,set一次性可以选择多个成员,enum一次只能选择一个
六、约束
定义:就是一种限制,为了保持数据一致性
1 主键约束:PRIMARY KEY
- 使得字段具有唯一性和非空性
2 非空约束:NOT NULL
- 保证字段的值不能为空
3 唯一约束:UNIQUE
- 保证该字段的值是唯一的
4 默认约束:DEFAULT
- 给字段添加默认值
5 检查约束:CHECK
- MySQL中不支持
6 外键约束:
- 用来保证两张表的参照完整性
分类:
- 列级约束:除外键约束外都可作为列级约束
- 表级约束:出了默认和非空约束,其他都可以作为表级约束
CREATE TABLE stu_info(
snum INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(15) NOT NULL,
gender CHAR CHECK(gender IN('男','女')),
person_id VARCHAR(20) UNIQUE,
join_timet TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
teacher_id INT REFERENCES teacher(teacher_id)
)
CREATE TABLE teacher (
teacher_id INT PRIMARY KEY,
tname VARCHAR(20) NOT NULL
)
USE student
CREATE TABLE stu_info(
snum INT AUTO_INCREMENT,
sname VARCHAR(15) NOT NULL,
gender CHAR CHECK(gender IN('男','女')),
person_id VARCHAR(20),
join_timet TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
teacher_id INT ,
CONSTRAINT pk PRIMARY KEY (snum),-- pk时可以省略的
CONSTRAINT fk UNIQUE(sname),
CONSTRAINT gk FOREIGN KEY(teacher_id) REFERENCES teacher(teacher_id)
)
CREATE TABLE teacher (
teacher_id INT PRIMARY KEY,
tname VARCHAR(20) NOT NULL
)
#查看表索引
SHOW INDEX FROM stu_info
#创建表之后添加约束
/*
添加表级别约束
ALTER TABLE 表名 ADD[CONSTRAINT 约束名] 约束类型 [KEY](字段名)
添加列级别约束
ALTER TABLE 表名 MODIFY COLUMN 列名 类型 约束类型 [KEY]
*/
#创建表之后添加主键约束(主键有默认的索引名,故无需添加索引名)
ALTER TABLE stu_info ADD CONSTRAINT PRIMARY KEY(sid)
ALTER TABLE stu_info MODIFY COLUMN sid INT PRIMARY KEY
#创建表之后添加唯一约束
ALTER TABLE stu_info ADD CONSTRAINT uk UNIQUE (sname)
#创建表之后添加外键约束
ALTER TABLE stu_info ADD CONSTRAINT fk FOREIGN(teacher_id)
#添加非空约束
ALTER TABLE stu_info MODIFY COLUMN sname VARCHAR(20) NOT NULL
#删除主键约束,主键唯一,故可不用指定字段
ALTER TABLE stu_info DROP PRIMARY KEY
#删除唯一约束(删除唯一约束的时候,是通过删除索引来完成的)
ALTER TABLE stu_info DROP INDEX uq
#删除外键约束(删除外键约束时不会删除其索引,所以通常来说需要删除对应的索引)
ALTER TABLE stu_info DROP FOREIGN KEY fk
ALTER TABLE stu_info DROP INDEX fk
#删除默认约束
ALTER TABLE stu_info MODIFY COLUMN join_time TIMESTAMP
#删除非空约束
ALTER TABLE stu_info MODIFY COLUMN sname VARCHAR(20) NULL
#mysql中提供了自增长列,
AUTO_INCREMENT -- 通常放在主键或者唯一键上,一张表只能出现一个自增列
-- 说明:如果一张表中使用了自增长列,如果使用 DELETE 删除的表中的所有数据,则下次添加时自增长
-- 会从断电开始,TRUNCATE则不会
#设置自增列的步长
SET AUTO_INCREMENT_INCREMENT = 2;
七、事务(tcl事务控制语言)
7.1 概述
定义:一个或者一组sql组成的一个执行单元,数据的添加、修改、删除、查询。表和库没有事务这个说法
特性:acid特性
- 原子性:数据库事务具有不可分割性,要么都成功,要么都失败
- 一致性:事务的前后应该保持一致
- 隔离性:某个事务的操作对其他事务是不可见的
- 持久性:当事务提交之后,其影响应该保留下来,不能撤销
#查看引擎
SHOW ENGINES
7.2 事务开启
自动事务/隐式事务:事务的提交是自动的
#查看AUTOCOMMIT变量
SHOW VARIABLES LIKE 'AUTOCOMMIT'
切换为手动事务
SET AUTOCOMMIT = FALSE -- FALSE 可替换为 0
事务开启
START TRANSACTION;
结束事务
COMMIT 提交事务
ROLLBACK 回滚事务
事务回滚演示
#事务回滚演示
SET autocommit = FALSE;
SHOW VARIABLES autocommit;
#开启事务,结束事务之前的语句都是事务
START TRANSACTION;
INSERT INTO stu_info(sname,gender,person_id,teacher_id)
VALUES('ljq','m','1',1);
INSERT INTO stu_info(sname,gender,person_id,teacher_id)
VALUES('ljq',m,'12321421324',1); -- 有错语句
#结束事务
-- COMMIT; #提交事务
-- ROLLBACK; #回滚事务到事务开启之前的状态,事务一旦提交不能回滚
7.3事务的隔离级别
实质是多线程并发问题
- 脏读(脏数据):对于两个事务:T1、T2,T1读取了T2更新但是还没有提交的数据,如果此时T2回滚,T1读取的数据是临时无效数据
- 不可重复度:对于两个事务:T1、T2,T1读取了一个字段,T2更新了一个字段并提交,此时T1在读取相同字段时值会改变
- 幻读:主要针对于修改和插入,T1、T2两个事务,T1从表中修改了一条数据,T2从表中添加数据,添加的数据满足T1修改数据的条件,则对应T1会修改T2未提交的数据,TI在修改的时候会发现多出了几条修改的数据
隔离级别 | 描述 |
read-uncommitted | 允许事务去读其他食物未提交的数据。脏读,不可重复读,幻读都无法解决 |
read-committed- | 只允许读其他食物已经提交的数据,可解决脏读,但是依旧不能处理不可重复,幻读问题 |
repeatable-read | 确保事务可以多次从一个字段中读取相同的值,解决了不可重复读的问题,依旧会出现幻读 |
serializable | 确保事务可以从一个表中读取相同的行,事务持续期间禁止其他事务执行插入、更新、删除操作,可以解决幻读问题,但一般没人用 |
#查看当前的默认隔离级别
SELECT @@TX_ISOLATION;
#修改隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; #SESSION 加上之后可以立马生效
事务回滚
#关于 ROLLBACK
set autocommit = FALSE;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT @@tx_isolation;
START TRANSACTION;
SAVEPOINT b; -- 设置回滚点
DELETE FROM stu_info;
SELECT * FROM stu_info;
ROLLBACK TO b; -- 回滚到b
SELECT * FROM stu_info; --再次查看表
说明:
- 在innodb存储引擎中事务隔离级别前三个默认使用行级锁,serializable加标记锁
- trancate清除表的时候无法回滚
#创建表时指定引擎
CREATE TABLE score(
id int;
)ENGINE = INNODB DEFAULT CHARACTER=utf8
serializable实验
- T1
Microsoft Windows [版本 10.0.17763.652]
(c) 2018 Microsoft Corporation。保留所有权利。
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 60
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> set session transaction isolation level serializable
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
ERROR 1046 (3D000): No database selected
mysql> set session transaction isolation level serializable
-> exit
-> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'exit' at line 2
mysql> exit
Bye
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 63
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use student
Database changed
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
+------+-----------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-----------+--------+-----------+---------------------+------------+
| 1 | 杩炴帴 | n | we | 2019-07-29 15:13:00 | 1 |
| 2 | 閮痉绾? | m | 13 | 2019-07-29 15:18:06 | 1 |
+------+-----------+--------+-----------+---------------------+------------+
2 rows in set (0.00 sec)
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
+------+-----------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-----------+--------+-----------+---------------------+------------+
| 1 | 杩炴帴 | n | we | 2019-07-29 15:13:00 | 1 |
| 2 | 閮痉绾? | m | 13 | 2019-07-29 15:18:06 | 1 |
+------+-----------+--------+-----------+---------------------+------------+
2 rows in set (0.00 sec)
mysql> update stu_info set sname = 'ljq';
Query OK, 2 rows affected (0.07 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> update stu_info set sname = 'ln';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> update stu_info set sname = 'lnn';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> update stu_info set sname = 'ln';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from stu_info;
+------+-------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-------+--------+-----------+---------------------+------------+
| 1 | ln | n | we | 2019-07-29 15:13:00 | 1 |
| 2 | ln | m | 13 | 2019-07-29 15:18:06 | 1 |
+------+-------+--------+-----------+---------------------+------------+
2 rows in set (0.00 sec)
mysql> select * from stu_info;
+------+-------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-------+--------+-----------+---------------------+------------+
| 1 | ln | n | we | 2019-07-29 15:13:00 | 1 |
+------+-------+--------+-----------+---------------------+------------+
1 row in set (0.00 sec)
- T2
Microsoft Windows [版本 10.0.17763.652]
(c) 2018 Microsoft Corporation。保留所有权利。
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 61
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
C:\Users\18392>mysql -uroot -proot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 62
Server version: 5.5.54 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use student
Database changed
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from stu_info where snum = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
mysql> delete from stu_info where snum = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> delete from stu_info where snum = 2;
Query OK, 1 row affected (29.15 sec)
mysql> select * from stu_info;
+------+-------+--------+-----------+---------------------+------------+
| snum | sname | gender | person_id | join_timet | teacher_id |
+------+-------+--------+-----------+---------------------+------------+
| 1 | ln | n | we | 2019-07-29 15:13:00 | 1 |
+------+-------+--------+-----------+---------------------+------------+
1 row in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
八、视图
8.1概述
视图的定义:保存一组sql语句的逻辑。不保存数据,只保存一组sql的逻辑
创建视图的语法
CREATE VIEW 视图名
AS
编写的sql
视图一般只用来查找
SELECT * FROM 视图名
视图的用法和表一样
创建视图
#创建视图
#查询各部门员工的姓名,角色,部门名称,工资级别
CREATE VIEW salarys
AS
SELECT
d.stuff_name,
dt.department_id
FROM
department d JOIN department_type dt ON d.department_id = dt.department_id;
8.2修改视图
#修改视图
#方法一
CREATE OR REPLACE VIEW 视图名
AS
新的sql语句
#方法二
ALTER VIEW SALARYS
AS
新的sql语句
#更改视图一
CREATE OR REPLACE VIEW salays
AS
SELECT * FROM department;
#更改视图二
ALTER VIEW salays
AS
SELECT * FROM department;
8.3 删除视图
DROP VIEW 视图1,视图2…
#删除视图
DROP VIEW salarys;
8.4 查询视图
#查询视图法一
SELECT
*
FROM
视图名
#查询视图法二(看详细的语法)
SHOW CREATE VIEW salarys;
#查看视图法三
DESC salarys;
#查询视图法一
SELECT
*
FROM
salays;
#查询视图法二(可以看详细的语法)
SHOW CREATE VIEW salarys;
#查看视图法三
DESC salarys;
总结:视图一般情况下只做查询,保存sql的逻辑,不做数据保存
九 存储过程和函数
9.1变量
和Java中的变量是一样的,都需要声明,赋值之后才能使用
- 系统变量:系统提供的,不需要自定义
- 全局变量
- 会话变量
查看系统变量的语法
#查所有全局变量|会话变量
SHOW GLOBAL|SESSION VARIABLES -- 若不指明是GLOBAL|SESSION默认查询SESSION
#通过模糊查询方式查找
SHOW GLOBAL|SESSION VARIABLES LIKE '%auto%'
#查看指定的变量
SELECT @@GLOBAL|SESSION.系统变量名
#为变量赋值
SET GLOBAL|SESSION 系统变量名 = 值
SET @@GLOBAL|SESSION.系统变量名 = 值
作用范围:服务器每一次启动,都会为全局变量赋默认初始值,如果修改了全局变量的值,只在本次服务的生命周期内有效,重启服务器将恢复默认值
- 自定义变量
- 用户变量:针对于一次有效的数据库连接
#声明变量
语法:
SET @用户变量名=值
SET @用户变量名:=值
SELECT @用户变量名:=值
#赋值法一
SET @用户变量名=值
SET @用户变量名:=值
SELECT @用户变量名:=值
SET @count_people = 0
#赋值法二
SELECT 字段 INTO @变量名 FROM 表(查询的字段值只能由一个)
SELECT COUNT(*) INTO @count_people FROM employee
#查看变量
SELECT @count_people;
- 局部变量:只在begin end中有效,而且只能使用在begin end 中第一行
#声明
DECLARE 变量名称 类型;
DECLARE 变量名称 类型 DEFAULT 默认值;
#赋值
SET 局部变量名 = 值;
SET 局部变量:=值;
SELECT 字段 INTO 局部变量名 FROM 表; -- 表中被查询的字段只能有一个
SELECT 字段1,字段2 INTO 局部变量1,局部变量2 FROM 表
#查看变量:局部变量无法查看
9.2 存储过程
9.2.1 存储过程概述:
- 定义:一组预先编译好的sql语句集
- 优点:语句提高重用性,减少冗余度,减少了sql编译次数,以及减少了与服务器连接交互的次数
9.2.2 语法
- 参数列表包含三个部分:参数的模式,参数名,参数类型
#参数列表示意
IN deptname VARCHAR(20)
- 参数模式
- IN:需要调用者传入,类似于java中的形参
- OUT:作为返回值,类似于java中的return
- INOUT:调用者传入参数,对应的可以有返回值
- 语法
#创建语法
DELIMITER $ -- 定义结束标记
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(sql语句); -- 存储过程体中的每条语句结尾必须加分号
END $ -- 利用结束标记结束
-- 如果存储体过程中只有一句话,则对应的BEGIN END可以省略
-- 存储过程结尾需要使用delimiter标记,重新设置存储过程的结束标记
#存储过程的调用
CALL 存储过程名(实参)
#定义存储结构
DELIMITER $
CREATE PROCEDURE isr()
BEGIN
INSERT INTO stu_info(sname) VALUE('LDJ');
END $
#运行
CALL isr();
#定义存储结构
DELIMITER $
CREATE PROCEDURE findall(INOUT d INT)
BEGIN
SELECT * FROM stu_info;
SELECT COUNT(*) INTO d FROM teacher;
SELECT @a;
END $
#运行
CALL findall(@a);
#通过部门名称查询对应的员工信息
DELIMITER $
CREATE PROCEDURE empinfo(IN deptname VARCHAR(20))
BEGIN
SELECT
d.stuff_id,d.stuff_name,d.department_id
FROM department d RIGHT JOIN department_type dt
ON d.department_id = dt.department_id
WHERE dt.department_name = deptname;
END $
#调用函数
CALL empinfo('研发部')
- 带IN的存储过程
#通过查询员工部门是否有指定的员工角色
DELIMITER $
CREATE PROCEDURE empinfospecify(IN deptname VARCHAR(20),IN roletype VARCHAR(20))
BEGIN
DECLARE result INT DEFAULT 0;
SELECT COUNT(*) INTO result
FROM department d
LEFT JOIN department_type dt
ON d.department_id = dt.department_id
LEFT JOIN stuff_role sr
ON d.stuff_salary BETWEEN sr.MIN AND sr.MAX
WHERE deptname = dt.department_name AND roletype = sr.role;
SELECT IF(result > 0,'存在','不存在');
END $
#调用函数
CALL empinfospecify('研发部','员工');
- 带OUT的存储过程
#传入员工姓名返回对应的部门名称
DELIMITER $
CREATE PROCEDURE finddeptname(IN stuffname VARCHAR(20),OUT deptname VARCHAR(20))
BEGIN
SELECT dt.department_name INTO deptname
FROM department d LEFT JOIN department_type dt
ON d.department_id = dt.department_id
WHERE stuffname = d.stuff_name;
END $
#调用函数
CALL finddeptname('LJQ',@deptname);
SELECT @deptname;
- 带IN的存储过程
#传入两个工资并计算年薪
DELIMITER $
CREATE PROCEDURE salaryear(INOUT salary1 INT,INOUT salary2 INT)
BEGIN
SET salary1 = salary1*12;
SET salary2 = salary2*12;
END $
#调用函数
SET @salary1 = 1000;
SET @salary2 = 2343;
CALL salaryear(@salary1,@salary2);
SELECT @salary1,@salary2;
9.3 其他存储过程的命令
#删除存储过程
DROP PROCEDURE 存储过程名;
#查看存储过程
SHOW CREATE PROCEDURE 存储过程名;
9.4 函数
- 基础概念
- 定义:是一组运行编译好的sql语句集
- 优点:提高重用性,减少冗余度,减少SQL编译次数,以及和服务器连接交互的慈湖
- 函数和存储过程中的区别
- 存储过程可以没有返回或多个返回,函数有且只有一个返回
- 存储过程中适合做批量插入,函数适合做处理数据后返回的结果
- 语法
#创建函数语法
DELIMITER $
CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型 -- 注意这个是RETURNS不是RETURN
BEGIN
函数体 -- 函数体必须有return语句进行返回,其中的return不起到中断作用,放哪里都可以,建议放最后
END
#调用函数
SELECT 函数名(参数列表)
#查看函数 SHOW CREATE FUNCTION 函数名
#删除函数 DROP FUNCTION 函数名
```mysql
#返回员工个数
DELIMITER $
CREATE FUNCTION stuffcount() RETURNS INT
BEGIN
DECLARE c INT DEFAULT 0;
SELECT COUNT(*)INTO c FROM department;
RETURN c;
END $
#调用
SELECT stuffcount()
#查看函数
SHOW CREATE FUNCTION stuffcount
#删除函数
DROP FUNCTION stuffcount
9.5 循环结构
- WHILE
#WHILE语法
循环名:WHILE 循环条件
DO
循环体;
END 循环名;
#批量插入到teacher表中,如果大于20条则停止
DELIMITER $
CREATE PROCEDURE pro_insert(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
pIn:WHILE i<=insertCount DO
INSERT INTO teacher(tname) VALUES(CONCAT('教师',i));
SET i=i+1;
END WHILE pIn;
END $
#调用存储空间
CALL pro_insert(10);
- LOOP
#LOOP语法 没有循环条件可以用来模拟死循环
循环名:LOOP
循环条件;
END LOOP 循环名;
- REPEAT
#REPEAT语法
循环名:REPEAT
循环体;
UNTIL 循环结束条件
END REPEAT 循环名
- 循环控制
- ITERATE 类似于continue
- LEAVE 类似于 break
十、数据库的三范式
- 第一范式:必须要有主键,强调的十列的原子性,即列不能再分割为其他列
- 第二范式:非主键列必须完全依赖于主键列,完全依赖要求不允许存在非主主键依赖于主键中的某一部分属性(主键有可能是多个属性构成)。满足第二范式的条件是满足第一范式,
- 第三范式:非主键列必须直接雨来主键列,不能存在传递依赖
- 实际开发中三范式能遵守尽量遵守,因为有些情况下我们是需要冗余度去提高效率
十一、附录
- department 表
stuff_id | stuff_name | stuff_salary | department_id | manager | join_date |
1 | LDJ | 5000 | 1 | 2 | 2019/7/24 |
2 | JQQ | 9000 | 2 | 4 | 2019/7/24 |
3 | LXX | 4237 | 0 | 6 | 2019/7/24 |
4 | LXN | 24333 | 2 | 2 | 2019/7/24 |
5 | LNN | 12323 | 2 | 3 | 2032/8/1 |
6 | LN | 2343 | 0 | | 2019/7/24 |
7 | LJQ | 123213 | 1 | 3 | 2019/7/24 |
8 | LJJ | 2343 | 2 | 2 | 2019/7/24 |
9 | JQ_LN | 30033 | 0 | 2 | 2019/7/24 |
10 | JQQ | 223 | | | 2019/7/24 |
12 | LPP | 3000 | | 0 | 2019/7/26 |
14 | LKA | 3000 | | 0 | 2019/7/26 |
15 | LBB | 3000 | | 0 | 2019/7/26 |
16 | XQQ | 3000 | | 0 | 2019/7/26 |
18 | XJJ | 5000 | | 0 | 2019/7/26 |
20 | LSS | 3333 | 2 | 1 | 2019/7/26 |
- department_type 表
department_name | department_id |
人事部 | 0 |
研发部 | 1 |
后勤部 | 2 |
- stuff_role 表
MAX | MIN | role |
14999 | 5000 | 员工 |
100000 | 15000 | 经理 |
4999 | 0 | 临时工作者 |
1 | | 暂无 |
- teacher 表
teacher_id | tname |
1 | 231 |
- stu_info表
snum | sname | gender | person_id | join_timet | teacher_id |
1 | ln | n | we | 2019/7/29 15:13 | 1 |
19 | LDJ | | | 2019/7/30 9:52 | |
20 | LDJ | | | 2019/7/30 9:53 | |