天天看點

mysql資料庫總結筆記

一、安裝和配置資料庫:

下載下傳mysql位址:https://dev.mysql.com/downloads/mysql/
windows下載下傳的版本是installer msi版本:https://dev.mysql.com/downloads/windows/installer/5.7.html
環境變量的配置:
	書上80頁。
	路徑:C:\Program Files\mysql\MySQL Server 5.7\bin
	環境變量配置位址:電腦——》屬性——》系統屬性——》進階——》環境變量——》Path

啟動指令行:windows鍵+R鍵,輸入CMD
啟動資料庫:net start mysql57
關閉資料庫:net stop mysql57
           

二、連接配接資料庫的方式:

1、連接配接本地資料庫:

mysql -h localhost -u root -p    回車後輸入密碼
           

如果是連接配接遠端的資料庫的話,将localhost 換為資料庫伺服器的ip位址。

2、navicat連接配接資料庫:

左上角的連接配接——》選擇Mysql——》輸入連接配接名(任意)——》輸入資料庫的密碼——》測試連接配接——》儲存——》輕按兩下連接配接名。

三、關于資料庫的操作

檢視目前所有的資料庫:show databases;
	mysql、information_schema、perfermance_schema、sys這四個是系統自帶的資料庫,不用動它。
建立資料庫:create database 資料庫名; 
		  e.g create database mydb;
打開資料庫:use 資料庫名;
		  e.g use mydb;
删除資料庫:drop database 資料庫名;
		  e.g drop database mydb;
檢視單個資料庫資訊: show create database 資料庫名;
		e.g show create database mydb;
檢視系統支援的存儲引擎類型:
		SHOW ENGINES;		
           

四、關于表的操作

1、建立表

限制條件與資料類型的寬度一樣,都是可選參數。

作用:用于保證資料的完整性和一緻性。

PRIMARY KEY (PK)    辨別該字段為該表的主鍵,可以唯一的辨別記錄
	FOREIGN KEY (FK)    辨別該字段為該表的外鍵
	NOT NULL    辨別該字段不能為空
	UNIQUE KEY (UK)    辨別該字段的值是唯一的
	AUTO_INCREMENT    辨別該字段的值自動增長(整數類型,而且為主鍵)
	DEFAULT    為該字段設定預設值
	UNSIGNED 無符号
	ZEROFILL 使用0填充
           
create table 表名 (
	字段1 資料類型(長度) 完整性限制, 
	字段2 資料類型(長度) 完整性限制
);
e.g create table t1 (
	id int(4) NOT NULL,
	name varchar(14) default 'allen'
);
           

2、檢視表

1)檢視表結構

describe 表名;   ||   desc 表名;
e.g desc t1;
           

2)檢視表詳細結構

show create table 表名\G;
	\G:幫助整理結果的格式
	e.g show create table course\G;
           

3)檢視所有的表

show tables;
           

3、修改表結構

1)修改表名

-- 文法:ALTER TABLE 表名 RENAME 新表名;
ALTER TABLE sc RENAME score;
           

2)增加字段

-- 文法:ALTER TABLE 表名 ADD 新字段名 資料類型 [完整性限制條件];

-- 增加一個字段
ALTER TABLE student ADD motor varchar(30) DEFAULT 'cb300r';

-- 增加多個字段
ALTER TABLE teacher ADD motor varchar(30) DEFAULT 'cb500r',
                    ADD car varchar(30) DEFAULT 'BMW7';
 
-- 增加字段到第一項
ALTER TABLE score ADD semester varchar(30) DEFAULT '2021' FIRST;

-- 增加新字段到指定字段之後
ALTER TABLE student ADD salary int DEFAULT 1000 AFTER ssex;
           

3)删除字段

-- 删除字段:ALTER TABLE 表名 DROP 字段名;
ALTER TABLE student DROP salary;
           

4)修改字段類型和名稱

-- 修改字段類型
-- 文法:ALTER TABLE 表名 MODIFY  字段名 資料類型 [完整性限制條件…];
ALTER TABLE student MODIFY salary MEDIUMINT DEFAULT 3000;


-- 修改字段名稱
-- 文法: ALTER TABLE 表名 CHANGE 舊字段名 新字段名 舊資料類型 [完整性限制條件…]; 
ALTER TABLE student CHANGE salary living_cost MEDIUMINT DEFAULT 3000;


-- 修改字段類型和名稱
-- 文法:ALTER TABLE 表名 CHANGE 舊字段名 新字段名 新資料類型 [完整性限制條件…];
ALTER TABLE student CHANGE living_cost capital INT NOT NULL DEFAULT 300000;
           

4、删除表

-- 文法:DROP TABLE 表名;
DROP TABLE ts;
           

五、表記錄相關操作

1、添加表記錄

insert into 表名(列名) values (常量清單);
-- 單條資料 
insert into student(sno, sname) values
('2005010104', '張三');
-- 多條資料 
insert into student(sno, sname) values 
('2001010101', '李四'),
('2002020202', '王五');
-- 不使用可選列名: 
insert into t1 values
(1,'egon','male',18), 
(2,'alex','female',81);
           

2、删除表記錄

-- 文法:DELETE FROM 表名 WHERE 條件;
DELETE FROM student
WHERE sno='2005030301';
           

3、修改表記錄

-- 文法:UPDATE 表名 SET 關系式 (WHERE 條件);
-- 改單個記錄
UPDATE student SET ssex='女'
WHERE sname='張麗';

-- 改多個記錄
UPDATE sc SET degree=0
WHERE sno IN (
	SELECT sno
	FROM student
	WHERE sdept='計算機工程系'
);

-- 改單個記錄多項
UPDATE student SET ssex='女', capital=300000
WHERE sname='張立';
           

六、關于表的查詢的操作:

select 要查詢的字段:1、*,2、name,sex,age

DISTINCT 去重

SELECT DISTINCT sno FROM sc;

from 要查詢的表名

where 要查詢結果的篩選條件

  • 1、比較運算符:=、>、<、>=、<=、 兩個不等于符号:<>、!= (不大于!>和不小于!< 在mysql中執行失敗)

    ```

    SELECT sname, ssex, YEAR(CURRENT_DATE)-YEAR(sbirthday) as age

    FROM student

    WHERE YEAR(CURRENT_DATE)-YEAR(sbirthday) > 33;

    SELECT sname, ssex, YEAR(CURRENT_DATE)-YEAR(sbirthday) as age
      FROM student
      WHERE YEAR(CURRENT_DATE)-YEAR(sbirthday) != 33;
      ```
               
  • 2、範圍運算符 between and 、not between and

    WHERE YEAR(CURRENT_DATE)-YEAR(sbirthday) BETWEEN 30 AND 33;

    SELECT sname, ssex, YEAR(CURRENT_DATE)-YEAR(sbirthday) as age
      FROM student
      WHERE YEAR(CURRENT_DATE)-YEAR(sbirthday) NOT BETWEEN 30 AND 33;
      ```
               
  • 3、清單運算符 in、 not in

    SELECT sname, ssex, YEAR(CURRENT_DATE)-YEAR(sbirthday) as age FROM student WHERE YEAR(CURRENT_DATE)-YEAR(sbirthday) IN (30,32,33);

  • 4、字元比對符 LIKE、NOT LIKE

    SELECT * FROM student WHERE sdept LIKE '%程%';

  • 5、空值判斷 IS NULL、IS NOT NULL

    SELECT * FROM student WHERE sdept IS NULL;

  • 6、邏輯運算符 AND、OR、NOT

    SELECT *

    WHERE ssex='女' AND sdept LIKE '%數學%';

    SELECT * 
      FROM student
      WHERE ssex='女' OR ssex='男';
      ```
               

group by 指定查詢結果的分組條件

SELECT * FROM student WHERE ssex='女' OR ssex='男' GROUP BY sdept;

having 分組或集合的查詢條件 (在group by後執行)

SELECT * FROM student WHERE ssex='女' OR ssex='男' GROUP BY sdept HAVING ssex='女';

ORDER BY 指定查詢結果排序 DESC:逆向排序

LIMIT 指定結果輸出範圍

WHERE ssex='女'

ORDER BY sbirthday DESC

LIMIT 1;

SELECT * 
	FROM student
	WHERE ssex='女'
	ORDER BY sbirthday
	LIMIT 1;
	```
           

1、通配符:

1、%:任意多個字元
		1)以什麼開頭的模糊查詢
		SELECT * 
		FROM student
		WHERE sdept LIKE '信%';
		
		2)以什麼結尾的模糊查詢
		SELECT * 
		FROM student
		WHERE saddress LIKE '%州';
		
		3)包含有什麼字段的模闆查詢
		SELECT * 
		FROM student
		WHERE sdept LIKE '%程%';

	2、_:單個字元
		SELECT * 
		FROM student
		WHERE sname LIKE '王_';
		
		SELECT * 
		FROM student
		WHERE sname LIKE '王%';
           

2、正規表達式:

1、^以什麼開頭
		SELECT * 
		FROM student
		WHERE sname REGEXP '^王';

	2、$以什麼結尾
		SELECT * 
		FROM student
		WHERE speciality REGEXP '務$';

	3、.比對任意單字元(不支援中文,僅支援數字和字母字元串)
		SELECT * 
		FROM student
		WHERE sno REGEXP '2.050301';

	4、*比對任意個前面的字元串(不生效)
		SELECT * 
		FROM student
		WHERE sno REGEXP '2*50301';
		
		SELECT * 
		FROM student
		WHERE sno REGEXP '2*5*';

	5、+比對前面的字元1次或多次
		SELECT *
		FROM student
		WHERE sbirthday REGEXP '198+-0';
		
		SELECT *
		FROM student
		WHERE sno REGEXP '20+303';

	6、比對指定字元串文本
		SELECT * 
		FROM student
		WHERE sdept REGEXP '機工';

	7、[]比對字元串集合中任意一個字元(中文無法過濾,僅支援數字和字母字元串)
		SELECT * 
		FROM sc
		WHERE cno REGEXP '[13]';

	8、[^]比對不在括号内的任何字元(沒有發生作用)

	9、字元串{n}比對前面的字元串至少n次(不支援中文,僅支援數字和字母字元串)
		SELECT *
		FROM student
		WHERE sno REGEXP '21{3}';

	10、字元串{m,n}比對前面的字元串至少m次,至多n次
		SELECT *
		FROM student
		WHERE sno REGEXP '21{4,7}';

		SELECT *
		FROM student
		WHERE sno REGEXP '21{5,7}';
           

七、多表連接配接查詢

注意:當對多個表進行查詢時,要在 SELECT 語句後面指定字段是來源于哪一張表。

是以,在多表查詢時,SELECT 語句後面的寫法是表名.列名。

另外,如果表名非常長的話,也可以給表設定别名,這樣就可以直接在 SELECT 語句後面寫上表的别名.列名。

1、交叉連接配接

交叉連接配接(CROSS JOIN)一般用來傳回連接配接表的笛卡爾積。
兩個表的笛卡爾積,傳回結果數量就是兩個表的資料行相乘。
           

(1)文法格式:

方法一:
SELECT <字段名> 
FROM <表1> CROSS JOIN <表2>;
方法二:
SELECT <字段名> 
FROM <表1>, <表2>;
           

(2)示例:

SELECT * FROM student CROSS JOIN sc;
SELECT * FROM student, sc;
           

2、内連接配接

内連接配接(INNER JOIN)主要通過設定連接配接條件的方式,來移除查詢結果中某些資料行的交叉連接配接。

即取兩張表共同部分,相當于上面利用條件從笛卡爾積結果中篩選出正确結果。

- INNER JOIN 關鍵字連接配接兩張表

- ON 子句來設定連接配接條件

(1)文法格式:

方法一:
SELECT <字段名> 
FROM <表1> INNER JOIN <表2> 
ON  <連接配接條件表達式>;
方法二:
SELECT <字段名> 
FROM <表1>, <表2> 
where  <連接配接條件>;
           

(2)示例:

SELECT * FROM student INNER JOIN sc ON student.sno=sc.sno;
SELECT * FROM student, sc WHERE student.sno=sc.sno;
           

(3)多表連接配接查詢

多個表内連接配接時,在 FROM 後連續使用 INNER JOIN 或 JOIN 即可。

SELECT * FROM student INNER JOIN sc ON student.sno=sc.sno
					  INNER JOIN course ON sc.cno=course.cno;
           

3、自連接配接

一張表内可以進行自身連接配接操作——同一個表的不同行連接配接起來。

- 必須為表指定兩個别名(邏輯上成兩個表)

SELECT <字段名> 
FROM <表1> [别名1], <表1> [别名2] 
WHERE  <連接配接條件表達式>;
           

-- 查詢同時選修C01和C04課程的學生學号
SELECT A.sno
FROM sc A, sc B
WHERE A.sno=B.sno AND A.cno='C01' AND B.cno='C04';

-- 查詢與 王智剛 同在一個系的學生的學号、姓名、系
SELECT stu2.sno, stu2.sname, stu2.sdept
FROM student stu1, student stu2
WHERE stu1.sdept=stu2.sdept AND stu1.sname='王智剛' AND stu2.sname!='王智剛';
           

4、外連接配接

外連接配接分為三種:左外連接配接,右外連接配接,全外連接配接。對應SQL:LEFT/RIGHT/FULL OUTER JOIN。

通常省略 outer 這個關鍵字。寫成:

LEFT JOIN:保留左邊表中的非比對記錄。

RIGHT JOIN:保留右邊表中的非比對記錄。

FULL JOIN:保留兩邊表的所有行。

SELECT <字段名> 
FROM <表1> LEFT/RIGHT/FULL JOIN <表2>
ON  <連接配接條件表達式>;
           

select * from student LEFT JOIN sc ON student.sno=sc.sno;
select * from sc RIGHT JOIN course ON course.cno=sc.cno;
           

(3)資料庫不支援FULL JOIN

mysql不支援FULL JOIN,方法是使用 UNION ALL 模拟全連接配接。

SELECT * FROM sc
LEFT JOIN course ON course.cno=sc.cno
UNION ALL
SELECT * FROM sc
RIGHT JOIN student ON student.sno=sc.sno;
           

八、嵌套查詢(子查詢)

查詢塊:一個SELECT-FROM-WHERE語句稱為一個查詢塊。

嵌套查詢(子查詢):将一個查詢塊嵌套在另一個查詢塊的WHERE子句或HAVING子句的條件中。簡單來說,一個查詢語句嵌套在另一個查詢語句内部的查詢。

子查詢中的SELECT語句用一對括号“( )”定界,查詢結果必須确定。

SELECT語句中不能使用ORDER BY子句,ORDER BY子句永遠隻能對最終查詢結果排序。

求解方法:由裡向外處理的,即每個子查詢在其上一級查詢處理之前求解,子查詢的結果用于建立其父查詢的查找條件。

  • 常用關鍵字:IN 、NOT IN 、ANY 、ALL、EXISTS 和 NOT EXISTS 等。
  • 比較運算符:>, >=, <, <=, != 等
  • 子查詢一般分為兩種:嵌套子查詢和相關子查詢。

1、嵌套子查詢

嵌套子查詢(不相關子查詢):嵌套子查詢的執行不依賴于外部嵌套。

  • 執行順序:先執行子查詢,子查詢的結果集傳給外部查詢作為條件使用,再執行外部查詢,顯示查詢結果。
  • 子查詢可以多層嵌套。

(1)子查詢傳回單個值

子查詢傳回的單個值,被外部查詢的比較操作使用。

-- 平均年齡
SELECT AVG(YEAR(CURDATE()) - YEAR(sbirthday))
FROM student;
-- 結果:25

-- 查詢所有年齡大于25的學生姓名
SELECT *
FROM student
WHERE YEAR(CURDATE()) - YEAR(sbirthday) > 25;

-- 查詢所有年齡大于平均年齡的學生姓名
SELECT *
FROM student
WHERE YEAR(CURDATE()) - YEAR(sbirthday) > (SELECT AVG(YEAR(CURDATE()) - YEAR(sbirthday)) FROM student);
           

(2)子查詢傳回一個值清單(用IN操作符實作查詢)

IN表示屬于,判斷外部查詢某個屬性是否在子查詢結果中。

-- 找出‘C01’這門課有成績的學生
SELECT sname
FROM student 
WHERE  sno IN(
SELECT sno FROM sc WHERE cno='C01');
           

(3)子查詢傳回一個值清單(用ANY或ALL操作符實作查詢)

  • ANY和SOME關鍵字是同義詞。
  • ANY和ALL操作符都必須與比較運算符一起使用。
  • 常用的比較運算符:>,<,>=,<=,=,!=,<>
# 查詢其他系中比數學系某一學生年齡大的學生姓名和年齡  ANY
select YEAR(CURDATE()) - YEAR(sbirthday)
FROM student
where sdept='數學系';

select sname, YEAR(CURDATE()) - YEAR(sbirthday) as age
from student
where YEAR(CURDATE()) - YEAR(sbirthday) > ANY(
	select YEAR(CURDATE()) - YEAR(sbirthday)
	FROM student
	where sdept='數學系'
) AND sdept!='數學系';

# 查詢其他系中比數學系全部學生年齡大的學生姓名和年齡 
select sname, YEAR(CURDATE()) - YEAR(sbirthday) as age
from student
where YEAR(CURDATE()) - YEAR(sbirthday) > ALL(
	select YEAR(CURDATE()) - YEAR(sbirthday)
	FROM student
	where sdept='數學系'
) AND sdept!='數學系';
           

2、相關子查詢

相關子查詢:子查詢的執行依賴于外部查詢,即子查詢的查詢條件依賴于外部查詢的某個屬性值。

執行過程:

  • 1)子查詢為外部查詢的每一個元組(行)執行一次,外部查詢将子查詢引用列的值傳給子查詢。
  • 2)如果子查詢的任何行與其比對,外部查詢則取此行放入結果表。
  • 3)再回到 1),直到處理完外部表的每一行。

經常要用到 EXISTS 操作符,代表存在量詞。

-- 查詢所有選修C01課程的學生姓名
select sname from student
where EXISTS (
	select * from sc 
	where sno=student.sno AND cno='C01'
);

-- 查詢選修了全部課程的學生姓名。
SELECT sname  FROM student
WHERE NOT EXISTS
    (SELECT * FROM course
      WHERE NOT EXISTS
          (SELECT * FROM sc
            WHERE sno=student.sno AND cno=course.cno));
           

九、集合查詢

SELECT的查詢結果是元組的集合,是以可以對SELECT的結果進行集合操作。

但是MySQL語言隻支援UNION(并操作)運算,對于INTERSECT(交操作)和EXCEPT(差操作)沒有實作。

-- 查詢計算機工程系的學生及年齡不大于19歲的學生。
select *  from student
where sdept='計算機工程系'
UNION
select *  from student
where year(curdate())-year(sbirthday)<=19;
           

十、索引

索引是一種有效組合資料的方式。通過索引,可以快速快速查詢到資料庫表對象中的特定記錄,是一種提供性能的常用方式。

1、關于索引

使用索引可以提高從表中檢索資料的速度,索引由表中的一個字段和多個字段生成的鍵組成。

索引按存儲類型可分為:B型樹索引(BTREE)和哈希索引。

MySQL支援6種索引,分别為普通索引、唯一索引、全文索引、單列索引、多列索引、空間索引。

過多的索引會占據大量的磁盤空間。

以下情況适合建立索引:

  • 經常被查詢的字段,即在WHERE子句中經常出現的字段
  • 在分組的字段,即在GROUP BY子句中出現的字段
  • 存在依賴關系的子表和父表之間的聯合查詢,即主鍵或外鍵字段
  • 設定唯一完整性限制的字段

2、建立表時建立普通索引

普通索引:在建立索引時,不附加任何限制條件(唯一,非空等限制),該類型的索引可以建立在任何資料類型的字段上。

文法形式:
create table 表名(
  屬性名 資料類型,
  ……
  index|key [索引名](屬性名1 [長度] [ASC|DESC])
)

示例:
create table t_dept(
deptno int,
dname varchar(20),
location varchar(40),
index index_deptno(deptno)
);
           

3、在已經存在的表上建立普通索引

文法形式:
create index 索引名 on 表名 (屬性名 [長度] [ASC|DESC]);
示例:
create index index_dname on t_dept(dname); 
           

4、通過SQL中語句alter table建立普通索引

文法形式:
alter table 表名 add index|key 索引名(屬性名 [長度]  [ASC|DESC]);
示例:
ALTER table t_dept add index index_deptno(deptno);
           

5、建立表時建立唯一索引

唯一索引:在建立索引時,限制索引的值必須是唯一的。

在MySQL中,根據索引的建立方式,分為手動索引和自動索引兩種。

  • 自動索引,是指在資料庫表裡設定完整性限制時,該表會被系統自動建立索引。
  • 手動索引,是指手動在表上建立索引。當設定表的某個字段為主鍵或唯一完整性限制時,系統就會自動建立關聯該字段的唯一索引。
文法形式:
create table 表名(
  屬性名 資料類型,
  ……
  unique index|key [索引名](屬性名1 [長度] [ASC|DESC])
);
示例:
create table t_dept1(
deptno int,
dname varchar(20),
location varchar(40),
unique index index_deptno(deptno)
);
           

6、在已經存在的表上建立唯一索引

文法形式:
create unique index 索引名 on 表名 (屬性名 [長度] [ASC|DESC]);
示例:
create unique index index_dname on t_dept1(dname);
           

7、通過alter table 建立唯一索引

文法形式:
alter table table_name add unique index|key 索引名(屬性名 [長度] [ASC|DESC]);
示例:
alter table t_dept1 add unique index index_deptno on t_dept1(deptno);
           

8、删除索引

删除索引即删除表中已存在的索引。之是以要删除索引,是由于這些索引會降低更新速度,影響資料庫的性能。

文法形式:
drop index 索引名 on 表名;
示例:
drop index index_deptno on t_dept;
drop index index_dname on t_dept;
           

9、索引改名

對于MySQL 5.7及以上版本,可以執行以下指令:

-- 文法:
ALTER TABLE tbl_name RENAME INDEX old_index_name TO new_index_name;
-- 示例:
ALTER TABLE workinfo RENAME INDEX index_t TO index_taddress;
           

對于MySQL 5.7以前的版本,可以執行下面兩個指令:

-- 文法:
ALTER TABLE tbl_name DROP INDEX old_index_name;
ALTER TABLE tbl_name ADD INDEX new_index_name(column_name);
-- 示例:
drop index index_t on workinfo;
create index index_taddress on workinfo(type,address); 
           

十一、視圖

視圖是一種資料庫對象,是從一個或多個基表(或視圖)導出的虛表。可以被看成是虛拟表或存儲查詢。

  • 視圖的結構和資料是對資料表進行查詢的結果。
  • 建立視圖通過定義 SELECT 語句檢索将在視圖中顯示的資料。
  • 視圖的基表是SELECT 語句引用的資料表稱。
  • 視圖被定義後便存儲在資料庫中,通過視圖看到的資料隻是存放在基表中的資料。

資料修改:當對通過視圖看到的資料進行修改時,相應的基表的資料也會發生變化;同時,若基表的資料發生變化,這種變化也會自動地反映到視圖中。

視圖産生:視圖可以是一個資料表的一部分,也可以是多個基表的聯合;視圖也可以由一個或多個其他視圖産生。(視圖可以從表的資料查詢産生,也可以從其他視圖查詢資料産生)

1、視圖常用操作:

(1)篩選表中的行。

(2)防止未經許可的使用者通路敏感資料。

(3)将多個實體資料表抽象為一個邏輯資料表。

注意:視圖上的操作和基表類似,但是 DBMS對視圖的更新操作(INSERT、DELETE、UPDATE)往往存在一定的限制。

2、視圖優點

(1)視圖能夠簡化使用者的操作。

(2)視圖使使用者能從多種角度看待同一資料。

(3)視圖對重構資料庫提供一定程式的邏輯獨立性。

(4)視圖能夠對機密資料提供安全保護。

3、建立視圖

文法:

CREATE [OR REPLACE]	[ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}] 
VIEW 視圖名[(字段名清單)]
AS
 select語句 
[ WITH [CASCADED|LOCAL] CHECK OPTION ]  

說明:
	(1)OR REPLACE:表示當已具有同名的視圖時,将覆寫原視圖。
	(2)ALGORITHM子句:可選項,表示視圖選擇的算法。ALGORITHM可取三個值:MERGE、TEMPTABLE或UNDEFINED。
		如果沒有ALGORITHM子句,預設算法是UNDEFINED(未定義的)。算法會影響MySQL處理視圖的方式。
		MERGE:會将引用視圖的語句的文本與視圖定義合并起來,使得視圖定義的某一部分取代語句的對應部分。
		TEMPTABLE:視圖的結果将被置于臨時表中,然後使用它執行語句。
		UNDEFINED:由MySQL選擇所要使用的算法。如果可能,它傾向于MERGE而不是TEMPTABLE,這是因為MERGE通常更有效,而且如果使用了臨時表,視圖是不可更新的。
	(3)WITH CHECK OPTION:對于可更新視圖,給定WITH CHECK OPTION子句用來防止插入或更新行,除非作用在行上的select_statement中的WHERE子句為“真”。
		 在可更新視圖中加入WITH CHECK OPTION子句,當視圖是根據另一個視圖定義時,LOCAL和CASCADED關鍵字決定了檢查測試的範圍。 
		 LOCAL關鍵字對CHECK OPTION進行了限制,使其僅作用在定義的視圖上,
		 CASCADED會對該視圖相關的所有視圖和基表進行檢查。
		如果未給定任一關鍵字,預設值為CASCADED。
           

例子:

-- 查詢其他系中比數學系全部學生年齡大的學生姓名和年齡
select sname, YEAR(CURDATE()) - YEAR(sbirthday) as age
from student
where YEAR(CURDATE()) - YEAR(sbirthday) > ALL(
	select YEAR(CURDATE()) - YEAR(sbirthday)
	FROM student
	where sdept='數學系'
) AND sdept!='數學系';

-- 定義視圖(儲存上面查詢語句的結果)
create view stu_older_info
AS 
select sname, YEAR(CURDATE()) - YEAR(sbirthday) as age
from student
where YEAR(CURDATE()) - YEAR(sbirthday) > ALL(
	select YEAR(CURDATE()) - YEAR(sbirthday)
	FROM student
	where sdept='數學系'
) AND sdept!='數學系';

-- 查詢視圖資料
SELECT * FROM stu_older_info;
SELECT * FROM stu_older_info WHERE age=33; -- 視圖的查詢跟查詢資料表一樣可以條件查詢 及其他各種查詢方式
           

4、修改視圖

-- 文法:alter view 視圖名稱 as 修改後的查詢語句;
-- 示例:
ALTER VIEW stu_no
AS
SELECT *
FROM sc
WHERE degree > ANY(
	SELECT degree FROM sc where sno='20050301'
) AND sno!='20050301';

SELECT * FROM stu_no;
           

視圖修改完成後,再次查詢視圖,此時視圖的資料變成執行修改後的查詢語句。

修改視圖的名稱:可以先将視圖删除,然後按照相同的定義語句進行視圖的建立,并命名為新的視圖名稱

5、删除視圖

-- 文法:drop view 視圖名稱
-- 示例:
drop view stu_no;
           

6、檢視視圖資訊

1)使用DESCRIBE檢視視圖

在MySQL中,使用權DESCRIBE語句可以檢視視圖的字段資訊,包括字段名、字段類型等資訊。

-- DESCRIBE語句的文法格式如下所示:
DESCRIBE 視圖名;
-- 或簡寫為:
DESC 視圖名;

-- 示例:
desc stu_older_info;
           

檢視資訊結果說明:Field:視圖中的字段名;Type:字段的資料類型;Null:表示該字段是否允許存放空值;Key:表示該字段是否已經建有索引;Default:表示該列是否有預設值;Extra:表示該列的附加資訊。

2)使用SHOW TABLE STATUS語句檢視視圖

-- 文法:
SHOW TABLE STATUS LIKE '視圖名稱';
-- 示例
SHOW TABLE STATUS LIKE 'stu_older_info';
           

從查詢中可以看到,Comment的值為VIEW,說明所檢視的teacher_view是一個視圖。

存儲引擎(Engine)、資料長度(Data_length)、索引長度(Index_length)等資訊都顯示為NULL,說明視圖是虛拟表。

3)檢視視圖的建立語句:SHOW CREATE VIEW語句

在查詢結果的create view字段,可以檢視定義視圖的語句

SHOW CREATE VIEW stu_older_info;
           

7、通過視圖更新資料

insert ,update ,delete
-- 通常是對基表的資料進行跟新,視圖的資料随着更新
UPDATE t_stuinfo SET c_id=1 WHERE s_id=8	-- 更新基表
SELECT * FROM vi_stu_class 			-- 查詢視圖(資料已改變)

-- 能不能通過視圖修改資料(把修改的資料儲存到基表),可以,但是有很多限制
UPDATE vi_stu_class SET s_sex='女' WHERE s_id=8   -- 修改視圖資料
SELECT * FROM t_stuinfo;			-- 查詢基表資料已修改
           

8、注意事項

(1) 建立,删除視圖等操作需要權限
(2) 視圖屬于資料庫。在預設情況下,将在目前資料庫建立新視圖。要想在給定資料庫中建立視圖,建立時,應将名稱指定為資料庫名.視圖名。
	如:目前資料庫t4 ,想在t9中建立 名為 vi_stu_sc的視圖
		create view t9.vi_stu_sc as 查詢語句
(3) 如果視圖的基表有多張,多張表有共同的字段,查詢select字句後要指定 該字段所屬的表 ,
	如:select * from 表1 inner join 表2 on 表1.id=表2.id 
	在建立視圖時的sql語句 寫 select 表1.id ,表1.某字段。。。。。from  表1 inner join 表2 on 表1.id=表2.id 
(4) 通過修改視圖進而修改基表資料的注意事項有:
	使用INSERT語句進行插入操作的視圖必須能夠在基表中插入資料,否則插入操作會失敗。
	如果視圖上沒有包括基表中所有屬性為NOT NULL 的字段,那麼插入操作會由于那些字段的NULL值而失敗。
	如果在視圖中使用聚合函數的結果,或者是包含表達式計算的結果,則插入操作不成功。
	不能在使用了DISTINCT,UNION,TOP,GROUP BY 或HAVING語句的視圖中插入資料。
	如果在建立視圖的CREATE VIEW語句中使用了WITH CHECK OPTION ,那麼所有對視圖進行修改的語句必須符合WITH CHECK OPTION中限定條件。
	對于由多個基表聯接查詢而生成的視圖來說,一次插入操作隻能作用于一個基表上。

	在視圖中更新資料與在基表中更新資料一樣,使用UPDATE語句。
	但是當視圖是來自多個基表中的資料時,與插入操作一樣,每次更新操作隻能更新一個基表中的資料,
	如果通過視圖修改存在于多個基表中的資料時,則對不同的基表要分别使用UPDATE語句來實作。
	在視圖中使用UPDATE語句進行更新操作也受到與插入操作一樣的限制。

	當一個視圖聯接了兩個以上的基表時,對資料的删除操作則不允許的