1. 视图
视图是一个虚拟表,其内容由查询定义。与实际的物理表类似,视图也包含一系列具有名称的列和行数据。视图的数据变化会影响基表,反之,基表的数据变化也会影响视图。
1.1 基本使用
创建视图
创建视图的基本语法如下:
sql
CREATE VIEW 视图名 AS SELECT 查询语句;
示例:查看学生的学号、姓名、成绩和课程号:
ini
SELECT s1.sno, snme, sdept, grade, cno
FROM student s1
JOIN score s2 ON s1.sno = s2.sno;

创建视图 v_s_s
,该视图包含学生学号、姓名、成绩和课程号:
sql
CREATE VIEW v_s_s AS
SELECT s1.sno, snme, sdept, grade, cno
FROM student s1
JOIN score s2 ON s1.sno = s2.sno;

修改视图中的数据:假设我们希望修改马小燕课程号 001
的成绩为 100,若视图支持更新操作,可以修改原表数据:
ini
UPDATE v_s_s
SET grade = 100
WHERE sno = '马小燕' AND cno = '001';

删除视图
删除视图的语法如下:
sql
DROP VIEW 视图名;
1.2 视图的规则与限制
视图与基表之间存在紧密的关系,视图数据的修改会影响基表的数据,反之亦然。为了确保系统的稳定性,使用视图时需要特别注意以下限制:
- 数据更新限制:并非所有视图都支持数据更新操作。特别是当视图涉及多个表的连接、聚合函数、分组(GROUP BY)等操作时,修改视图中的数据可能会受到限制。例如,包含聚合函数或联合查询的视图通常不支持更新。
- 性能考虑:虽然视图可以简化查询,但如果查询的视图非常复杂且涉及大量数据,可能会导致性能问题。因此,在设计视图时应避免过于复杂的查询,特别是涉及大量数据的视图。
- 不支持索引:视图本身不支持索引,因此在使用视图时,查询性能可能不如直接查询基表。如果视图查询包含复杂的计算或连接操作,可能会对查询性能产生影响。
- 只读视图:一些视图被设计为只读的,无法修改其中的数据。这通常发生在视图涉及多表连接、聚合操作或复杂计算时。对于这种只读视图,修改视图中的数据将会失败。
1.3 视图与查找数据创建表的比较
视图和基于查询结果创建的表在以下方面有所不同:
-
视图 :
视图是动态的,它始终基于最新的查询结果。当视图中的数据发生变化时,实际的数据表也会发生变化。视图不存储数据本身,而是存储查询逻辑。当查询视图时,实际上是执行视图定义中的查询语句。
语法示例:
sqlCREATE VIEW t_name AS SELECT 查询数据;

- 创建表:
使用 CREATE TABLE
可以将查询结果保存为一个物理表。与视图不同,创建的表会将数据永久存储在数据库中,数据修改不会影响原始数据表。创建的表可以具有索引等性能优化。
语法示例:
sql
CREATE TABLE t_name AS SELECT 查询数据;

1.4 视图添加限制
在 MySQL 中,视图虽然提供了极大的便利,但在某些情况下需要对其进行适当的限制,以确保数据的一致性和完整性。以下是常见的视图限制及其应用:
视图的修改限制
-
当视图涉及多个表、聚合函数、分组等操作时,视图通常为只读,无法直接修改。只有在视图基于单一表且没有涉及复杂计算时,视图才通常支持数据更新操作。
-
若需要限制视图中数据的修改,可以使用
WITH CHECK OPTION
,该选项确保通过视图进行的更新操作符合视图中的条件,否则修改会被拒绝。例如,创建一个只允许修改
grade >= 60
的视图:sqlCREATE VIEW v_students AS SELECT sno, snme, grade FROM student WHERE grade >= 60 WITH CHECK OPTION;
视图查询限制
视图能够简化复杂的查询,但也需要根据实际需求进行适当限制。为了确保不暴露敏感数据,可以设计只包含非敏感字段或经过加密/脱敏处理的视图。
权限控制与安全性
权限设置示例:
vbnet
GRANT SELECT ON v_employee_view TO 'user1';
使用视图时,应当考虑权限控制,通过为不同用户分配不同的视图访问权限,可以确保数据安全。视图可以提供一个中介层,使得用户仅能访问特定数据,而不暴露整个表的数据。
对于敏感数据,视图的设计应遵循最小权限原则,避免直接暴露敏感信息。
2. 存储过程的基本语法
存储过程是一组 SQL 语句的集合,它被存储在数据库中,并可根据需要执行,可以接收输入参数并返回结果。

2.1 创建存储过程
存储过程的创建需要修改语句分隔符,以避免与 SQL 语句的结束符(;
)发生冲突:
sql
DELIMITER $$ -- 修改分隔符以避免与语句结束符冲突
CREATE PROCEDURE procedure_name (parameters)
BEGIN
-- SQL 语句
END$$
DELIMITER ; -- 恢复分隔符
存储过程的参数包括:
- IN:输入参数,用于向存储过程传递值。
- OUT:输出参数,用于存储过程返回数据。
- INOUT:输入输出参数,既可以接收输入数据,又可以返回结果。

不改变分隔符会出现报错:

2.2 调用存储过程
调用存储过程的语法如下:
scss
CALL procedure_name(parameters);
2.3 查看存储过程信息
-
查看所有数据库的存储过程:
sqlSHOW PROCEDURE STATUS;
-
查看当前数据库的存储过程:
iniSHOW PROCEDURE STATUS WHERE db = 'db_name';
Db
:存储过程所在的数据库Name
:存储过程的名称Type
:存储过程类型(例如PROCEDURE
)Definer
:存储过程的定义者Modified
:最后修改时间Created
:创建时间Security_type
:安全类型Comment
:存储过程的注释

2.4 查看存储过程定义
查看存储过程定义的语法:
sql
SHOW CREATE PROCEDURE procedure_name;
2.5 删除存储过程
删除存储过程的语法如下:
sql
DROP PROCEDURE procedure_name;

3. 变量
3.1 查看系统变量
3.1.1查看所有系统变量
查看当前会话的系统变量:
ini
SHOW SESSION VARIABLES;
查看全局系统变量:
sql
SHOW GLOBAL VARIABLES;
3.1.2系统变量的模糊匹配
sql
show session variables like '...';
show global variables like '...';

3.1.3查看指定变量
sql
select @@global.tname;----查看指定全局环境变量
select @@session.tname;----查看当前会话环境变量

3.2 设置全局变量与会话变量
Aspect | 全局隔离权限 | 会话隔离权限 |
---|---|---|
作用范围 | 系统范围,决定了系统的默认行为和限制 | 仅对当前会话有效,独立于全局权限 |
初始化与导入 | 在系统初始化时从全局设置导入 | 在新会话启动时从全局导入配置 |
修改的时效性 | 修改后不会立即影响现有会话,需重新启动会话才会生效 | 当前会话的隔离级别修改不会影响其他会话 |
对系统设计的影响 | 确保系统权限的统一性,易于集中管理 | 确保每个会话可以根据需要调整权限,而不影响其他会话 |
3.2.1全局变量设置
ini
SET GLOBAL transaction_isolation_level = 'READ COMMITTED';

重新启动一个新的会话:
3.2.2当前会话变量设置
arduino
set session transaction isolation level read committed;

重新启动一个会话:

3.3 用户定义变量
用户定义变量是会话级别的临时变量,用户可以在 SQL 语句中使用它们来存储数据或进行计算。变量名以 @
开头。例如:
-
使用
SET
语句定义变量:sqlSET @variable_name = value;-----方法一 SET @variable_name := value;----方法二
例如 ,定义一个名为
@age
的变量并赋值为 25:iniSET @age = 25;
-
也可以直接在查询语句中进行赋值:
scssSELECT @variable_name := expression;
例如,将查询结果赋值给变量:
sqlSELECT @age := age FROM users WHERE name = 'John';-----方法一 SELECT age into @age FROM users WHERE name = 'John';---方法二
3.4 局部变量
局部变量是在存储过程、函数或触发器内部定义的变量,作用范围仅限于该存储过程、函数或触发器的执行期间。它们通常用于临时存储数据、进行计算或传递信息。
3.4.1 局部变量的声明
在 MySQL 中,局部变量通过 DECLARE
语句在存储过程、函数或触发器中声明。局部变量的作用范围仅限于声明它们的存储过程、函数或触发器内部,并且不能在 SQL 查询的其他地方使用。
局部变量的特点:
- 局部性:局部变量仅在存储过程、函数或触发器的执行期间有效。当存储过程或函数执行完毕后,局部变量会被自动销毁。
- 无法在查询外部使用:局部变量只能在其所在的存储过程、函数或触发器内使用,不能在 SQL 查询的其他部分引用。
- 生命周期:当存储过程或函数执行结束时,局部变量的值会丢失。每次执行存储过程或函数时,局部变量会重新创建,并可以为其赋予初始值(如果指定了初始值)。
3.4.2 局部变量的使用
局部变量常用于存储中间计算结果、执行逻辑运算或在存储过程/函数中临时存储查询结果。它们的使用受到以下限制:
- 声明位置 :
DECLARE
语句必须在存储过程、函数或触发器的开头部分,也就是在BEGIN
语句之前声明。 - 命名规则 :局部变量不能使用以
@
开头的命名方式。@
是用于用户定义会话变量的前缀,局部变量不允许使用此命名规则。 - 初始值 :如果没有为局部变量指定初始值,则其默认值为
NULL
。因此,在使用局部变量时,开发者需要考虑NULL
的处理,确保程序的逻辑正确。
语法:
ini
DECLARE variable_name data_type [DEFAULT value];
variable_name
:变量的名称。data_type
:变量的数据类型(如INT
,VARCHAR
,DATE
等)。[DEFAULT value]
:可选,设置默认值。如果不指定,则默认值为NULL
。
例子:
sql
DECLARE @user_id INT DEFAULT 100;
DECLARE @user_name VARCHAR(255) DEFAULT 'John';