MySQL資料庫之檢視
1 引言
為了簡化複雜SQL語句編寫,以及提高資料庫安全性,MySQL資料庫檢視特性。檢視是一張虛擬表,不在資料庫中以儲存的資料值形式存在。在開發中,開發者往往只對某些特定資料和所負責的特定任務感興趣,只需要看到這一部分資料即可。這時候就可以用到檢視來完成。
2 檢視簡介
2.1 什麼是檢視
資料庫中的檢視是一個虛擬表,但它同真實表一樣,包含一系列帶有名稱的行和列資料。行和列資料來自由定義檢視查詢所引用的表,並且在應用檢視時動態生成。另外,檢視還可以在已經存在的檢視的基礎上定義。
檢視一經定義變儲存在資料庫中,與其相對應的資料並沒有像表那樣在資料庫中再儲存一份,通過檢視看到的資料只是儲存在基本表中的資料。對檢視的操作與對標的操作一樣,可以對其進行查詢、修改和刪除。當對通過檢視看到的資料進行修改時,相應的基本表中的資料也會發生變化;同時,若是基本表的資料發生變化,則這種變化也會自動地反映在檢視上。
2.2 檢視的作用
與直接從真實資料表中進行資料操作相比,檢視具有以下的有點:
(1)簡單化
看到的就是需要的。檢視不僅可以簡化使用者對資料的理解,也可以簡化他們的操作。那些被經常使用的查詢可以被定義為檢視,從而使用者不必為以後的每一次操作指定全部的條件。
(2)安全性
通過檢視使用者只能查詢和修改他們所能看到的資料。資料庫中的其他資料則既看不見也娶不到。資料庫授權命令可以使每個使用者對資料庫的檢索限制到特定的資料庫物件上,但不能限制到特定行和特定列上。但通過檢視,使用者可以被限制到資料庫的行列級別的子集上。
(3)邏輯資料獨立性
檢視可以幫助使用者遮蔽真實表結構變化帶來的影響。
3 建立檢視
檢視包含了SELECT查詢結果,因此屬兔的建立基於SELECT語句和已存在的資料庫,檢視可以建立在一張表上,也可以建立在多張表上。
本篇博文中,所有操作基於以下兩張資料表(emp表、dept表)進行:
emp表:
emp表sql語句如下:
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for emp -- ---------------------------- DROP TABLE IF EXISTS `emp`; CREATE TABLE `emp`( `empno` int(4) NOT NULL, `ename` varchar(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL, `job` varchar(9) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL, `mgr` int(4) NULL DEFAULT NULL, `hiredate` date NULL DEFAULT NULL, `sal` float(7, 2) NULL DEFAULT NULL, `comm` float(7, 2) NULL DEFAULT NULL, `deptno` int(2) NULL DEFAULT NULL, PRIMARY KEY (`empno`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of emp -- ---------------------------- INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1998-12-17', 800.00, NULL, 20); INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600.00, 300.00, 30); INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250.00, 500.00, 30); INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975.00, NULL, 20); INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250.00, 1400.00, 30); INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850.00, NULL, 30); INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450.00, NULL, 10); INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1981-11-17', 3000.00, NULL, 20); INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000.00, NULL, 10); INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500.00, 0.00, 30); INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100.00, NULL, 20); INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950.00, NULL, 30); INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000.00, NULL, 20); INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-02-23', 1300.00, NULL, 10); INSERT INTO `emp` VALUES (8888, 'CHB', 'CLERK', 7369, '2018-12-10', 8000.00, 100.00, NULL); SET FOREIGN_KEY_CHECKS = 1; emp表SQL語句
dept表:
dept表SQL語句如下:
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for dept -- ---------------------------- DROP TABLE IF EXISTS `dept`; CREATE TABLE `dept`( `deptno` int(2) NOT NULL, `dname` varchar(14) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL, `loc` varchar(13) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL, PRIMARY KEY (`deptno`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of dept -- ---------------------------- INSERT INTO `dept` VALUES (10, 'ACCOUNTING', 'NEW YORK'); INSERT INTO `dept` VALUES (20, 'RESEARCH', 'DALLAS'); INSERT INTO `dept` VALUES (30, 'SALES', 'CHICAGO'); INSERT INTO `dept` VALUES (40, 'OPERATIONS', 'BOSTON'); SET FOREIGN_KEY_CHECKS = 1; demp表SQL語句
3.1 建立檢視的基本格式
建立檢視的基本格式如下:
CREATE VIEW <檢視名稱> [(column_list)] AS SELECT語句;
雖然還有更加完整的詳細語法格式,但一般情況下,使用上述基本格式就夠用了。
(1)基於單個數據表建立檢視
在使用emp表時,如果需要查詢查詢empno(編號)、ename(姓名)、job(職位)、hiredate(僱用日期)、sal(月薪)等欄位,並指定中文拼音別名,SQL語句如下:
select empno bianhao , ename xinmin, job zhiwei, hiredate guyongriqi, sal yuexin from emp;
如果需要頻繁得進行該語句查詢,那麼每次都要重寫這一行語句。使用檢視可以簡化操作,對empno、ename、job、hiredate、sal建立檢視:
create view view_01 as select empno , ename , job , hiredate , sal from emp;
執行完上述語句即可建立名為view_01的檢視,如果你是通過Navicat等圖形介面工具建立檢視,在左側檢視欄下可找到view_01檢視。
在剛建立好的view_01檢視進行查詢:
select * from view_01 ;
查詢結果如下:
可以發現,我們並未指定查詢的欄位,但查詢效果卻與直接在真實資料表上指定欄位查詢效果一樣。但view_01檢視並未實現欄位別名,繼續建立一個view_02為每個列新增別名:
create view view_02 (bianhao , xinmin , zhiwei , guyongriqi , yuexin) as select empno , ename , job , hiredate , sal from emp;
檢視view_02:
select * from view_02 ;
結果如下:
可以看到,每一個列的列名都是我們在建立檢視時自己重新指定的。
(2)建立基於多個表上檢視
建立一個檢視,檢視中包含每個員工編號(empno)、姓名(ename)、職位(job)、領導編號(mgr)、領導姓名(empno)、部門名稱(dname)、部門位置(loc),在真實資料表中查詢語句如下:
select e1.empno bianhao, e1.ename xingming, e1.job zhiwei, e1.mgr lindaobianhao, e2.ename lindaoxingming, d.dname bumenmingchen, d.loc bumenweizhi from emp e1 , emp e2 , dept d where e1.mgr=e2.empno and e1.deptno=d.deptno ;
建立檢視:
create view view_03 as select e1.empno bianhao, e1.ename xingming, e1.job zhiwei, e1.mgr lindaobianhao, e2.ename lindaoxingming, d.dname bumenmingchen, d.loc bumenweizhi from emp e1 , emp e2 , dept d where e1.mgr=e2.empno and e1.deptno=d.deptno ;
對剛建立的view_03檢視進行查詢:
select * from view_03 ;
查詢結果如下:
可以發現,在select中指定別名與在view檢視中指定別名效果是一樣的。
4 檢視檢視
(1)檢視檢視基本資訊:describe 檢視名;
檢視上一章節建立的檢視view_03的基本資訊:
describe view_03 ;
describe一般情況下都寫成desc,兩者是完全等效的。
另外還可以通過“show create view 檢視名;”來檢視檢視詳細資訊。
(2)檢視所有檢視
在MySQL中,information_schema資料庫下的views表中儲存了所有檢視的定義,通過對views表的查詢,可以檢視資料庫中說喲檢視的詳細資訊,查詢語句如下:
select * FROM information_schema.views ;
部分查詢結果如下所示:
5 修改檢視
(1)使用create or replace view語句修改檢視
create or replace view語句從字面上也可以理解:既可以建立檢視,也可以修改檢視(存在的話就修改,不存在就建立)。create or replace view語句的語法結構與建立檢視的create語句語法結構是完全一樣的。
修改上文中建立的檢視view_01,新增一個部門編號欄位(deptno):
create or replace view view_02 (bianhao , xinmin , zhiwei , guyongriqi , yuexin , bumenbiaohao) as select empno , ename , job , hiredate , sal , deptno from emp;
再次查詢view_02,發現確實多了部門編號這一列:
select * from view_02 ;
(2)使用alter語句修改檢視
alter語句是MySQL提供的另一種修改檢視的方法,其語法結果與create or replace語句也是基本一樣的。
繼續修改檢視view_02,新增一個獎金欄位(comm):
alter view view_02 (bianhao , xinmin , zhiwei , guyongriqi , yuexin , bumenbiaohao , jiangjin) as select empno , ename , job , hiredate , sal , deptno , comm from emp;
檢視view_01檢視:
alter語句與create orreplace語句的區別是當檢視不存在是,alter語句會報錯。
6 更新檢視
更新檢視是指通過檢視來插入、更新、刪除表中的資料,因為檢視是一個虛擬表,其中是沒有資料的。通過檢視更新的時候都是轉到真實表上進行的。對檢視的更新操作也包括update、insert和delete。
(1)update
通過檢視將員工編號為7369的員工月薪改為1000,在更新前,其資料為:
select * from view_02 where bianhao=7369;
用update語句進行更新
update view_02 set yuexin=1000 where bianhao=7369;
再次通過檢視檢視資料,發現數據確實已更新:
再看看真實表中資料有沒有更新:
select * from emp where empno=7369;
可以看出,真實表中的資料也一起更新了,說明對檢視的更新操作本質上是對真實表的更新。
(2)insert
先建立一個檢視view_04,該檢視結果與emp表一樣:
create view view_04 as select * from emp ;
使用insert語句向view_04檢視中插入一條資料:
insert into view_04 values(8002 , 'MARK' , 'CLERK' ,7902 , '1998-12-12' , 1100 ,20 ,500 ) ;
檢視真實emp表中是否新增這麼一條資料:
select * from emp where empno =8002;
證明在檢視進行insert操作是可以新增資料到真實表的。但一般來說,檢視的表結構與檢視的表結構可能不一樣,若真實表中存在非空等約束,這通過檢視的insert操作就回失敗。所以,insert操作一般不會通過檢視來進行。
(3)delete
通過檢視刪除剛建立的empno為8002的記錄:
delete from view_04 where empno =8002;
檢視真實表中資料是否刪除:
select * from emp where empno =8002;
返回的是一個空表,證明真實表中的這條記錄也已經被刪除了。
最後總結一下檢視的更新操作,當檢視中包含如下內容時,檢視的更新操作將不能被執行:
(1)檢視中不包含真實表中被定義為非空的列(檢視中沒有,但真實表中為非空約束)。
(2)在定義檢視的select語句後的欄位列表中使用了數學表示式。
(3)在定義檢視的select語句後的欄位列表中使用了聚合函式。
(4)在定義檢視的select語句中使用了distinct,union,top, group by,或having子句。
7 總結
本文是對MySQL資料中檢視的詳細總結,包括了對檢視概念、特性的介紹,然後通過實際示例展示了對檢視的增刪改查操作。