mysql<七>
-- ########## 01、集合逻辑 ########## -- MySQL中,只实现了一种集合逻辑:逻辑与,有两种用法:UNION 和 UNION ALL -- 临时表1
CREATE TABLE temp1
(
id INT NOT NULL
); -- 临时表2
CREATE TABLE temp2
(
id INT NOT NULL
); -- 模拟数据
INSERT INTO temp1 VALUES(1), (2);
INSERT INTO temp2 VALUES(2), (3); SELECT * FROM temp1;
SELECT * FROM temp2; -- UNION:进行逻辑与操作的集合中相同的元素在结果中出现一次
(
SELECT * FROM temp1
)
UNION
(
SELECT * FROM temp2
); -- UNION ALL:进行逻辑与操作的集合中相同的元素在结果中都出现
(
SELECT * FROM temp1
)
UNION ALL
(
SELECT * FROM temp2
); -- 使用UNION 或 UNION ALL进行逻辑与操作后得到的结果还是一个集合
SELECT *
FROM
(
(
SELECT * FROM temp1
)
UNION
(
SELECT * FROM temp2
)
) AS temp; SELECT *
FROM
(
(
SELECT * FROM temp1
)
UNION ALL
(
SELECT * FROM temp2
)
) AS temp; -- ########## 02、视图(View) ########## -- 视图:View,从其他表中抽取部分 或 全部字段形成的一种映射,在某种程度上可以理解为临时表
-- 使用场景:一般用于方便查询 -- 创建视图的格式:
-- create view 视图名称
-- AS
-- SQL语句 -- 1、基于单表的视图操作 -- 需求:查询学生信息(涉及学生姓名 和 学生性别),只给使用者查看这两列字段的内容
-- 创建视图
CREATE VIEW vw_studentinfo
AS
SELECT studentname AS 学生姓名, studentgender AS 学生性别
FROM studentinfo; -- 使用视图进行查询
SELECT * FROM vw_studentinfo; -- 使用视图进行新增
-- 错误代码: 1423 Field of view 'test.vw_studentinfo' underlying table doesn't have a default value
INSERT INTO vw_studentinfo VALUES('孙权', '男');
SELECT * FROM studentinfo; -- 使用视图进行修改,可以执行成功
-- 注意:对视图中数据的修改最终反映在视图基于的原始表的数据中
UPDATE vw_studentinfo SET 学生性别 = '女' WHERE 学生姓名 = '关羽';
-- 使用视图进行查询
SELECT * FROM vw_studentinfo;
-- 对视图抽取的原始表进行查询
SELECT * FROM studentinfo; -- 使用视图进行删除,可以执行成功
-- 注意:对视图中数据的删除最终反映在视图基于的原始表的数据中
DELETE FROM vw_studentinfo WHERE 学生姓名 = '关羽';
-- 使用视图进行查询
SELECT * FROM vw_studentinfo;
-- 对视图抽取的原始表进行查询
SELECT * FROM studentinfo; -- 2、基于多表连接的视图操作 -- 需求:查询部门信息及部门对应的员工姓名
CREATE VIEW vw_dept_employee
AS
SELECT d.deptid AS 部门编号, d.deptname AS 部门名称, e.employeename AS 员工姓名
FROM dept AS d
LEFT JOIN employee AS e
ON d.deptid = e.deptid; -- 使用视图进行查询
SELECT * FROM vw_dept_employee; -- 使用视图进行新增
-- 错误代码: 1394 Can not insert into join view 'test.vw_dept_employee' without fields list
INSERT INTO vw_dept_employee VALUES(NULL, '后勤部', '祝融'); -- 使用视图进行修改
UPDATE vw_dept_employee SET 部门名称 = '人力资源部' WHERE 部门编号 = 4;
-- 使用视图进行查询
SELECT * FROM vw_dept_employee;
-- 对视图抽取的原始表进行查询
SELECT * FROM dept; -- 使用视图进行修改
UPDATE vw_dept_employee SET 员工姓名 = '赵云' WHERE 部门编号 = 1 AND 员工姓名 = '张飞';
-- 使用视图进行查询
SELECT * FROM vw_dept_employee;
-- 对视图抽取的原始表进行查询
SELECT * FROM employee; -- 使用视图进行修改
UPDATE vw_dept_employee SET 员工姓名 = '张飞' WHERE 员工姓名 = '赵云';
-- 使用视图进行查询
SELECT * FROM vw_dept_employee;
-- 对视图抽取的原始表进行查询
SELECT * FROM employee; -- 使用视图进行修改
-- 错误代码: 1393 Can not modify more than one base table through a join view 'test.vw_dept_employee'
-- 因为对连接视图来说,修改一条记录对于其他的部门名称也是开发部的记录无法一次都修改
UPDATE vw_dept_employee SET 员工姓名 = '赵云', 部门名称 = '通宵部' WHERE 员工姓名 = '张飞';
-- 变通的写法,可以执行成功
UPDATE vw_dept_employee SET 部门名称 = '通宵部' WHERE 部门编号 = 1;
-- 使用视图进行查询
SELECT * FROM vw_dept_employee;
-- 对视图抽取的原始表进行查询
SELECT * FROM dept; -- 使用视图进行删除,连接视图不给删除数据
-- 错误代码: 1395 Can not delete from join view 'test.vw_dept_employee'
DELETE FROM vw_dept_employee WHERE 员工姓名 = '张飞';
-- 错误代码: 1395 Can not delete from join view 'test.vw_dept_employee'
DELETE FROM vw_dept_employee WHERE 部门名称 = '通宵部'; -- 视图的意义:封装性的体现
-- 使用者不需要知道数据的内在逻辑,也不需要懂高深的SQL语法,只要拿着视图就可以使用,很方便,降低了开发难度,也在一定程度上保证了数据安全 -- ########## 03、事务(Transaction) ##########
-- 事务的理解:一件事情的处理需要多个步骤,当多个步骤中的某一个步骤发生异常时,
-- 考虑接着如果处理这个事情是恢复到最初的状态或是恢复到之前的某一个状态,或者继续做下去的机制
-- 从操作的简洁性上考虑,将这件事情恢复到最初的状态,再重新执行,是最简单的处理方式 -- 术语:在事情的处理过程中,从某一个后续的状态恢复至之前的莫一个状态的动作,称为事务的回滚(rollback)
-- 类比:小学体育课上的翻垫子 -- MySQL是支持事务的关系型数据库(安装时选择支持事务的数据库引擎InnoDB)
-- 事务通常用在增加、修改、删除(DML)操作中 CREATE TABLE test
(
id INT
); -- MySQL中的事务处理有两种方式:
-- 方式1、使用BEGIN、ROLLBACK、COMMIT关键字来实现
-- BEGIN: 开始事务
-- ROOLBACK: 事务回滚
-- COMMIT: 事务确认(提交事务) BEGIN;
INSERT INTO test VALUES(1);
INSERT INTO test VALUES(2); -- 先执行BEGIN及后面2条插入语句,再执行下句,可以查询出2条记录
SELECT * FROM test; BEGIN;
INSERT INTO test VALUES(3);
INSERT INTO test VALUES(4);
COMMIT; -- 先执行BEGIN及后面2条插入语句以及COMMIT,再执行下句,可以查询出4条记录(前2条记录是上一步操作插入的)
SELECT * FROM test; -- 发现插入后,写COMMIT语句 和 不写COMMIT语句效果一致 BEGIN;
INSERT INTO test VALUES(5);
ROLLBACK; -- 先执行BEGIN及后面1条插入语句以及ROLLBACK,再执行下句,可以查询出4条记录(前2条记录是上一步操作插入的)
-- 即208行的插入操作是无效的
SELECT * FROM test; -- 方式2、对于MySQL的DML操作,默认都是自动提交(事务)的
-- 所以,想看到手工操作事务的效果,首先设置MySQL的自动提交参数为否
-- 设置MySQL的自动提交参数为否,也就是设置需要手动提交
SET AUTOCOMMIT = 0; INSERT INTO test VALUES(6); -- 在当前的SQLyog客户端中查询test表,显示数据6已经插入进去了,但是这是假象
-- 在命令行窗口中查询test表,数值6是不存在的
SELECT * FROM test; -- 既然设置了AUTOCOMMIT参数为0,禁止自动提交,那么就需要显式的进行手动提交
COMMIT; -- 手动提交后,不论在当前的SQLyog客户端中查看test表,还是在命令行窗口中查看test表,数值6真的插入进去了
SELECT * FROM test; -- 操作后恢复默认设置
SET AUTOCOMMIT = 1; -- ########## 04、变量 ##########
-- 1、变量定义:declare 变量名 数据类型 [默认值];
DECLARE i INT DEFAULT 0;
DECLARE j DATETIME;
DECLARE k VARCHAR(10); -- 2、用户变量:使用@ + 英文字符 -- 3、用户变量赋值:set 变量名 = 表达式值;
-- SELECT 直接量 INTO 用户变量
SELECT 'test' INTO @i;
SELECT @i; -- SET 用户变量 = 直接量
SET @j = '中华人民共和国';
SELECT @j; SET @k = 1 + 2 + 3;
SELECT @k; -- ########## 05、存储过程(Stored Procedure) ##########
-- 存储过程:Stored Procedure
-- 数据库中的SQL语句在执行时都是需要先编译再执行的,存储过程就是这样一组为了完成特定功能的SQL语句
-- 存储过程经过编译存储在数据库中,并不立即执行,而是使用者通过自定义的存储过程的名称的调用并赋予制定的参数来进行执行 -- 格式:
-- create procedure 存储过程名([参数1, 参数2, ...])
-- [特性]
-- 过程体 -- 存储过程的创建和使用:
-- 1、首先需要使用DELIMITER关键声明分隔符,因为MySQL中默认以;作为分隔符
-- 所以如果没有再声明一个分隔符,MySQL编译器就会把存储过程当作SQL语句来进行处理,那样存储过程的编译过程就会出错
-- 注意:使用完成后需要把设置的分隔符再还原回去
-- 2、存储过程根据参数的有无分为:无参、有参输入、有参输出、有参输入输出 四种形式 SELECT * FROM userinfo;
DESC userinfo; INSERT INTO userinfo VALUES(1, '诸葛亮', '888'), (2, '司马懿', '666'); -- 1、无参的存储过程
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_select_userinfo()
-- 使用BEGIN...END语句块
BEGIN
SELECT * FROM userinfo;
END
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; -- 调用存储过程:CALL 存储过程名称();
CALL proc_select_userinfo(); -- 在无参的存储过程中使用用户变量
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_test_var()
-- 使用BEGIN...END语句块
BEGIN
SELECT CONCAT(@i, 'MySQL');
END
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; SET @i = '真简单';
CALL proc_test_var(); -- 显示结果为:真简单MySQL -- 2、输入参数的存储过程
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_select_userinfo_by_id(IN _id INT)
-- 使用BEGIN...END语句块
BEGIN
SELECT *
FROM userinfo
WHERE userid = _id;
END
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; -- 调用存储过程:CALL 存储过程名(输入参数值);
CALL proc_select_userinfo_by_id(1);
-- 可以在其他窗口(比如:命令行窗口)中执行编译好的存储过程
CALL proc_select_userinfo_by_id(2); -- 3、输出参数的存储过程
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_select_count_userinfo(OUT _number INT)
-- 使用BEGIN...END语句块
BEGIN
SELECT COUNT(*) INTO _number
FROM userinfo;
END
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; -- 调用存储过程,使用用户变量作为输出参数
CALL proc_select_count_userinfo(@outparam);
-- 查看输出参数用户变量的内容
SELECT @outparam AS `userinfo表的行数`; -- 4、输入输出参数的存储过程
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_select_count_userinfo_by_id(INOUT _param INT)
-- 使用BEGIN...END语句块
BEGIN
SELECT COUNT(*) INTO _param
FROM userinfo
GROUP BY userid
HAVING userid = _param;
END
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; -- 调用存储过程,定义并给用户变量赋值,调用存储过程并使用赋值的用户变量,最后获取取得输出参数的用户变量的内容
SET @inoutparam = 2;
CALL proc_select_count_userinfo_by_id(@inoutparam);
SELECT @inoutparam AS `userid为2的用户记录条数`; -- 5、存储过程中的变量作用域
-- 内部的变量在其作用域范围内可以进行访问,在执行到end时,内部变量消失,在其作用域外,变量不可以使用 -- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_test_var_scope()
-- 使用BEGIN...END语句块
BEGIN
DECLARE i VARCHAR(10) DEFAULT '外层变量'; BEGIN
DECLARE i VARCHAR(10) DEFAULT '内层变量'; SELECT i;
END; SELECT i;
END
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; CALL proc_test_var_scope(); -- 使用 DROP PROCEDURE 存储过程名; 对存储过程进行删除
DROP PROCEDURE proc_test_var_scope; DESC test;
SELECT * FROM test; -- 6、存储过程中使用控制语句(选择结构):if...then...elseif...else...end if
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_test_if(IN param INT)
-- 使用BEGIN...END语句块
BEGIN
DECLARE i INT DEFAULT 123;
IF param = 1 THEN
INSERT INTO test VALUES(i);
ELSEIF param = 2 THEN
UPDATE test SET id = i * 2;
ELSE
UPDATE test SET id = i * 3;
END IF;
END;
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; DROP PROCEDURE proc_test_if; TRUNCATE TABLE test; CALL proc_test_if(1);
SELECT * FROM test; CALL proc_test_if(2);
SELECT * FROM test; CALL proc_test_if(3);
SELECT * FROM test; -- 7、存储过程中使用控制语句(选择结构):case...when...then...else...end case
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_test_case(IN param INT)
-- 使用BEGIN...END语句块
BEGIN
DECLARE i INT DEFAULT 123;
CASE param
WHEN 1 THEN
INSERT INTO test VALUES(i);
WHEN 2 THEN
UPDATE test SET id = i * 2;
ELSE
UPDATE test SET id = i * 3;
END CASE;
END;
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; TRUNCATE TABLE test; CALL proc_test_case(1);
SELECT * FROM test; CALL proc_test_case(2);
SELECT * FROM test; CALL proc_test_case(3);
SELECT * FROM test; -- 8、存储过程中使用控制语句(循环结构):while...do...end while
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_test_while()
-- 使用BEGIN...END语句块
BEGIN
DECLARE i INT;
SET i = 0;
WHILE i < 5 DO
INSERT INTO test VALUES(i);
SET i = i + 1;
END WHILE;
END;
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; TRUNCATE TABLE test; CALL proc_test_while(); SELECT * FROM test; -- 9、存储过程中使用控制语句(循环结构):repeat...until...end repeat
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_test_repeat()
-- 使用BEGIN...END语句块
BEGIN
DECLARE i INT;
SET i = 0;
REPEAT
INSERT INTO test VALUES(i);
SET i = i + 1;
UNTIL i >= 5
END REPEAT;
END;
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; TRUNCATE TABLE test; CALL proc_test_repeat(); SELECT * FROM test; -- 注意:while是在执行前进行检查,repeat在执行后进行检查 -- 10、存储过程中使用控制语句(循环结构):loop...end loop
-- 声明分隔符为 $$
DELIMITER $$
CREATE PROCEDURE proc_test_loop()
-- 使用BEGIN...END语句块
BEGIN
DECLARE i INT;
SET i = 0;
LOOP_LABLE: LOOP
INSERT INTO test VALUES(i);
SET i = i + 1;
IF i >= 5 THEN
LEAVE LOOP_LABLE;
END IF;
END LOOP;
END;
-- 下句使用声明的分隔符,表明到这里都是需要编译的存储过程的内容,不需要执行
$$
-- 使用完毕后,再把分隔符还原为分号;
DELIMITER ; TRUNCATE TABLE test; CALL proc_test_loop(); SELECT * FROM test;
mysql<七>的更多相关文章
- Hadoop 中利用 mapreduce 读写 mysql 数据
Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...
- mysql每秒最多能插入多少条数据 ? 死磕性能压测
前段时间搞优化,最后瓶颈发现都在数据库单点上. 问DBA,给我的写入答案是在1W(机械硬盘)左右. 联想起前几天infoQ上一篇文章说他们最好的硬件写入速度在2W后也无法提高(SSD硬盘) 但这东西感 ...
- LINUX篇,设置MYSQL远程访问实用版
每次设置root和远程访问都容易出现问题, 总结了个通用方法, 关键在于实用 step1: # mysql -u root mysql mysql> Grant all privileges o ...
- nodejs进阶(6)—连接MySQL数据库
1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...
- MySQL高级知识- MySQL的架构介绍
[TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...
- 闰秒导致MySQL服务器的CPU sys过高
今天,有个哥们碰到一个问题,他有一个从库,只要是启动MySQL,CPU使用率就非常高,其中sys占比也比较高,具体可见下图. 注意:他的生产环境是物理机,单个CPU,4个Core. 于是,他抓取了CP ...
- 我的MYSQL学习心得(一) 简单语法
我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制
将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...
- 当忘记mysql数据库密码时如何进行修改
因为长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件 ...
随机推荐
- flex布局使用方法简要汇总
近期因为使用inline-block,在项目部署后出现了一点小问题,几番解决未果,遂使用flex布局,于是借此机会对flex布局的用法做一个简要的汇总. 遇到的bug如下: 本想两个div使用inli ...
- P2814 家谱
我真没什么创意了woc.. so,为什么一道水题是蓝色的???哦哦哦,水好像就是蓝色的,emmm那就不是恶意评分了嘤嘤嘤 ... 好吧实际上可能是非c党对于字符串的处理需要进行编号和结构体,会麻烦一点 ...
- Ubuntu安装并使用emacs
1. sudo add-apt-repository ppa:kelleyk/emacs 2. sudo apt update sudo apt install emacs26 3.安装完成,查看em ...
- ocelot集成consul服务发现
首先下载consul 点击这里下载 转到解压文件夹目录输入cmd命令 consul agent -dev (有时候会卡住按一下方向键上) 在浏览器中输入http://localhost:8500/u ...
- 20191209 Linux就该这么学(1-3)
1. 部署虚拟环境安装 Linux 系统 RPM 是为了简化安装的复杂度,而 Yum软件仓库是为了解决软件包之间的依赖关系. 2. 新手必须掌握的Linux命令 通常来讲,计算机硬件是由运算器.控制器 ...
- js多张图片合成一张图,canvas(海报图,将二维码和背景图合并) -----vue
思路:vue中图片合并 首先准备好要合并的背景图,和请求后得到的二维码, canvas画图,将两张背景图和一张二维码用canvas画出来, 将canvas再转为img 注意canvas和图片的清晰图和 ...
- wget断点续传下载需要登录的网站上的大文件
1 举个例子 xcode 2 方法 wget --load-cookies=cookies.txt -c url -c是断点续传,如果网络断了,再运行该命令会接着最新的下载继续下载. --load- ...
- python nonlocal 的具体原理
很多文章都大概列了下nonlocal的具体用法,比如看到几篇文章写的 “nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量” 看完以后我感觉自己是懂了,但光从这句话来说还没完全理解它 ...
- linux中/etc/profile 和 ~/.bash_profile 的区别
在 linux中设置环境变量一般使用bash_profile进行配置 其中/etc/bash_profile 表示系统整体设置 ,生效后系统内所有用户可用而 ~/.bash_profile 只表示当前 ...
- 10分钟学会RabbitMQ安装部署
一.单机版的 RabbitMQ 的安装部署 1.安装 Erlang 环境 wget http://erlang.org/download/otp_src_19.3.tar.gz tar -zxvf o ...