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
    ```
    SELECT sname, ssex, YEAR(CURRENT_DATE)-YEAR(sbirthday) as age
    FROM student
    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 *
    FROM student
    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 指定結果輸出范圍
```
SELECT *
FROM student
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、自連接

一張表內可以進行自身連接操作——同一個表的不同行連接起來。
- 必須為表指定兩個別名(邏輯上成兩個表)

(1)語法格式:

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

(2)示例:

-- 查詢同時選修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:保留兩邊表的所有行。

(1)語法格式:

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

(2)示例:

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語句進行更新操作也受到與插入操作一樣的限制。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM