在MySQL数据库中,视图是作为一个虚表存在,是由一个SQL查询定义的,可以当作表使用。与持久表不同的是,视图中的数据没有实际的物理存储。
视图在数据库中,可以被作为一个抽象的装置,特别是对于一些应用程序,程序本身是不需要关注基础表的结构,只需要按照视图定义来取数据或更新数据。
视图虽然是基于基础表的虚拟表,但是用户可以对某些视图进行更新操作,其本质还是通过更新视图来更新基础表。
在创建视图时,如果添加with check option
,则当不满足修改条件时,修改视图会报错。
# 1.查询基础表
mysql> select * from zxy;
+------+------+------------+
| id | name | testtime |
+------+------+------------+
| 1 | zxy | 2023-03-10 |
| 2 | zxy | 2023-03-11 |
+------+------+------------+
2 rows in set (0.00 sec)# 2.创建视图,with check option;
mysql> create view v_zxy as select * from zxy with check option;
Query OK, 0 rows affected (0.00 sec)# 3.修改视图
mysql> update v_zxy set name='ZXY' where id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0# 4.检查视图修改结果
mysql> select * from v_zxy;
+------+------+------------+
| id | name | testtime |
+------+------+------------+
| 1 | ZXY | 2023-03-10 |
| 2 | zxy | 2023-03-11 |
+------+------+------------+
2 rows in set (0.00 sec)# 5.检查基础表修改结果
mysql> select * from zxy;
+------+------+------------+
| id | name | testtime |
+------+------+------------+
| 1 | ZXY | 2023-03-10 |
| 2 | zxy | 2023-03-11 |
+------+------+------------+
2 rows in set (0.00 sec)
如果想要查看基础表和视图的元数据信息,可以访问information_schema
下的TABLES
和VIEWS
表
TABLES
select *
from information_schema.TABLES
where table_type='BASE TABLE'
and table_schema=database()
and table_name='zxy'\G;mysql> select *-> from information_schema.TABLES-> where table_type='BASE TABLE'-> and table_schema=database()-> and table_name='zxy'\G;
*************************** 1. row ***************************TABLE_CATALOG: defTABLE_SCHEMA: zxyTABLE_NAME: zxyTABLE_TYPE: BASE TABLEENGINE: InnoDBVERSION: 10ROW_FORMAT: CompactTABLE_ROWS: 3AVG_ROW_LENGTH: 5461DATA_LENGTH: 16384
MAX_DATA_LENGTH: 0INDEX_LENGTH: 0DATA_FREE: 0AUTO_INCREMENT: NULLCREATE_TIME: 2023-02-26 15:21:16UPDATE_TIME: 2023-03-13 16:52:22CHECK_TIME: NULL
TABLE_COLLATION: latin1_swedish_ciCHECKSUM: NULLCREATE_OPTIONS: row_format=COMPACTTABLE_COMMENT:
1 row in set (0.00 sec)
VIEWS
select *
from information_schema.VIEWS
where table_schema=database()
and table_name='v_zxy'\G;mysql> select *-> from information_schema.VIEWS-> where table_schema=database()-> and table_name='v_zxy'\G;
*************************** 1. row ***************************TABLE_CATALOG: defTABLE_SCHEMA: zxyTABLE_NAME: v_zxyVIEW_DEFINITION: select `zxy`.`zxy`.`id` AS `id`,`zxy`.`zxy`.`name` AS `name`,`zxy`.`zxy`.`testtime` AS `testtime` from `zxy`.`zxy`CHECK_OPTION: CASCADEDIS_UPDATABLE: YESDEFINER: root@%SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
1 row in set (0.00 sec)
有些数据库支持物化视图,比如Oracle、postgres。物化视图不是虚表,而是基于基础表实际存在的实表。物化视图可以预先计算并保存多表连接的SQL结果。
在Oracle数据库中,物化视图的创建方式包括以下两种:
build immediate
默认的方式,在创建物化视图时就生成数据
build deferred
创建物化视图时不生成数据,以后根据需求再生成
物化视图的刷新的条件是,当基础表发生了DML操作后,物化视图何时采用何种方式进行同步更新,刷新的模式有两种:
on demand
用户需要的时候刷新
on commit
基础表DML提交的同时刷新
刷新的方法有四种:
fast
fast刷新采用增量刷新,只刷新自上次刷新后进行的修改
complete
对物化视图完全刷新
force
数据后在刷新时判断是否可以进行快速刷新,如果可以则采用fast,否则采用complete方式
never
物化视图永不刷新
MySQL只有虚表视图,如果想实现物化视图的功能。全量刷新的话,可以创建实表作为物化视图,通过写存储过程,定时刷新。增量刷新的话,需要利用触发器,记录基础表的更改操作,然后进行增量刷新。