MySQL視圖介紹,常見視圖操作:基於單表創建視圖,基於多表創建視圖;更新視圖結構與數據,刪除視圖。 ...
1、準備工作
在MySQL資料庫中創建兩張表balance(餘額表)和customer(客戶表)並插入數據。
create table customer(
id int(10) primary key,
name char(20) not null,
role char(20) not null,
phone char(20) not null,
sex char(10) not null,
address char(50) not null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
#外鍵為customerId
create table balance(
id int(10) primary key,
customerId int(10) not null,
balance DECIMAL(10,2),
foreign key(customerId) references customer(id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
向客戶表和餘額表中各插入3條數據。
insert into customer values(0001,"xiaoming",'vip1','12566666','male','江寧區888號');
insert into customer values(0002,"xiaohong",'vip10','15209336760','male','建鄴區888號');
insert into customer values(0003,"xiaocui",'vip11','15309336760','female','新街口888號');
insert into balance values(1,0001,900.55);
insert into balance values(2,0002,900.55);
insert into balance values(3,0003,10000);
2、視圖簡介
視圖可以簡單理解成虛擬表,它和資料庫中真實存在數據表不同,視圖中的數據是基於真實表查詢得到的。視圖和真實表一樣具備相似的結構。真實表的更新,查詢,刪除等操作,視圖也支持。那麼為什麼需要視圖呢?
a、提升真實表的安全性:視圖是虛擬的,可以只授予用戶視圖的許可權而不授予真實表的許可權,起到保護真實表的作用。
b、定製化展示數據:基於同樣的實際表,可以通過不同的視圖來向不同需求的用戶定製化展示數據。
c、簡化數據操作:適用於查詢語句比較複雜使用頻率較高的場景,可以通過視圖來實現。
......
需要說明一點的是:視圖相關的操作需要用戶具備相應的許可權。以下操作使用root用戶,預設用戶具備操作許可權。
創建視圖語法
create view <視圖名稱> as <select語句>;
修改視圖語法
修改視圖名稱可以先刪除,再用相同的語句創建。
#更新視圖結構
alter view <視圖名稱> as <select語句>;
#更新視圖數據相當於更新實際表,不適用基於多表創建的視圖
update ....
註意:部分視圖的數據是無法更新,也就是無法使用update,insert等語句更新,比如:
a、select語句包含多個表
b、視圖中包含having子句
c、試圖中包含distinct關鍵字
......
刪除視圖語法
drop view <視圖名稱>
3、視圖的操作
基於單表創建視圖
mysql> create view bal_view
-> as
-> select * from balance;
Query OK, 0 rows affected (0.22 sec)
創建完成後,查看bal_view的結構和記錄。可以發現通過視圖查詢到數據和通過真實表查詢得到的結果完全一樣。
#查詢bal_view的結構
mysql> desc bal_view;
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| id | int(10) | NO | | NULL | |
| customerId | int(10) | NO | | NULL | |
| balance | decimal(10,2) | YES | | NULL | |
+------------+---------------+------+-----+---------+-------+
3 rows in set (0.07 sec)
#查詢bal_view中的記錄
mysql> select * from bal_view;
+----+------------+----------+
| id | customerId | balance |
+----+------------+----------+
| 1 | 1 | 900.55 |
| 2 | 2 | 900.55 |
| 3 | 3 | 10000.00 |
+----+------------+----------+
3 rows in set (0.01 sec)
通過創建視圖的語句不難得出結論:當真實表中的數據發生改變時,視圖中的數據也會隨之改變。那麼當視圖中的數據發生改變時,真實表中的數據會變化嗎?來實驗一下,修改id=1的客戶balance為2000。
mysql> update bal_view set balance=2000 where id=1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
來看一下真實表balance中的數據。
mysql> select * from bal_view where id=1;
+----+------------+---------+
| id | customerId | balance |
+----+------------+---------+
| 1 | 1 | 2000.00 |
+----+------------+---------+
1 row in set (0.03 sec)
結論:視圖表中的數據發生變化時,真實表中的數據也會隨之改變。
基於多表創建視圖
創建視圖cus_bal,共兩個欄位客戶名稱和餘額。
mysql> create view cus_bal
-> (cname,bal)
-> as
-> select customer.name,balance.balance from customer ,balance
-> where customer.id=balance.customerId;
Query OK, 0 rows affected (0.05 sec)
#查看cus_bal中的數據
mysql> select * from cus_bal;
+----------+----------+
| cname | bal |
+----------+----------+
| xiaoming | 2000.00 |
| xiaohong | 900.55 |
| xiaocui | 10000.00 |
+----------+----------+
3 rows in set (0.28 sec)
修改視圖
將cus_bal視圖中的cname改成cusname。
mysql> alter view cus_bal
-> (cusname,bal)
-> as
-> select customer.name,balance.balance from customer ,balance
-> where customer.id=balance.customerId;
Query OK, 0 rows affected (0.06 sec)
#查看修改後視圖結構。
mysql> desc cus_bal;
+---------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------+------+-----+---------+-------+
| cusname | char(20) | NO | | NULL | |
| bal | decimal(10,2) | YES | | NULL | |
+---------+---------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
修改基於多表創建的視圖
mysql> insert into cus_bal(cusname,bal) values ("ee",11);
ERROR 1393 (HY000): Can not modify more than one base table through a join view 'rms.cus_bal'
刪除視圖
刪除視圖cus_bal
drop view cus_bal;
mysql> drop view cus_bal;
Query OK, 0 rows affected (0.00 sec)