五、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:Users18392>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:Users18392>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:Users18392>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:Users18392>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:Users18392>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:Users18392>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:Users18392>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:Users18392>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 -
-
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