从MySQL到ORM(三):连接、存储过程和用户权限
一、联结表
数据仍使用前文中的数据。
1、子查询
作为子查询的SELECT语句只能查询单个列。企图检索多个列将返回错误。
-- 作为查询条件使用
-- 查看TNT2订单对应的客户ip(order表)
SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id='TNT2');
-- 根据TNT2订单的客户ip查看客户信息(cust表)
SELECT cust_name, cust_contact FROM customers WHERE cust_id IN (SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id='TNT2'));
-- 作为计算字段使用
-- 计算每个客户的订单数据
SELECT cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;
2、创建链接
图片示例 | 链接方式 | 关键字 | 语句示例 |
内连接 | INNER JOIN ... ON | SELECT <select_list> FROM A INNER JOIN B ON A.key = B.key | |
左外连接 | LEFT JOIN ... ON | SELECT <select_list> FROM A LEFT JOIN B ON A.key = B.key | |
左外连接 | LEFT JOIN ... ON ... WHERE B.key IS NULL | SELECT <select_list> FROM A LEFT JOIN B ON A.key = B.key WHERE B.key IS NULL | |
右外连接 | RIGHT JOIN ... ON | SELECT <select_list> FROM A RIGHT JOIN B ON A.key = B.key | |
右外连接 | RIGHT JOIN ... ON ... WHERE A.key IS NULL | SELECT <select_list> FROM A RIGHT JOIN B ON A.key = B.key WHERE A.key IS NULL | |
全外连接 | UNION |
SELECT <select_list> FROM A LEFT JOIN B ON A.key = B.key UNION SELECT <select_list> FROM A RIGHT JOIN B ON A.key = B.key |
|
全外连接 | (WHER IS NULL) UNION ... (WHER IS NULL) |
SELECT <select_list> FROM A LEFT JOIN B ON A.key = B.key WHERE B.key IS NULL UNION SELECT <select_list> FROM A RIGHT JOIN B ON A.key = B.key WHERE A.key IS NULL |
用例:
-- 笛卡尔积:n * m
-- SELECT * FROM vendors, products;
SELECT orders.cust_id, cust_name FROM orders CROSS JOIN customers;-- 没有WHERE子句
-- 内连接
-- SELECT * FROM vendors, products WHERE vendors.vend_id = products.vend_id;
SELECT * FROM vendors INNER JOIN products on vendors.vend_id = products.vend_id;
-- 左外连接(a),根据A表相应字段取列
SELECT orders.cust_id, cust_name FROM orders LEFT JOIN customers on customers.cust_id = orders.cust_id;
-- 左外连接b,只取A表中无B表相应字段的列
SELECT vendors.vend_id, vend_name, vend_country FROM vendors LEFT JOIN products on vendors.vend_id = products.vend_id where products.vend_id IS NULL ORDER BY vend_id;
-- 右外连接(a),同左外连接(a)
SELECT orders.cust_id, cust_name FROM orders RIGHT JOIN customers on customers.cust_id = orders.cust_id;
-- 右外连接(b),同左外连接(b)
SELECT customers.cust_id, cust_name FROM orders RIGHT JOIN customers on customers.cust_id = orders.cust_id WHERE orders.cust_id IS NULL; -- 全外连接,两者id相等的行和不相等的行都保留
SELECT customers.cust_id, orders.order_num FROM orders LEFT JOIN customers on customers.cust_id = orders.cust_id
UNION
SELECT customers.cust_id, orders.order_num FROM orders RIGHT JOIN customers on customers.cust_id = orders.cust_id;
-- 全外连接,只保留两者id不相等的行,这里两个WHERE子句一样是因为customers的id字段完全包含orders中的字段
SELECT customers.cust_id, orders.order_num FROM orders LEFT JOIN customers on customers.cust_id = orders.cust_id WHERE orders.cust_id IS NULL
UNION
SELECT customers.cust_id, orders.order_num FROM orders RIGHT JOIN customers on customers.cust_id = orders.cust_id WHERE orders.cust_id IS NULL
3、视图
视图是虚拟的表。它只包含使用时动态检索数据的查询,换言之,视图存储查询语句。保存查询语句可以使用视图。视图的一些规则:
- 与表名一样,视图必须唯一命名。
- 视图数目没有限制。
- 为了创建视图,必须具有足够的访问权限。
- 视图可以嵌套。
- 视图查询中不要使用GROUP BY。
- 视图不能索引,也不能有关联的触发器或默认值。
-- 创建视图
-- CREATE VIEW viewname AS SELECT *
CREATE VIEW productcustomers AS SELECT cust_name, cust_contact, prod_id FROM customers, orders, orderitems WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num; CREATE VIEW orderitemsexpanded AS SELECT order_num, prod_id, quantity, item_price, quantity*item_price AS expanded_price FROM orderitems; -- 执行视图查询时会首先执行视图
SELECT cust_name, cust_contact FROM productcustomers WHERE prod_id ='FB';
SELECT * FROM orderitemsexpanded WHERE order_num = 20009;
-- 删除视图
-- DROP VIEW viewname;
DROP VIEW productcustomers;
二、存储过程
1、存储过程
1.简介
存储过程是存储在数据库目录中的一段声明性SQL语句。它像是编程语言中的函数或者可执行代码块。通过声明一段可执行的SQL语句,既可以避免一行行的输入SQL语句,又可以将这段SQL语句重复使用。
存储过程的优点:
- 通常存储过程有助于提高应用程序的性能。
- 存储过程有助于减少应用程序和数据库服务器之间的流量,因为应用程序不必发送多个冗长的SQL语句,而只能发送存储过程的名称和参数。
- 存储的程序对任何应用程序都是可重用的和透明的。
- 存储的程序是安全的。
存储过程的缺点:
- 如果使用大量存储过程,那么使用这些存储过程的每个连接的内存使用量将会大大增加。
- 存储过程的构造使得开发具有复杂业务逻辑的存储过程变得更加困难。
- 很难调试存储过程。
- 开发和维护存储过程并不容易。
2.使用
-- 创建存储过程
DELIMITER // -- DELIMITER // 和DELIMITER;用于划分一块范围来声明存储过程
CREATE PROCEDURE GetAllProducts()-- CRAET PROCEDURE 创建一个存储过程
BEGIN-- 存储过程的主体的开始
DECLARE id INT(20) DEFAULT 1003;-- DECLARE variable datatype(size) DEFAULT value,声明局部变量;它只能在BEGIN和END之间生效
SET id = 1001;-- 变量赋值
SELECT * FROM products WHERE vend_id = id;-- SQL语句
END //-- 存储过程的主体的结束,结尾用//
DELIMITER ; -- 调用存储过程
CALL GetAllProducts();
-- 删除存储过程
DROP PROCEDURE IF EXISTS `GetAllProducts`; -- 设置参数
DELIMITER //
CREATE PROCEDURE GetProductsByVendId(IN id INT(20), OUT outcome VARCHAR(20))-- 参数默认前缀是IN,即只允许调用函数时给参数传递值;OUT则表示将存储过程的运行结果传递出去,它是个单值参数;
BEGIN
SELECT count(*) INTO outcome FROM products WHERE vend_id = id;
END //
DELIMITER ;
CALL GetProductsByVendId(1003, @outcome);-- 不直接打印结果,而是把结果传递给了全局变量@outcome
SELECT @outcome;-- 设置全局变量可以用SET variable = value; -- 条件语句
/* IF condition THEN
sql
ELSEIF condition THEN
sql
...
ELSE
sql
END IF */ DELIMITER //
CREATE PROCEDURE GetPriceLevel(IN prod_id CHAR(10), OUT price_level VARCHAR(20))
BEGIN
DECLARE price DECIMAL(8,2);
SELECT prod_price INTO price FROM products WHERE products.prod_id = prod_id; IF price <= 5 THEN
SET price_level = 'cheap';
ELSEIF (price > 5 AND price <= 10) THEN
SET price_level = 'ordinary';
ELSE
SET price_level = 'expensive';
END IF;
END //
DELIMITER ;
CALL GetPriceLevel('ANV01', @price_list);
SELECT @price_list; -- 循环语句
/* WHILE condition DO
statements
END WHILE */
-- 函数 略
-- 游标 https://www.yiibai.com/mysql/cursor.htm
2、事务处理
1.概念
事务处理(transaction processing)用于保证SQL操作的完整性。它提供一种处理机制来应对SQL或者其它环境因素可能造成的异常结果。事务处理中的几个术语:
- 事务(transaction),指一组SQL语句。
- 回退(rollback),指撤销指定SQL语句的过程。
- 提交(commit),指将未存储的SQL语句结果些人数据库表。
- 保留点(savepoint),指事务处理中设置的临时占位符(placeholder),它可以回退。
事务处理用来管理(可以回退)INSERT、UPDATE和DELETE语句,不能回退SELECT语句,也不能回退CREATE或者DROP操作。
在MySQL中,事务开始使用COMMIT或ROLLBACK语句开始工作和结束。开始和结束语句的SQL命令之间形成了大量的事务。
2.ACID特性
事务有以下四个标准属性的缩写ACID,通常被称为:
- 原子性: 指事务是一个不可再分割的工作单元,事务中的操作要么都发生,要么都不发生。
- 一致性: 在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
- 隔离性: 多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。
- 持久性: 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
3.简单用例
-- MySQL默认出错自动回滚,没出错自动提交
BEGIN;
SAVEPOINT place;
INSERT INTO orders VALUES(20010, '2005-09-08 00:00:00', 10001);
ROLLBACK;-- ROLLBACK place
COMMIT
在COMMIT提交之前,ROLLBACK语句来撤销事务中所做的每一项工作,即便工作是成功的也可以撤销,它可以一直撤销到事务的开始。在COMMIT提交之后,只能使用DELETE,INSERT或者UPDATE语句,ROLLBACK是不行的。
三、访问控制和用户权限管理
内容摘自MySQL教程(https://www.yiibai.com/mysql)
1、访问控制
当客户端连接到服务器时,MySQL访问控制有两个阶段:
- 连接验证:连接到MySQL数据库服务器的客户端需要有一个有效的用户名和密码。此外,客户端连接的主机必须与MySQL授权表中的主机相匹配。
- 请求验证:当连接成功建立后,对于客户端发出的每个语句,MySQL会检查客户端是否具有足够的权限来执行该特定语句。 MySQL能够检查数据库,表和字段级别的权限。
MySQL安装程序自动创建一个名为mysql
的数据库。 mysql
数据库包含五个主要的授权表(user、db、host、tables_priv和columns_priv),它们存储了不同级别上对用户权限的设置。并可通过GRANT和REVOKE等语句间接操作这些表。
表名 | 权限 |
mysql.user | 包含用户帐户和全局权限列。MySQL使用user 表来接受或拒绝来自主机的连接。 在user 表中授予的权限对MySQL服务器上的所有数据库都有效 |
mysql.db | 包含数据库级权限。MySQL使用数据库表来确定用户可以访问哪个数据库以及哪个主机。在db 表中的数据库级授予的特权适用于数据库,所有对象属于该数据库,例如表,触发器,视图,存储过程等 |
mysql.table_priv |
包含表级别权限,权限适用于表中所有列 |
mysql.columns_priv |
授予的权限只适用于字段 |
mysql.procs_priv |
包含存储函数和存储过程的权限 |
2、用户权限管理
MySQL8以上提供了role对象进行多用户权限管理。
/* GRANT
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
TO user_specification [, user_specification] ...
[REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]
[WITH with_option ...]
*/ -- 创建单个用户账户
-- CREATE USER username@localhost IDENTIFIED BY passwd
CREATE USER dbadmin@localhost IDENTIFIED BY 'pwd123';
-- 查看该用户权限
SHOW GRANTS FOR dbadmin@localhost;
-- 赋予该用户对test数据库下customer数据表的操作权限
GRANT ALL PRIVILEGES ON test.customer TO dbadmin@localhost;-- 可以到mysql.table_priv授权表中查看设置
-- 更新
FLUSH PRIVILEGES;
SHOW GRANTS FOR dbadmin@localhost;
SELECT * FROM mysql.user;
-- 删除权限
REVOKE ALL PRIVILEGES ON test.customer FROM dbadmin@localhost;
dbadmin@localhost用来指定账户名和主机地址。
-- 创建单个用户账户
CREATE USER dbadmin@localhost IDENTIFIED BY 'pwd123';
-- 创建一个数据库
CREATE DATABASE apple;
-- 赋予该用户对apple数据库的操作权限
GRANT SELECT,INSERT,ALTER,UPDATE,CREATE,DELETE,DROP ON apple.* TO dbadmin@localhost;-- 可以到mysql.table_priv授权表中查看设置
-- 更新
FLUSH PRIVILEGES;
-- 删除权限,注意这里apple、@和localhost的引号
REVOKE SELECT ON apple.* FROM 'apple'@'localhost';
-- 查看权限
SHOW GRANTS FOR apple@localhost;
GRANT SELECT ON apple.* FROM 'apple'@'localhost';
SHOW GRANTS FOR apple@localhost;
GRANT子句设置用户权限,包括对数据库级、表级、字段、查询语句等的设置。
权限 | 含义 | 全局 | 数据库 | 表 | 列 | 过程 | 代理 |
---|---|---|---|---|---|---|---|
ALL [PRIVILEGES] |
授予除了GRANT OPTION 之外的指定访问级别的所有权限 |
||||||
ALTER |
允许用户使用ALTER TABLE 语句 |
x | x | x | |||
ALTER ROUTINE |
允许用户更改或删除存储程序 | x | x | x | |||
CREATE |
允许用户创建数据库和表 | x | x | x | |||
CREATE ROUTINE |
x | x | |||||
CREATE TABLESPACE |
允许用户创建,更改或删除表空间和日志文件组 | x | |||||
CREATE TEMPORARY TABLES |
允许用户使用CREATE TEMPORARY TABLE 创建临时表 |
x | x | ||||
CREATE USER |
允许用户使用CREATE USER ,DROP USER ,RENAME USER 和REVOKE ALL PRIVILEGES 语句。 |
x | |||||
CREATE VIEW |
允许用户创建或修改视图 | x | x | x | |||
DELETE |
允许用户使用DELETE |
x | x | x | |||
DROP |
允许用户删除数据库,表和视图 | x | x | x | |||
EVENT |
能够使用事件计划的事件 | x | x | ||||
EXECUTE |
允许用户执行存储过程/存储函数 | x | x | ||||
FILE |
允许用户读取数据库目录中的任何文件 | x | |||||
GRANT OPTION |
允许用户有权授予或撤销其他帐户的权限 | x | x | x | x | x | |
INDEX |
允许用户创建或删除索引 | x | x | x | |||
INSERT |
允许用户使用INSERT 语句 |
x | x | x | x | ||
LOCK TABLES |
允许用户在具有SELECT 权限的表上使用LOCK TABLES |
x | x | ||||
PROCESS |
允许用户使用SHOW PROCESSLIST 语句查看所有进程 |
x | |||||
PROXY |
启用用户代理 | ||||||
REFERENCES |
允许用户创建外键 | x | x | x | x | ||
RELOAD |
允许用户使用FLUSH 操作 |
x | |||||
REPLICATION CLIENT |
允许用户查询主服务器或从服务器的位置 | x | |||||
REPLICATION SLAVE |
允许用户使用复制从站从主机读取二进制日志事件 | x | |||||
SELECT |
允许用户使用SELECT 语句 |
x | x | x | x | ||
SHOW DATABASES |
允许用户显示所有数据库 | x | |||||
SHOW VIEW |
允许用户使用SHOW CREATE VIEW 语句 |
x | x | x | |||
SHUTDOWN |
允许用户使用mysqladmin shutdown 命令 |
x | |||||
SUPER |
允许用户使用其他管理操作,如CHANGE MASTER TO ,KILL ,PURGE BINARY LOGS ,SET GLOBAL 和mysqladmin 命令 |
x | |||||
TRIGGER |
允许用户使用TRIGGER 操作 |
x | x | x | |||
UPDATE |
允许用户使用UPDATE 语句 |
x | x | x | x | ||
USAGE |
相当于“无权限” |
从MySQL到ORM(三):连接、存储过程和用户权限的更多相关文章
- Navicat连接Oracle数据库用户权限问题
解决Navicat连接Oracle数据库用户权限问题: 第一步:在cmd窗口运行[sqlplus], 第二步:输入Oracle的用户名和口令连接Oracle数据库, 第三步:执行授权代码,给用户授予D ...
- Windows下降权MYSQL和apche的运行级别(普通用户权限运行)
1.MYSQL的降权运行 新建立一个用户比如mysql net user mysql microsoft /add net localgroup users mysql /del 不属于任何组 ...
- 【MySql】权限不足导致的无法连接到数据库以及权限的授予和撤销
[环境参数] 1.Host OS:Win7 64bit 2.Host IP:192.168.10.1 3.VM: VMware 11.1.0 4.Client OS:CentOS 6 5.Client ...
- Mysql 用户权限管理--从 xxx command denied to user xxx
今天遇到一个mysql 权限的问题,即标题所述 xxx command denied to user xxx,一般mysql 这种报错,基本都属于当前用户没有进行该操作的权限,需要 root 用户授 ...
- MySQL 系列(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句
第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...
- MySQL入门第三天(下)——存储过程与存储引擎
一.存储过程 1.简介 原始的SQL执行的流程: 通过存储过程,便可以简化以上流程,那么存储过程是什么,如何进行性能提高呢? 是什么? 存储过程是可编程的函数,在数据库中创建并保存,可以由SQL语句和 ...
- MySql(三)存储过程和函数
MySql(三)存储过程和函数 一.什么是存储过程和函数 二.存储过程和函数的相关操作 一.什么是存储过程和函数 存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程和函数 ...
- MySQL数据库实验三:连接查询
实验三 连接查询 实验名称:连接查询(2课时) 一.实验目的 理解JOIN语句的操作和基本使用方法,掌握内连接.外连接.自身连接的概念和使用. 二.实验环境 是MS SQL SERVER 200 ...
- mysql 视图,事务,存储过程,触发器
一 视图 视图是一个虚拟表(非真实存在),是跑到内存中的表,真实表是硬盘上的表.使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sq ...
随机推荐
- “全栈2019”Java异常第五章:一定会被执行的finally代码块
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- Mac下安装HomeBrew
本文章为菲利克斯猫(Felix.mao)原创,转载务必在明显处注明:原文链接:http://blog.csdn.net/maojudong/article/details/7918291 1. 前言 ...
- 【vim】插入模式与常用编辑操作
vim不像很多编辑器那样一启动便可以直接编辑文本,需要在普通模式按下i, a等键才会进入插入模式进行文本编辑. 如何进入插入模式 以下的命令都会让vim从普通模式切换到插入模式,但命令执行后的字符插入 ...
- java后台简单从阿里云上传下载文件并通知前端以附件的形式保存
一. 首先开通阿里的OSS 服务 创建一个存储空间在新建一个Bucket 在你新建的bucket有所需的id和key 获取外网访问地址或者是内网 看个人需求 我使用的是外网(内网没用过 估计是部署到阿 ...
- jmeter我们必须搞清楚的问题
我们从以下几个点来看jmeter: 1.jmeter是什么? 2.jmeter为什么我们要使用jmeter?他可以帮我们解决那些事情? 3.怎样使用jmeter做这些事情? 4.我们在什么时候会使用j ...
- 老男孩Day12作业:RabbitMQ-RPC版主机管理程序
一.作业需求 1.可以对指定机器异步的执行多个命令 例子: 请输入操作指令>>>:run ipconfig --host 127.0.0.0 in the call tack ...
- This operation is not available unless admin mode is enabled: FLUSHDB
报错: This operation is not available unless admin mode is enabled: FLUSHDB 参考内容: https://www.cnblogs ...
- How to install Jenkins on CentOS 7
How to install Jenkins on CentOS 7 on March 3, 2018 by AmirLeave a comment Introduction Jenkins is a ...
- SPB 公开课记录
sql server 用工具到处mysql脚本,不过目前有点问题
- Linux网络编程服务器模型选择之并发服务器(上)
与循环服务器的串行处理不同,并发服务器对服务请求并发处理.循环服务器只能够一个一个的处理客户端的请求,显然效率很低.并发服务器通过建立多个子进程来实现对请求的并发处理.并发服务器的一个难点是如何确定子 ...