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