本篇内容较少也较为简单,讲述关于视图以及权限管理相关内容,也是数据库中不可或缺的一大知识点。视图相关内容较少,主要是权限管理部分。
一、 什么是视图
视图是一个虚拟的表,它是基于一个或多个基本表或其他视图的查询结果集。视图本身不存储数据,而是通过执行查询来动态生成数据。用户可以像操作普通表一样使用视图进行查询、更新和管理。视图本身并不占用物理存储空间,它仅仅是一个查询的逻辑表示,物理上它依赖于基础表中的数据。
二、 创建视图
sql
# 语法
CREATE VIEW view_name [(column_list)] AS select_statement
三、使用视图
查询用户的所有信息和考试成绩
sql
# 使⽤真实表进⾏查询
select
s.id, s.name, s.sno, s.age, s.gender, s.enroll_date,
c.id, c.`name`,
co.id, co.`name`,
sc.id, sc.score
from student s, class c, course co, score sc
where s.class_id = c.id
and sc.student_id = s.id
and sc.course_id = co.id
order by s.id;
# 创建视图,在select中使⽤别名
create view v_student_socre as
select s.id, s.name, s.sno, s.age, s.gender, s.enroll_date,
c.id as class_id, c.`name` as class_name,
co.id as course_id, co.`name` as course_name, sc.id as score_id, sc.score
from student s, class c, course co, score sc
where s.class_id = c.id
and sc.student_id = s.id
and sc.course_id = co.id
order by s.id;
# 创建视图,指定结果集中的列名
create view v_student_socre_v1
(id, name, sno, age, gender, enroll_date,
class_id, class_name,
course_id, course_name,
score_id, score) as
select s.id, s.name, s.sno, s.age, s.gender, s.enroll_date, c.id, c.`name`,
co.id, co.`name`, sc.id, sc.score from student s, class c, course co, score sc
where s.class_id = c.id
and sc.student_id = s.id
and sc.course_id = co.id;
# 查询视图
select * from v_student_socre;
select * from v_student_socre_v1;
查询用户的姓名和总分,(隐藏学号和各科成绩)
sql
# 使⽤真实表进⾏查询
select s.name, sum(sc.score) total from student s, score sc
where s.id = sc.student_id
group by sc.student_id order by s.id;
# 如果使⽤真实表,在查询列表中随时可以加上学号字段
# 创建视图
create view v_student_total_points as
select s.id, s.name, sum(sc.score) total from student s, score sc
where s.id = sc.student_id
group by s.id order by s.id;
# 使⽤视图查询,只能查到学⽣姓名和总分,不能再添加查询字段
mysql> select * from v_student_total_points;
+-----------+-------+
| name | total |
+-----------+-------+
| 唐三藏 | 469 |
| 孙悟空 | 179.5 |
| 猪悟能 | 200 |
| 沙悟净 | 218 |
| 宋江 | 118 |
| 武松 | 178 |
| 李逹 | 172 |
+-----------+-------+
7 rows in set (0.00 sec)
视图和真实表进行表连接查询
sql
select * from v_student_total_points v, student s where v.id = s.id;
四、 修改数据
通过真实表修改数据,会影响视图
sql
# 修改唐三藏的JAVA成绩为99分
mysql> update score set score = 99 where student_id = 1 and course_id = 1;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2 Changed: 2 Warnings: 0
# 查询视图,发现唐三藏这条记录已被修改
mysql> select * from v_student_socre;
通过视图修改数据会影响基表
sql
# 修改唐三藏的计算机⽹络成绩为99分
mysql> update v_student_socre set score = 99 where score_id = 3;
ERROR 1221 (HY000): Incorrect usage of UPDATE and ORDER BY
# 发现更新失败,因为创建视图时使⽤了order by 语句
# 更新视图
mysql> update v_student_socre_v1 set score = 99 where score_id = 3;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
# 是看真实表数据已被修改
select * from score where student_id = 1 and course_id = 5;
4.1注意事项
修改真实表会影响视图,修改视图同样也会影响真实表
以下视图不可更新:
- 创建视图时使用聚合函数的视图0
- 创建视图时使用DISTINCTO
- 创建视图时使用GROUP BY以及 HAVING子句0
- 创建视图时使用 UNION 或UNION ALL0
- 查询列表中使用子查询
- 在FROM子句中引用不可更新视图
五、 删除视图
sql
# 语法
drop view view_name;
六、 视图的优点
- **简单性:**视图可以将复杂的查询封装成一个简单的查询。例如,针对一个复杂的多表连接查询,可以创建一个视图,用户只需查询视图而无需了解底层的复杂逻辑。
- **安全性:**通过视图,可以隐藏表中的敏感数据。例如,一个系统的用户表中,可以创建一个不包含密码列视图,普通用户只能访问这个视图,而不能访问原始表。
- **逻辑数据独立性:**视图提供了一种逻辑数据独立性,即使底层表结构发生变化,只需修改视图定义,而无需修改依赖视图的应用程序。使用到应用程序与数据库的解耦。
- **重命名列:**视图允许用户重命名列名,以增强数据可读性。
七、用户
7.1查看用户
MySQL的用户信息保存在mysql系统数据库的user表中,可以通过Select语句查看,如下所示:
sql
# 选择数据库
mysql> use mysql
Database changed
# 查看所有的表
mysql> show tables;
# 查看表结构
mysql> desc user;
#查询user表中的记录
mysql> select host, user, authentication_string from user;
+-----------+------------------+-----------------------------------------------
-------------------------+
| host | user | authentication_string
|
+-----------+------------------+-----------------------------------------------
-------------------------+ |
| localhost | mysql.infoschema |
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session |
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys |
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root | $A$005$4"/zI3
,S2!905H8kQgTq2Boe6PFBOp6cbLIqLX0TasCS58WzBBdXrC |
+-----------+------------------+-----------------------------------------------
-------------------------+
4 rows in set (0.00 sec)
- **host:**允许登录的主机,相当于白名单,如果是localhost,表示只能从本机登陆
- **user:**用户名
- ***_priv:**用户拥有的权限
- **authentication_string:**加密后的用户密码
7.2创建用户
7.2.1语法
sql
CREATE USER [IF NOT EXISTS] 'user_name'@'host_name' IDENTIFIED BY'auth_string';
- **user_name:**用户名,用单引号包裹,区分大小写
- **host_name:**主机或IP(段),用单引号包裹
- **auth_string:**真实密码,有些密码策略不允许使用简单密码
7.2.2注意事项
- 如果不指定host_name相当于'user_name'@'%',%表示所有主机都可以连接到数据库,强烈建议不要这样设置,因为会导致严重的安全问题
- user_name和host_name分别用单引号包裹,如果写成'user_name@host_name',相当于'user_name@host_name'@'%'
- host_name可以通过子网掩码设置主机范围
198.0.0.0/255.0.0.0:A段网络中的任意一台主机
198.51.0.0/255.255.0.0:198.51 B段网络中的任意一台主
198.51.100.0/255.255.255.0:198.51.100 C段网络中的任意一台主机
198.51.100.1:只包含特定IP地址的主机
- 从MySQL8.0.23开始,指定为IPv4地址的主机值可以使用CIDR表示法写入,例如198.51.100.44/24
- 允许在IP地址中使用%通配符,比如,主机值'%'匹配任何主机名,198.51.100.%匹配198.51.100 C段网络中的任何主机。MySQL8.0.35中已弃用,以后可能会删除
7.2.3示例
sql
# 添加⼀个名为bit的新用户,允许从本机登录
mysql> create user 'bit'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.02 sec)
# 添加⼀个名为bit1的新用户,允许从192.168.1.1/24⽹段登录
mysql> create user 'bit1'@'192.168.1.1/24' identified by '123456';
Query OK, 0 rows affected (0.02 sec)
# 查询,添加成功
mysql> select host, user, authentication_string from user\G
*************************** 1. row ***************************
host: 192.168.1.36/24
user: bit1
LYkbuBpcAPQ1f2JJSc8Je4u.5ce6UPmQ01U2pHmfzKQ7-:%
*************************** 2. row ***************************
host: localhost
user: bit
authentication_string:
$A$005$P+EPe6Ht`5S%KxoXIjzgBT5EuT2nYzallHaP6fOaSw2B2he7EaFnFzB
*************************** 3. row ***************************
host: localhost
user: mysql.infoschema
authentication_string:
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 4. row ***************************
host: localhost
user: mysql.session
authentication_string:
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 5. row ***************************
host: localhost
user: mysql.sys
authentication_string:
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED
*************************** 6. row ***************************
host: localhost
user: root
authentication_string:
$A$005$4"/zI3S2!905H8kQgTq2Boe6PFBOp6cbLIqLX0TasCS58WzBBdXrC
6 rows in set (0.00 sec)
sql
# 使⽤新用户登录
C:\Users\bit>mysql -ubit -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.39 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
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.
7.3 修改密码
7.3.1语法
sql
# 为指定用户设置密码 【推荐】
ALTER USER 'user_name'@'host_name' IDENTIFIED BY 'auth_string';
# 为指定用户设置密码
SET PASSWORD FOR 'user_name'@'host_name' = 'auth_string';
# 为当前登录用户设置密码
SET PASSWORD = 'auth_string';
7.3.2 示例
sql
# 以root身份登录,为'bit'@'localhost'用户重置密码
mysql> ALTER USER 'bit'@'localhost' IDENTIFIED BY '987654';
Query OK, 0 rows affected (0.02 sec)
# 以root身份登录,为'bit'@'localhost'用户重置密码
mysql> SET PASSWORD FOR 'bit'@'localhost' = '123456';
Query OK, 0 rows affected (0.01 sec)
# 以bit用户登录,并确认当前登录用户,USER()与CURRENT_USER()是同义词
mysql> select USER();
+---------------+
| USER() |
+---------------+
| bit@localhost |
+---------------+
1 row in set (0.00 sec)
# 修改当前登录用户的密码
mysql> SET PASSWORD = '111111';
Query OK, 0 rows affected (0.02 sec)
7.4 删除用户
7.4.1语法
sql
DROP USER [IF EXISTS] 'user_name'@'host_name'[, ...];
7.4.2 示例
sql
# 删除用户'bit1'@'192.168.1.1/24'
mysql> drop user 'bit1'@'192.168.1.1/24';
Query OK, 0 rows affected (0.01 sec)
# 删除成功
mysql> select host, user, authentication_string from user;
+-----------+------------------+-----------------------------------------------
-------------------------+
| host | user | authentication_string
|
+-----------+------------------+-----------------------------------------------
-------------------------+
| localhost | bit |
$A$005$P+EPe6Ht`5S%KxoXIjzgBT5EuT2nYzallHaP6fOaSw2B2he7EaFnFzB |
| localhost | mysql.infoschema |
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session |
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys |
$A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root | $A$005$4"/zI3
,S2!905H8kQgTq2Boe6PFBOp6cbLIqLX0TasCS58WzBBdXrC |
+-----------+------------------+-----------------------------------------------
-------------------------+
5 rows in set (0.00 sec)
八、 权限与授权
8.1 给用户授权
刚创建的用户没有任何权限,需要给他授权,如下所示:
sql
mysql> select user();
+---------------+
| user() |
+---------------+
| bit@localhost |
+---------------+
1 row in set (0.00 sec)
# 看不到其他的数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)
8.1.1 语法
sql
grant priv_type[, priv_type ...] on priv_level
to 'user_name'@'host_name' [WITH GRANT OPTION]
- **priv_type:**根据类型,参考根据列表4.1中的Privilege列
- priv_level:*|**|db_name.* |db_name.tbl_name|tbl_name,比*.表示所有数据库下的所有表
- 'user_name'@'host_name': 指定用户
- **[WITHGRANTOPTION]:**可选,允许用户将自己的权限授权给其它用户
8.1.2示例
为bit@localhost用户授权于java01数据库的select权限
sql
# 授权
mysql> grant select on java01.* to 'bit'@'localhost';
Query OK, 0 rows affected (0.04 sec)
# 查看数据库,可以看到java01
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| java01 |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)
# 选择数据库
mysql> use java01
Database changed
# 查看所有表
mysql> show tables;
+------------------------+
| Tables_in_java01 |
+------------------------+
| account |
| class |
| course |
| emp |
| exam |
| for_delete |
| score |
| student |
| student1 |
| t_check |
| t_recored |
| t_recored_old |
| t_truncate |
| users |
| v_student_socre |
| v_student_socre_v1 |
| v_student_total_points |
+------------------------+
17 rows in set (0.00 sec)
# 查询数据
mysql> select * from student;
+----+----------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+----------+--------+------+--------+-------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
+----+----------+--------+------+--------+-------------+----------+
8 rows in set (0.02 sec)
# 写⼊⼀条数据时失败,因为没有授权写⼊权限
mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
ERROR 1142 (42000): INSERT command denied to user 'bit'@'localhost' for table
'student'
查看bit@localhost用户权限,USAGE表示在指定的priv_level上没有权限
sql
mysql> show grants for 'bit'@'localhost';
+-------------------------------------------------+
| Grants for bit@localhost |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `bit`@`localhost` |
| GRANT SELECT ON `java01`.* TO `bit`@`localhost` |
+-------------------------------------------------+
2 rows in set (0.00 sec)
为bit@localhost用户授权于java01数据库的所有权限
sql
# ALL为所有权限
mysql> grant ALL on java01.* to 'bit'@'localhost';
Query OK, 0 rows affected (0.01 sec)
# 查看用户权限
mysql> show grants for 'bit'@'localhost';
+---------------------------------------------------------+
| Grants for bit@localhost |
+---------------------------------------------------------+
| GRANT USAGE ON *.* TO `bit`@`localhost` |
| GRANT ALL PRIVILEGES ON `java01`.* TO `bit`@`localhost` |
+---------------------------------------------------------+
2 rows in set (0.00 sec)
# 插⼊⼀条新记录
mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
ERROR 1142 (42000): INSERT command denied to user 'bit'@'localhost' for table'student'
# 不成功说明权限没有⽣效,需要刷新权限,如果还不成功可以重新登录
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
# 重新执⾏插⼊操作
mysql> insert into student values (null, 'test', '500001', 18, 1, '2000-06-08', 1);
Query OK, 1 row affected (0.02 sec)
# 查看记录
mysql> select * from student;
+----+----------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+----------+--------+------+--------+-------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
| 12 | test | 500001 | 18 | 1 | 2000-06-08 | 1 | # 新记录写⼊成功
+----+----------+--------+------+--------+-------------+----------+
9 rows in set (0.00 sec)
# 删除操作
mysql> delete from student where id = 12;
Query OK, 1 row affected (0.01 sec)
# 删除成功
mysql> select * from student;
+----+----------+--------+------+--------+-------------+----------+
| id | name | sno | age | gender | enroll_date | class_id |
+----+----------+--------+------+--------+-------------+----------+
| 1 | 唐三藏 | 100001 | 18 | 1 | 1986-09-01 | 1 |
| 2 | 孙悟空 | 100002 | 18 | 1 | 1986-09-01 | 1 |
| 3 | 猪悟能 | 100003 | 18 | 1 | 1986-09-01 | 1 |
| 4 | 沙悟净 | 100004 | 18 | 1 | 1986-09-01 | 1 |
| 5 | 宋江 | 200001 | 18 | 1 | 2000-09-01 | 2 |
| 6 | 武松 | 200002 | 18 | 1 | 2000-09-01 | 2 |
| 7 | 李逹 | 200003 | 18 | 1 | 2000-09-01 | 2 |
| 8 | 不想毕业 | 200004 | 18 | 1 | 2000-09-01 | 2 |
+----+----------+--------+------+--------+-------------+----------+
8 rows in set (0.00 sec)
8.2回收权限
8.2.1 语法
sql
REVOKE [IF EXISTS] priv_type[, priv_type] ... ON priv_level
FROM 'user_name'@'host_name' [, 'user_name'@'host_name']...
8.2.2示例
回收bit@localhost用户对于java01数据库的权限
sql
mysql> REVOKE all on *.* from 'bit'@'localhost';
Query OK, 0 rows affected (0.01 sec)
# 刷新权限
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
# 查看权限,没有任何授权
mysql> show grants for 'bit'@'localhost';
+-----------------------------------------+
| Grants for bit@localhost |
+-----------------------------------------+
| GRANT USAGE ON *.* TO `bit`@`localhost` |
+-----------------------------------------+
1 row in set (0.00 sec)
# 查看所有数据库,没有可以访问的库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)
这篇主要说明了视图以及权限相关内容,下一篇就是我们的重头戏了JDBC。。。