一、安裝和配置資料庫:
下載下傳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語句進行更新操作也受到與插入操作一樣的限制。
當一個視圖聯接了兩個以上的基表時,對資料的删除操作則不允許的