1 視圖 視圖:View,是一種有結構(有行有列)但是沒結果(結構中不真實存放的數據)的虛擬表,虛擬表的結構來源不是自己定義,而是從對應的基表中產生(視圖的數據來源)。 示例腳本: 1.1 創建視圖 基本語法 創建單表視圖:基表只有一個 創建多表視圖:基表至少兩個 為什麼?我們知道兩張表都有id欄位 ...
1 視圖
- 視圖:View,是一種有結構(有行有列)但是沒結果(結構中不真實存放的數據)的虛擬表,虛擬表的結構來源不是自己定義,而是從對應的基表中產生(視圖的數據來源)。
- 示例腳本:
CREATE TABLE my_class( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵', c_name VARCHAR(20) NOT NULL COMMENT '班級名字', room VARCHAR(20) NOT NULL COMMENT '班級所在教室' ); -- 插入班級信息 INSERT INTO my_class VALUES (NULL,'java001班','A01'); INSERT INTO my_class VALUES (NULL,'Linux003班','C15'); INSERT INTO my_class VALUES (NULL,'c005班','B23'); -- 創建學生表 CREATE TABLE my_student( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵', NAME VARCHAR(20) NOT NULL COMMENT '學生姓名', age INT NOT NULL COMMENT '學生年齡', gender VARCHAR(2) NOT NULL COMMENT '學生性別', c_id INT COMMENT '外鍵' , height INT COMMENT '身高', CONSTRAINT fk_c_id FOREIGN KEY (c_id) REFERENCES my_class (id) ); -- 插入學生信息 INSERT INTO my_student VALUES (NULL,'張三',20,'男',1,180); INSERT INTO my_student VALUES (NULL,'李四',18,'女',2,170); INSERT INTO my_student VALUES (NULL,'王五',19,'女',2,165); INSERT INTO my_student VALUES (NULL,'趙六',25,'男',3,190); INSERT INTO my_student VALUES (NULL,'田七',14,'女',1,155); INSERT INTO my_student VALUES (NULL,'王八',19,'男',3,160); INSERT INTO my_student VALUES (NULL,'陳九',26,'男',NULL,195);
1.1 創建視圖
- 基本語法
create view 視圖名字 as select 語句; -- select 語句可以是普通查詢;可以是連接查詢;可以是聯合查詢;可以是子查詢
- 創建單表視圖:基表只有一個
CREATE VIEW v1 AS SELECT * FROM my_student;
CREATE VIEW v2 AS SELECT * FROM my_class;
- 創建多表視圖:基表至少兩個
CREATE VIEW v3 AS SELECT * FROM my_student AS s LEFT OUTER JOIN my_class AS c ON s.c_id = c.id ;
為什麼?我們知道兩張表都有id欄位,而我們又知道的是視圖是有結構但沒結果的虛擬表,既然它是虛擬表,怎麼可能一張表有兩個相同的欄位呢?
CREATE VIEW v3 AS SELECT s.*,c.c_name,c.room FROM my_student AS s LEFT OUTER JOIN my_class AS c ON s.c_id = c.id ;
1.2 查看視圖
- 查看視圖:查看視圖的結構
- 視圖是一張虛擬表,那麼表的所有查看方式都適用於表。
- show tables;
-
- DESC v1;
-
- SHOW CREATE TABLE v1;
-
- 視圖比表還是有一個關鍵字的區別:View。查看視圖的創建語句的時候可以使用View關鍵字。
- 視圖一旦創建:系統會在視圖對應的資料庫文件夾下創建一個對應的結構文件:frm文件。
1.3 使用視圖
- 使用視圖主要為了查詢,將視圖當做表即可。
- 示例:查看v1,v2,v3視圖
SELECT * FROM v1;
SELECT * FROM v2;
SELECT * FROM v3;
- 視圖的執行:其實本質就是執行封裝的select語句。
1.4 修改視圖
- 視圖本身不可修改,但是視圖的來源是可以修改的。
- 修改視圖就是修改視圖本身的來源語句(select語句)。
- 基本語法:
alter view 視圖名字 as 新的select語句;
ALTER VIEW v1 AS SELECT id,NAME,age,gender FROM my_student;
SELECT * FROM v1;
1.5 刪除視圖
- 基本語法
drop view 視圖名字;
CREATE VIEW v4 AS SELECT * FROM my_student; SHOW TABLES;
DROP VIEW v4; SHOW TABLES;
1.6 視圖的意義
- ① 視圖可以節省SQL語句:將一條複雜的查詢語句使用視圖進行保存,以後可以直接對視圖進行操作。
- ②數據安全:視圖操作是主要針對查詢的,如果對視圖結構進行處理(刪除),不會影響基表數據,相對安全。
- ③視圖往往是在大項目中使用,而且是多系統使用:可以對外提供有用的數據,但是隱藏關鍵(對外來說無用)的數據,這樣數據可以相對安全。
- ④視圖可以對外提供友好性:不同的視圖提供不同的數據,對外好像專門設計一樣。
- ⑤視圖可以更好(容易)的進行許可權控制。
1.7 視圖數據操作
- 視圖的確可以進行數據寫操作,但是是有限制的。
1.7.1 視圖的新增數據
- 數據的新增就是直接對視圖進行數據新增。
- 多表視圖不能新增數據
INSERT INTO v3 VALUES (NULL,'呵呵',50,'女',1,180,'java002班','C05');
- 可以向單表視圖插入數據:但是視圖中包含的欄位必須有基表中所有不能為空(或者沒預設值)的欄位。
-- 給學生增加學號 ALTER TABLE my_student ADD number VARCHAR(5) NOT NULL AFTER id ; -- 修改學號 UPDATE my_student SET number = '001' WHERE id =1; UPDATE my_student SET number = '002' WHERE id =2; UPDATE my_student SET number = '003' WHERE id =3; UPDATE my_student SET number = '004' WHERE id =4; UPDATE my_student SET number = '005' WHERE id =5; UPDATE my_student SET number = '006' WHERE id =6; UPDATE my_student SET number = '007' WHERE id =7;
-- 單表視圖插入:視圖不包含所有不允許為空欄位(學號) INSERT INTO v1 VALUES (NULL,'張三豐',120,'男');
- 視圖是可以插入數據的
SELECT * FROM v2;
SELECT * FROM my_class;
INSERT INTO v2 VALUES(NULL,'C++007班','D13');
SELECT * FROM v2;
SELECT * FROM my_class;
1.7.2 視圖的刪除數據
- 多表視圖不能刪除,原因:如果有一個視圖能查詢到學生和班級信息,那麼如果我想刪除一個學生的時候,卻將班級刪除了,於是,這個被刪除的班級下的所以學生都沒班級了,這就尷尬了。想象一下如下場景:學生轉班,當然是先在原來的班級中刪除此學生,然後在新的班級中增加此學生,而如果多表視圖可以刪除,豈不是學生不可以轉班了,否則一旦轉班,必須將自己原來的班級刪除,很可怕的哦。
SELECT * FROM v3;
DELETE FROM v3 WHERE id = 7;
- 單表視圖可以刪除
DELETE FROM v2 WHERE id = 4;
SELECT * FROM v2;
1.7.3 視圖的更新數據
- 理論上不但單表視圖還是多表視圖都可以更新數據
SELECT * FROM v3;
UPDATE v3 SET c_id = 1 WHERE id = 7;
SELECT * FROM v3;
- 更新限制:with check option,如果對視圖在新增的時候,限定了某個欄位有限制;那麼在對視圖進行數據更新的時候,系統會進行驗證:要保證更新之後,數據依然可以被視圖查詢出來,否則不讓更新。
-- 視圖:age欄位限制更新 CREATE VIEW v4 AS SELECT * FROM my_student WHERE age >20 WITH CHECK OPTION; -- 表示視圖的數據來源都是年齡大於20歲:where age > 20 -- -- with check option:決定通過視圖進行數據更新的時候,不能將已經得到的數據 age > 20 改成小於20 的
SELECT * FROM v4;
UPDATE v4 SET age = 18 WHERE id = 4;