c mysql 视图_mysql 视图
六、mysql 視圖
6.1、什么是視圖
① 定義
視圖是指計(jì)算機(jī)數(shù)據(jù)庫(kù)中的視圖,是一個(gè)虛擬表,其內(nèi)容由查詢定義。同真實(shí)的表一樣,視圖包含一系列帶有名稱的列和行數(shù)據(jù)。但是,視圖并不在數(shù)據(jù)庫(kù)中以存儲(chǔ)的數(shù)據(jù)值集形式存在。行和列數(shù)據(jù)來(lái)自由定義視圖的查詢所引用的表,并且在引用視圖時(shí)動(dòng)態(tài)生成。
② 為什么需要視圖
關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)是由一張一張的二維關(guān)系表所組成,簡(jiǎn)單的單表查詢只需要遍歷一個(gè)表,而復(fù)雜的多表查詢需要將多個(gè)表連接起來(lái)進(jìn)行查詢?nèi)蝿?wù)。對(duì)于復(fù)雜的查詢事件,每次查詢都需要編寫MySQL代碼效率低下。為了解決這個(gè)問(wèn)題,數(shù)據(jù)庫(kù)提供了視圖(view)功能。
③ 通俗易懂的解釋
朕想要了解皇宮的國(guó)庫(kù)的相關(guān)情況,想知道酒窖有什么酒,剩多少,窖藏多少年,于是派最信任的高公公去清點(diǎn),高公公去國(guó)庫(kù)清點(diǎn)后報(bào)給了朕;朕又想知道藏書情況,于是又派高公公去清點(diǎn)并回來(lái)報(bào)告給朕,又想知道金銀珠寶如何,又派高公公清點(diǎn)。。。過(guò)一段時(shí)間又想知道藏書情況,高公公還得重新再去清點(diǎn),皇上問(wèn)一次,高公公就得跑一次路。
后來(lái)皇上覺(jué)得高公公不容易,就成立了國(guó)庫(kù)管理部門,小鄧子負(fù)責(zé)酒窖,小卓子負(fù)責(zé)藏書,而小六子負(fù)責(zé)金庫(kù)的清點(diǎn)。。。后來(lái)皇上每次想了解國(guó)庫(kù)就直接問(wèn)話負(fù)責(zé)人,負(fù)責(zé)人就按照職責(zé)要求進(jìn)行匯報(bào)。
安排專人管理后,每次皇上想要了解國(guó)庫(kù)情況,就不必讓高公公每次都跑一趟,而是指定的人員按照指定的任務(wù)完成指定的匯報(bào)工作就可以了。
和數(shù)據(jù)庫(kù)相對(duì)應(yīng),每次進(jìn)行查詢工作,都需要編寫查詢代碼進(jìn)行查詢;而視圖的作用就是不必每次都重新編寫查詢的SQL代碼,而是通過(guò)視圖直接查詢即可。因此:視圖是虛擬表,本身不存儲(chǔ)數(shù)據(jù),而是按照指定的方式進(jìn)行查詢。
6.2、例子
① 創(chuàng)建數(shù)據(jù)//創(chuàng)建部門表
create?table?department(
id?int?primary?key?auto_increment,
name?char(30)?not?null
);
//創(chuàng)建員工表
create?table?employee(
id?int?primary?key?auto_increment,
department_id?int?not?null,
name?char(30)?not?null
);
//插入數(shù)據(jù)
insert?into?department(name)?values("人事部"),("研發(fā)部");
insert?into?employee(department_id,name)?values(1,"小明"),(2,"大明");
② 創(chuàng)建視圖
在創(chuàng)建視圖前應(yīng)先看看是否有權(quán)限:mysql>?SELECT?SELECT_priv,create_view_priv?from?mysql.user?WHERE?user="root";
+-------------+------------------+
|?SELECT_priv?|?create_view_priv?|
+-------------+------------------+
|?Y???????????|?Y????????????????|
|?Y???????????|?Y????????????????|
|?Y???????????|?Y????????????????|
+-------------+------------------+
Y表示有創(chuàng)建的權(quán)限。
單表上創(chuàng)建視圖:create?view?v_view1(id,name)?as?select?id,name?from?employee;
查看視圖:mysql>?select?*?from?v_view1;
+----+------+
|?id?|?name?|
+----+------+
|??1?|?小明?|
|??2?|?大明?|
+----+------+
多表上創(chuàng)建視圖:create?view?v_view2(id,name,department)?as?select?a.id,a.name,b.name?from?employee?a,department?b?where?a.department_id=b.id;
查看視圖:mysql>?select?*?from?v_view2;
+----+------+------------+
|?id?|?name?|?department?|
+----+------+------------+
|??1?|?小明?|?人事部?????|
|??2?|?大明?|?研發(fā)部?????|
+----+------+------------+
③ 更新視圖update?v_view1?set?name="小紅"?where?name="小明";
查看更新后的兩個(gè)視圖:mysql>?select?*?from?v_view1;
+----+------+
|?id?|?name?|
+----+------+
|??1?|?小紅?|
|??2?|?大明?|
+----+------+
mysql>?select?*?from?v_view2;
+----+------+------------+
|?id?|?name?|?department?|
+----+------+------------+
|??1?|?小紅?|?人事部?????|
|??2?|?大明?|?研發(fā)部?????|
+----+------+------------+
查看更新后的數(shù)據(jù)表:mysql>?select?*?from?employee;
+----+---------------+------+
|?id?|?department_id?|?name?|
+----+---------------+------+
|??1?|?????????????1?|?小紅?|
|??2?|?????????????2?|?大明?|
+----+---------------+------+
小結(jié):更新視圖,則對(duì)應(yīng)的真實(shí)表上的數(shù)據(jù)也發(fā)生改變
更新視圖,相關(guān)視圖的數(shù)據(jù)也發(fā)生改變
視圖中雖然可以更新數(shù)據(jù),但是有很多的限制。一般情況下,最好將視圖作為查詢數(shù)據(jù)的虛擬表,而不要通過(guò)視圖更新數(shù)據(jù)。因?yàn)?#xff0c;使用視圖更新數(shù)據(jù)時(shí),如果沒(méi)有全面考慮在視圖中更新數(shù)據(jù)的限制,就可能會(huì)造成數(shù)據(jù)更新失敗。
④、不可更新的視圖
某些視圖是可更新的。也就是說(shuō),可以在諸如UPDATE、DELETE或INSERT等語(yǔ)句中使用它們,以更新基表的內(nèi)容。對(duì)于可更新的視圖,在視圖中的行和基表中的行之間必須具有一對(duì)一的關(guān)系。
還有一些特定的其他結(jié)構(gòu),這類結(jié)構(gòu)會(huì)使得視圖不可更新。更具體地講,如果視圖包含下述結(jié)構(gòu)中的任何一種,那么它就是不可更新的:
聚合函數(shù)(SUM(), MIN(), MAX(), COUNT()等)、DISTINCT、GROUP BY、HAVING、UNION或UNION ALL、位于選擇列表中的子查詢、Join、FROM子句中的不可更新視圖、WHERE子句中的子查詢,引用FROM子句中的表、僅引用文字值(在該情況下,沒(méi)有要更新的基本表)、ALGORITHM = TEMPTABLE(使用臨時(shí)表總會(huì)使視圖成為不可更新的)
⑤、WITH[CASCADED|LOCAL] CHECK OPTION
創(chuàng)建或者修改視圖的時(shí)候加入?yún)?shù) with check option 決定視圖是否能更新:LOCAL參數(shù)表示更新視圖時(shí)只要滿足該視圖本身定義的條件即可。
CASCADED參數(shù)表示更新視圖時(shí)需要滿足所有相關(guān)視圖和表的條件。沒(méi)有指明時(shí),該參數(shù)為默認(rèn)值。
比如:create?view?v_view3(id,?name,?department_id)?as?select?id,?name,?department_id?from?employee?where?department_id=1?with?local?check?option;mysql>?select?*?from?v_view3;
+----+------+---------------+
|?id?|?name?|?department_id?|
+----+------+---------------+
|??1?|?小紅?|?????????????1?|
+----+------+---------------+
插入數(shù)據(jù):insert?into?v_view3(name,department_id)?values("小綠",1);
查看視圖:mysql>?select?*?from?v_view3;
+----+------+---------------+
|?id?|?name?|?department_id?|
+----+------+---------------+
|??1?|?小紅?|?????????????1?|
|??3?|?小藍(lán)?|?????????????1?|
|??4?|?小綠?|?????????????1?|
+----+------+---------------+
插入數(shù)據(jù):mysql>?insert?into?v_view3(name,department_id)?values("大綠",2);
ERROR?1369?(HY000):?CHECK?OPTION?failed?"test.v_view3"
結(jié)果顯示插入失敗。因?yàn)橐晥D v_view3 中 where department_id=1,當(dāng)你插入 department_id=2的時(shí)候就無(wú)法插入。
⑥、刪除視圖DROP?VIEW?IF?EXISTS?視圖名
6.3、視圖存在的意義
①、為何存在
視圖是存儲(chǔ)在數(shù)據(jù)庫(kù)中的查詢的SQL 語(yǔ)句,它主要出于兩種原因:安全原因, 視圖可以隱藏一些數(shù)據(jù),如:社會(huì)保險(xiǎn)基金表,可以用視圖只顯示姓名,地址,而不顯示社會(huì)保險(xiǎn)號(hào)和工資數(shù)等。
另一原因是可使復(fù)雜的查詢易于理解和使用。這個(gè)視圖就像一個(gè)“窗口”,從中只能看到你想看的數(shù)據(jù)列。
②、視圖的好處
A 視圖能簡(jiǎn)化用戶操作
視圖機(jī)制使用戶可以將注意力集中在所關(guān)心地?cái)?shù)據(jù)上。如果這些數(shù)據(jù)不是直接來(lái)自基本表,則可以通過(guò)定義視圖,使數(shù)據(jù)庫(kù)看起來(lái)結(jié)構(gòu)簡(jiǎn)單、清晰,并且可以簡(jiǎn)化用戶的的數(shù)據(jù)查詢操作。例如,那些定義了若干張表連接的視圖,就將表與表之間的連接操作對(duì)用戶隱藏起來(lái)了。換句話說(shuō),用戶所作的只是對(duì)一個(gè)虛表的簡(jiǎn)單查詢,而這個(gè)虛表是怎樣得來(lái)的,用戶無(wú)需了解。
B 視圖使用戶能以多種角度看待同一數(shù)據(jù)
視圖機(jī)制能使不同的用戶以不同的方式看待同一數(shù)據(jù),當(dāng)許多不同種類的用戶共享同一個(gè)數(shù)據(jù)庫(kù)時(shí),這種靈活性是非常必要的。
C ?視圖對(duì)重構(gòu)數(shù)據(jù)庫(kù)提供了一定程度的邏輯獨(dú)立性
數(shù)據(jù)的物理獨(dú)立性是指用戶的應(yīng)用程序不依賴于數(shù)據(jù)庫(kù)的物理結(jié)構(gòu)。數(shù)據(jù)的邏輯獨(dú)立性是指當(dāng)數(shù)據(jù)庫(kù)重構(gòu)造時(shí),如增加新的關(guān)系或?qū)υ械年P(guān)系增加新的字段,用戶的應(yīng)用程序不會(huì)受影響。層次數(shù)據(jù)庫(kù)和網(wǎng)狀數(shù)據(jù)庫(kù)一般能較好地支持?jǐn)?shù)據(jù)的物理獨(dú)立性,而對(duì)于邏輯獨(dú)立性則不能完全的支持。
在關(guān)系數(shù)據(jù)庫(kù)中,數(shù)據(jù)庫(kù)的重構(gòu)造往往是不可避免的。重構(gòu)數(shù)據(jù)庫(kù)最常見(jiàn)的是將一個(gè)基本表“垂直”地分成多個(gè)基本表。例如:將學(xué)生關(guān)系student(no,name,sex,age,dept),
分為x(no,name,age)和y(no,sex,dept)兩個(gè)關(guān)系。這時(shí)原表student為x表和y表自然連接的結(jié)果。如果建立一個(gè)視圖student:create?view?v_student(no,name,sex,age,dept)as?select?x.no,x.xname,y.sex,x.age,y.dept?from?x,y?WHERE?x.no=y.Sno;
這樣盡管數(shù)據(jù)庫(kù)的邏輯結(jié)構(gòu)改變了(變?yōu)閤和y兩個(gè)表了),但應(yīng)用程序不必修改,因?yàn)樾陆⒌囊晥D定義為用戶原來(lái)的關(guān)系,使用戶的外模式保持不變,用戶的應(yīng)用程序通過(guò)視圖仍然能夠查找數(shù)據(jù)。
當(dāng)然,視圖只能在一定程度上提供數(shù)據(jù)的邏輯獨(dú)立,比如由于視圖的更新是有條件的,因此應(yīng)用程序中修改數(shù)據(jù)的語(yǔ)句可能仍會(huì)因?yàn)榛颈順?gòu)造的改變而改變。
D 視圖能夠?qū)C(jī)密數(shù)據(jù)提供安全保護(hù)
有了視圖機(jī)制,就可以在設(shè)計(jì)數(shù)據(jù)庫(kù)應(yīng)用系統(tǒng)時(shí),對(duì)不同的用戶定義不同的視圖,使機(jī)密數(shù)據(jù)不出現(xiàn)在不應(yīng)該看到這些數(shù)據(jù)的用戶視圖上。這樣視圖機(jī)制就自動(dòng)提供了對(duì)機(jī)密數(shù)據(jù)的安全保護(hù)功能。例如,student表涉及全校15個(gè)院系學(xué)生數(shù)據(jù),可以在其上定義15個(gè)視圖,每個(gè)視圖只包含一個(gè)院系的學(xué)生數(shù)據(jù),并只允許每個(gè)院系的主任查詢和修改本原系學(xué)生視圖。
E 適當(dāng)?shù)睦靡晥D可以更清晰地表達(dá)查詢
例如經(jīng)常需要執(zhí)行這樣的查詢“對(duì)每個(gè)學(xué)生找出他獲得最高成績(jī)的課程號(hào)”。可以先定義一個(gè)視圖,求出每個(gè)同學(xué)獲得的最高成績(jī):CREATE?VIEW?VMGRADE?AS?SELECT?Sno,MAX(Grade)?Mgrade?FROM?SC?GROUP?BY?Sno;
然后用如下的查詢語(yǔ)句完成查詢:SELECT?SC.Sno,Cno?FROM?SC,VMGRADE?WHERE?SC.Sno?=?VMGRADE.Sno?AND?SC.Grade?=?VMGRADE.Mgrade;
③、總結(jié)
A 視圖是從一個(gè)或多個(gè)表或視圖中導(dǎo)出的表,其結(jié)構(gòu)和數(shù)據(jù)是建立在對(duì)表的查詢基礎(chǔ)上的
B 視圖不是真實(shí)存在的基礎(chǔ)表而是一張?zhí)摫?#xff0c;視圖所對(duì)應(yīng)的數(shù)據(jù)并不實(shí)際地以視圖結(jié)構(gòu)存儲(chǔ)在數(shù)據(jù)庫(kù)中,而是存儲(chǔ)在視圖所引用的表中。
總結(jié)
以上是生活随笔為你收集整理的c mysql 视图_mysql 视图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 社交新零售有什么优势?主要模式是什么?
- 下一篇: springboot+mysql “友书