花了3天時間學(xué)習(xí)MySql,考了個二級MySql
書籍參考:高等教育出版社《全國計算機等級考試二級教程-MySQL數(shù)據(jù)庫程序設(shè)計2016年版》
之后會持續(xù)考三級數(shù)據(jù)庫技術(shù)以及國際認(rèn)證證書
學(xué)習(xí)內(nèi)容整理如下方便以后快速查詢(完全根據(jù)下面的整理,再做7,8套練習(xí)題考個良好沒有問題):
1. 數(shù)據(jù)庫管理系統(tǒng)DBMS 是數(shù)據(jù)庫系統(tǒng)的核心
2. 數(shù)據(jù)庫屬于C/S架構(gòu)、Web屬于B/S架構(gòu)
3. 數(shù)據(jù)庫登錄(默認(rèn)用戶名root、密碼為空)
?mysql.exe -h localhost -u root -p
4. 數(shù)據(jù)模型
????4.1 概念模型
????典型的是實體聯(lián)系模型E-R模型(Entity-Relationship)
????實體、屬性、聯(lián)系
????4.2 邏輯模型
????層次模型、網(wǎng)狀模型、關(guān)系模型(二維表結(jié)構(gòu))、面向?qū)ο竽P?/p>
????4.3 物理模型
5. 數(shù)據(jù)庫的三級模式結(jié)構(gòu)是指:數(shù)據(jù)庫是由模式、外模式、內(nèi)模式三級構(gòu)成
6. 數(shù)據(jù)庫設(shè)計步驟
需求分析、概念結(jié)構(gòu)設(shè)計(E-R圖)、邏輯結(jié)構(gòu)設(shè)計、物理結(jié)構(gòu)設(shè)計、數(shù)據(jù)庫實施、數(shù)據(jù)庫運行和維護
7. SQL:Structured Query Language 所有關(guān)系型數(shù)據(jù)庫都支持SQL
?? ?語言組成:DDL、DML、DCL
8. MySQL函數(shù)
? ? 8.1 聚合函數(shù)==>COUNT() SUM() AVG() MAX() MIN()?常用于分組聚合查詢
? ? SELECT COUNT(*) FROM tb_student;
? ? SELECT AVG(score) FROM tb_score;
? ? 8.2 數(shù)學(xué)函數(shù)==>ABS() FLOOR() RAND() TRUNCATE(x, y) SQRT()
? ? SELECT ABS(-5), ABS(8), ABS(-8.1);
? ? SELECT SQRT(2); //計算平方根
? ? SELECT FLOOR(-5.1), FLOOR(5.1);
? ? SELECT RAND();
? ? SELECT TRUNCATE(589.123456, 4);
? ? 8.3 字符串函數(shù)==>UPPER() LOWER() LEFT() RIGHT() SUBSTRING()
? ? SELECT SUBSTRING('dsfkljasdklfj', 2, 5);
? ? 8.4 日期和時間函數(shù)==> CURDATE() CURTIME() NOW() YEAR(NOW())?YEAR(CURDATE())
? ? 8.5 其他函數(shù)==>IF(expr, v1, v2) IFNULL(v1, v2)
? ? SELECT studentNo, courseNo, score, IF(score>85, '優(yōu)秀','一般');
9. 數(shù)據(jù)庫命令
????9.1?
????SHOW DATABASES;?查看所有數(shù)據(jù)庫
????\s?查看數(shù)據(jù)庫基本信息
9.2?創(chuàng)建數(shù)據(jù)庫
?CREATE DATABASE?IF NOT EXISTS?db_school
CHARACTER SET UTF8
//修改數(shù)據(jù)庫字符集
COLLATE utf8_general_ci;
//指定字符集的校對規(guī)則
?? ? 9.3 選擇default數(shù)據(jù)庫
?USE db_school;
9.4?修改數(shù)據(jù)庫字符集
?ALTER?DATABASE db_school
?? ? CHARACTER SET gb2312
?COLLATE gb2312_chinese_ci;
?? ? 9.5 刪除數(shù)據(jù)庫
?DROP?DATABASE?IF EXISTSdb_school;?//數(shù)據(jù)庫刪除之后,之前設(shè)置該數(shù)據(jù)庫上的管理員權(quán)限并不會刪除,應(yīng)該手動刪除
10. 數(shù)據(jù)庫中的表 及 命令
10.1?查看表(SHOW)
? ? ?SHOW TABLES;?//查看當(dāng)前數(shù)據(jù)庫表
?SHOW TABLES FROM db_company; //查看非當(dāng)前數(shù)據(jù)庫表
?SHOW COLUMNS FROM tb_stu;?//查看表結(jié)構(gòu),可視效果比較好
?SHOW CREATE TABLE?tb_stu;?//查看更詳細(xì)的表結(jié)構(gòu),可以看到存儲引擎和字符編碼
? ? SHOW ENGINES;? ? //顯示所有存儲引擎信息
? ? 10.2 創(chuàng)建表(CREATE)
????CREATE TABLE tb_stu(
????stuNo CHAR(10),
????stuName VARCHAR(20)?NOT NULL,
????sex CHAR(2),
????bir DATE,
????native VARCHAR(20),
????nation VARCHAR(10)?DEFAULt?'漢',
????classNo CHAR(6)?REFERENCES?tb_class(classNo),
????CONSTRAINT?PK_stu?PRIMARY KEY(stuNo)
????)ENGINE=InnoDB;
10.3?修改表?(ALTER)
10.3.1?向表中添加字段
????????ALTER TABLE tb_stu ADD id1 INT NOT NULL;?//默認(rèn)添加到最后一行
?ALTER TABLE tb_stu ADD id1 INT NOT NULL?FIRST, ADD id2 TINYINT AUTO_INCREMENT?AFTER?stu_name;?//添加多個字段
????????10.3.2 修改表中的字段
????? ? CHANGE:?名稱、類型必須一起改, 默認(rèn)值填寫了才改,不寫就沒有默認(rèn)值, 可改順序。
?ALTER TABLE tb_stu2?CHANGE?id idtest INT NOT NULL DEFAULT '18' AFTER stu_name;
? ? ? ? ALTER:只能對默認(rèn)值的修改、設(shè)置、刪除
?ALTER TABLE tb_stu2?ALTER?id SET DEFAULT '10';?//修改、設(shè)置默認(rèn)值
????????ALTER TABLE tb_stu2?ALTER?id DROP DEFAULT;?//刪除默認(rèn)值
????? ? MODIFY:除了不能改列名,其他功能和CHANGE一樣
????? ??ALTER TABLE tb_stu2MODIFY?id SMALLINT NOT NULL?FIRST;
????? ? 10.3.3 刪除表中字段
????????ALTER TABLE tb_stu2DROP?id;
? ? 10.4 重命名表
?ALTER TABLE tb_stu2?RENAME TO?tb_stu3;?//修改一個表名
?RENAME?TABLE tb_stu1?TO?tb_stu2;?//另一種方式
????RENAME?TABLE tb_stu1TO?tb_stu2, tb_score1 TO tb_score2;?//另一種方式可重命名多個表
10.5?刪除表(DROP)
?DROP?TABLE IF EXIST tb_stu2;
11. 數(shù)據(jù)完整性約束
? ? 11.1 實體完整性約束
? ? 關(guān)系的主屬性不能取空值,即主鍵和候選鍵在關(guān)系屬性中所對應(yīng)的屬性都不能取空值
????? ? 11.1.1 主鍵約束(MySql自動對該表創(chuàng)建索引)
????? ? 列級完整性約束
????????CREATE TABLE tb_stu(
??????????????stuNo INT(10)?PRIMARY KEY?AUTO_INCREMENT,
????????????? ? 。。。。。。
????????)ENGINE = InnoDB;
????? ? 表級完整性約束
????????CREATE TABLE tb_stu2(
???????????? stuNo INT(10) AUTO_INCREMENT,
????????????。。。。。。
????????????PRIMARY KEY(stuNo)
????????)ENGINE = InnoDB;
????? ? 11.1.2 完整性約束的命名
????? ? 對完整性約束命名后,才能對其約束進行增刪改操作。
????? ? 目前MySQL只能給表級完整性約束命名,因此盡量定義表級完整性約束
????????CREATE TABLE tb_stu2(
???????????? stuNo INT(10) AUTO_INCREMENT,
???????????? 。。。。。。
???????????? CONSTRAINT PK_stu?PRIMARY KEY(stuNo)
????????)ENGINE = InnoDB;
????? ? 11.1.3 候選鍵約束
????????CREATE TABLE tb_class(
??????????????classNo CHAR(6),
??????????????className VARCHAR(20) NOT NULL,
???????????????。。。。。。
??????????????CONSTRAINT PK_class PRIMARY KEY(classNo),
??????????????CONSTRAINT UQ_class UNIQUE(className)
????????)Engine = InnoDB;
? ? 11.2 參照完整性約束
????CREATE TABLE tb_stu(
??????????????stuNo CHAR(10),
????????????????。。。。。。
??????????????classNum CHAR(6),
??????????????CONSTRAINT PK_stu PRIMARY KEY(stuNo),
??????????????CONSTRAINT FK_stu FOREIGN KEY(classNum) REFERENCES tb_class(classNo)
?????)ENGINE = InnoDB;
? ? 11.3 用戶定義完整性約束
????? ? 11.3.1 設(shè)置非空約束
????? ? 略
????? ? 11.3.2 CHECK約束
????? ? 列級:
?略?
????? ? 表級:
????????CREATE TABLE tb_course(
??????????????courseNo CHAR(6),
??????????????courseName CHAR(20),
??????????????credit INT,
??????????????courseHour INT,
??????????????term CHAR(2),
??????????????priorCourse CHAR(6),
??????????????CONSTRAINT PK_course PRIMARY KEY(courseNo),
??????????????CONSTRAINT FK_course FOREIGN KEY(priorCourse) REFERENCES tb_course(courseNo),
??????????????CONSTRAINT CK_course CHECK(credit = courseHour/16)
????????)Engine = InnoDB;
11.4?更新完整性約束
? ??? ? 11.4.1 刪除約束
????????? ? 11.4.1.1 刪除外鍵約束
ALTER TABLE tb_score?DROP FOREIGN KEY?FK_score;? //注意,刪除外鍵約束時,外鍵名沒有()
????????? ? 11.4.1.1 刪除主鍵約束
?因為一個表只有一個主鍵或者一個復(fù)合主鍵,因此刪除主鍵不用填寫主鍵命名
ALTER TABLE tb_stu?DROP PRIMARY KEY;
????????? ? 11.4.1.1 刪除候選鍵約束
?刪除候選鍵約束,實際上刪除的是唯一性索引
ALTER TABLE tb_class?DROP INDEX className;
????? ? 11.4.2 添加約束
????????11.4.2.1 添加主鍵約束
添加有約束命名的主鍵約束:
????????????ALTER TABLE tb_stu ADD CONSTRAINT PK_stu PRIMARY KEY(stuNo);
????????? ? 添加沒有約束命名的主鍵約束:
????????????ALTER TABLE tb_stu ADD PRIMARY KEY(stuNo);
????????11.4.2.1?添加外鍵約束
添加有約束命名的外鍵約束:
????????????ALTER TABLE tb_score ADD CONSTRAINT FK_score1 FOREIGN KEY(stuNo) REFERENCES tb_stu(stuNo);
????????????添加沒有約束命名的外鍵約束:
????????????ALTER TABLE tb_score ADD FOREIGN KEY(stuNo) REFERENCES tb_stu(stuNo);
????????11.4.2.1?添加候選鍵約束
添加有約束命名的候選鍵約束:
????????????ALTER TABLE tb_class ADD CONSTRAINT UQ_class UNIQUE(className);
????????????添加沒有約束命名的候選鍵約束:
????????????ALTER TABLE tb_class ADD UNIQUE(className);
12. 單表查詢
? ? 12.1 選擇字段
?SELECT?*?FROM tb_stu;?//所有字段
?SELECT?DISTINCT?department FROM tb_class;?//去掉重復(fù)數(shù)據(jù)
?SELECT classNo, department, className FROM tb_class;?//某些字段
?SELECT stuName, YEAR(NOW()) - YEAR(bir) FROM tb_stu;?//選擇計算后的值
????SELECT stuName?AS?'姓 名',YEAR(NOW()) - YEAR(bir)?年齡?FROM tb_stu;?//字段取別名, AS可省略
? ? 12.2 選擇指定記錄 WHERE子句
? ? ????12.2.1 比較大小
?SELECT courseName, credit FROM tb_course?WHERE?courseHour >= 48;
????????SELECT courseName, credit FROM tb_course?WHERE?NOT?courseHour < 48;
????????SELECT courseName, credit FROM tb_course?WHERE?courseHour <> 48;
????????SELECT courseName, credit FROM tb_course?WHERE?NOT?courseHour =?48;
????? ? 12.2.2 帶范圍查詢 BETWEEN...AND
?SELECT stuName, sex, bir FROM tb_stu?WHERE?bir?BETWEEN?'1997-01-01'?AND?'1997-12-31';
????????SELECT stuName, sex, bir FROM tb_stu?WHERE?bir?NOT BETWEEN?'1997-01-01'?AND?'1997-12-31';
????? ? 12.2.3 帶IN的集合查詢
?SELECT * FROM tb_stu WHERE native?IN('北京', '天津', '上海');
????????SELECT * FROM tb_stu WHERE native?NOT IN('北京', '天津', '上海');
????? ? 12.2.4 帶LIKE的字符串匹配查詢(通配符% 和 _)
????? ? %:代表任意長度包括長度為0
????? ? _:?代表代表任意單個字符
?SELECT * FROM tb_stu WHERE stuNo?LIKE?'2013110201';?//精準(zhǔn)匹配學(xué)號
????????SELECT * FROM tb_stu WHERE stuName?LIKE '王%';?//查詢姓王的
????????SELECT * FROM tb_stu WHERE stuName?NOT LIKE?'王%';?//查詢不姓王的
????????SELECT * FROM tb_stu WHERE stuName?LIKE?'王__';?//查詢姓王,名字是三個字的
?SELECT * FROM tb_course WHERE courseName LIKE '%#_%'?ESCAPE?'#';?//_作為匹配內(nèi)容,必須用ESCAPE指定換碼符,但換碼符不能是\
????? ? 12.2.5 IS NULL和IS NOT NULL
?SELECT * FROM tb_course WHERE priorCourse?IS NULL;?//不能改為=NULL
?SELECT *?FROM tb_course WHERE priorCourse?IS NOT NULL;?//不能改為!=NULL
????? ? 12.2.6 帶AND或OR的多條件查詢(AND優(yōu)先級高于OR,可用括號改變優(yōu)先級)
?SELECT * FROM tb_course WHERE credit >= 3?AND?courseHour > 32;
?SELECT * FROM tb_stu WHERE native = '北京'?OR?native = '上海';
????????SELECT * FROM tb_stu WHERE native?IN?('北京',?'上海');?//IN的速度優(yōu)于OR
?SELECT * FROM tb_stu WHERE (native = '北京' OR?native =?'湖南')AND nation != '漢' AND sex = '男';
? ? 12.3 對查詢結(jié)果排序
? ? NULL將作為最小值處理
?SELECT * FROM tb_stu?ORDER BY?stuName?ASC;?//名字升序排列,默認(rèn)ASC,這里ASC可不寫
?SELECT * FROM tb_score WHERE score > 85?ORDER BY?stuNo ASC, score?DESC;?//升序ASC,降序DESC
? ? 12.4 限制查詢結(jié)果的數(shù)量
?SELECT * FROM tb_score ORDRE BY score DESC?LIMIT?4, 5;?//查詢成績排名5到10位的成績信息, 注意偏移量是0 Base
13. 分組聚合查詢
? ? 13.1 使用聚合函數(shù)查詢
?SELECT COUNT(stuNo) FROM tb_stu;?//查詢學(xué)生總?cè)藬?shù)
?SELECT?COUNT(DISTINCT stuNo)?FROM tb_score;?//查詢有課程成績的學(xué)生總?cè)藬?shù), DISTINCT 寫在SELECT后面則會重復(fù)統(tǒng)計,應(yīng)該寫在COUNT函數(shù)內(nèi)
?SELECT?AVG(score) FROM tb_score?WHERE courseNo = '21001';?//查詢課程號為21001的課程平均分
? ? 13.2 分組聚合查詢
?SELECT?courseNo, COUNT(stuNo) FROM tb_score?GROUP BY?courseNo;?//查詢各個課程號及相應(yīng)選課人數(shù), 因為courseNo是GROUP BY的對象,所以SELECT后面要有courseNo,否則顯示不明確
?SELECT?stuNo, COUNT(courseNo), AVG(score), MAX(score) FROM tb_score?GROUP BYstuNo;?//查詢每個學(xué)生的選課門數(shù),平均分和最高分
????SELECTstuNo, COUNT(courseNo), AVG(score), MAX(score) FROM tb_scoreGROUP BYstuNo?HAVING?AVG(score) > 80;?//查詢平均分在80以上的每個學(xué)生的選課門數(shù),平均分和最高分
?SELECT stuNo, COUNT(courseNo) FROM tb_score?WHERE?score > 88GROUP BY?stuNo?HAVING?COUNT(score) >=2;?//查詢至少有2門課程成績大于88分的學(xué)生學(xué)號和大于88分的課程數(shù)
?WHERE子句過濾基本表或視圖,基于特定值;HAVING子句則作用于分組后的每個組,用于過濾分組,基于分組聚合值,不是特定值
????SELECT AVG(score) FROM tb_score?HAVING?AVG(score) > 80;?//沒有GOURP BY則將分組匯總,?AVG(score) > 80寫在HAVING里,寫在WHERE中運行報錯!因為是基于分組聚合值,不是特定值,所以寫在HAVING里
14. 連接查詢
? ? 14.1 交叉連接 (CROSS JOIN)
? ? 將表1的每一行與表2的每一行分別連接,產(chǎn)生很多無意義數(shù)據(jù),應(yīng)避免使用
? ? SELECT COUNT(*) FROM tb_stu; SELECT COUNT(*) FROM tb_course;?SELECT COUNT(*) FROM tb_stu?CROSS JOIN?tb_course;//交叉鏈接查詢總數(shù)是表1總數(shù)X表2總數(shù),中有很多無意義值;CROSS JOIN可用,替換
? ? SELECT * FROM tb_stu,?tb_course; //基本不用,使用時用WHERE過濾減少返回結(jié)果集的數(shù)量
? ? 14.2 內(nèi)鏈接 (INNER JOIN)
????? ? 14.2.1 等值于非等值連接?
?SELECT tb_stu.*, className FROM tb_stu,?tb_class WHERE tb_stu.classNo = tb_class.classNo AND department = '會計學(xué)院';
????????SELECT tb_stu.*, className FROM tb_stu?INNER JOINtb_class?ON?tb_stu.classNo = tb_class.classNo?WHERE?department = '會計學(xué)院';?//查詢會計學(xué)院所有同學(xué)的信息和班級名
????? ? PS:最好使用INNER JOIN...ON...便于顯示表達內(nèi)連接的表和表間的連接條件
內(nèi)連接是系統(tǒng)默認(rèn)連接,所以可以省略INNER
?SELECT tb_stu.stuNo, stuName, score FROM tb_stu, tb_score, tb_course WHERE tb_stu.stuNo = tb_score.stuNo AND tb_score.courseNo = tb_course.courseNo AND courseName = '程序設(shè)計';
????????SELECT tb_stu.stuNo, stuName, score FROM tb_stu?INNER JOINtb_score?INNER JOINtb_course?ON?tb_stu.stuNo = tb_score.stuNo AND tb_score.courseNo = tb_course.courseNo?WHERE?courseName = '程序設(shè)計';
SELECT a.stuNo, stuName, score FROM tb_stu?AS?aINNER JOINtb_score?AS?bINNER JOINtb_course?AS?cONa.stuNo = b.stuNo AND b.courseNo = c.courseNoWHERE?courseName = '程序設(shè)計';
????? ? 14.2.2 自連接
? ? ? ? 自己連接自己
????? ? SELECT * FROM tb_course AS c1 INNER JOIN tb_course AS c2 ON c1.credit = c2.credit WHERE c2.courseName = '數(shù)據(jù)庫';
????? ? || 推演
????? ? V
????????SELECT c1.* FROM?tb_course AS c1?INNER JOIN?tb_course AS c2?ON c1.credit = c2.credit WHERE?c2.courseName = '數(shù)據(jù)庫' AND c1.courseName != '數(shù)據(jù)庫';
????? ? 14.2.3 自然連接
SELECT a.stuNo, stuName, courseNo, score FROM tb_stu a?INNER JOIN?tb_score b?ON?a.stuNo = b.stuNo;
????? ? ^
????? ? || 等價
????? ? v
????????SELECT a.stuNo, stuName, courseNo, score FROM tb_stu a?NATURAL?JOINtb_score b;
? ? 14.3 外連接(OUTER JOIN)
????? ? 14.3.1 左外連接 (左表為基表)
? ? ? ? ?SELECT a.*, courseNo, score FROM tb_stu a?LEFT OUTER JOIN?tb_score b?ON?a.stuNo = b.stuNo;
tb_stu是左/基表, tb_score是右/參考表
????????查詢結(jié)果除了顯示自然連接能夠匹配的數(shù)據(jù),也會顯示基表沒有匹配的數(shù)據(jù),例如有一個學(xué)生沒有選課和成績,會將課程和成績顯示為NULL
????? ? 14.3.2 右外連接(右表為基表)
????? ? 參考左外連接
????????SELECT a.*, courseNo, score FROM tb_stu aRIGHT OUTER JOINtb_score bON?a.stuNo = b.stuNo;
?例如有一個學(xué)生沒有選課和成績,但是因為右表為基表, 則不會顯示沒有選課和成績的那個學(xué)生的信息
15. 子查詢
? ? 15.1 帶IN關(guān)鍵字
? ? 略
? ? 15.2 帶比較運算符
????略
15.3?帶EXISTS關(guān)鍵字(難理解)
?EXISTS含義:EXISTS構(gòu)造查詢子句時,如果子查詢結(jié)果集不為空,EXISTS返回TRUE,此時外查詢語句進行查詢;如果子查詢結(jié)果集為空,則EXISTS返回的結(jié)果為FALSE,此時外查詢語句將不進行查詢。
????SELECT stuName FROM tb_stu a WHERE?EXISTS?(SELECT * FROM tb_score b WHERE a.stuNo = b.stuNo AND courseNo='31002');?//查詢選修了課程號為‘31002’的學(xué)生姓名
????SELECT stuName FROM tb_stu a WHERE?NOT EXISTS?(SELECT * FROM tb_score b WHERE a.stuNo = b.stuNo AND courseNo='31002');?//查詢沒有選修課程號為‘31002’的學(xué)生姓名
????SELECT?stuName?FROM?tb_stu x?WHERE?NOT EXISTS(SELECT * FROM tb_course c WHERE NOT EXISTS(SELECT * FROM tb_score WHERE stuNo = x.stuNo AND courseNo = c.courseNo));?//查詢選擇了所有課程的學(xué)生姓名 <==>?查詢學(xué)生姓名,沒有一門課程是他沒有選的
16. 聯(lián)合查詢(UNION)
17. 數(shù)據(jù)更新
? ? 17.1 插入數(shù)據(jù)(INSERT|REPLACE INTO)
????? ? 17.1.1 插入完整的數(shù)據(jù)記錄
?完整插入命令,前后手動匹配
????? ??INSERT INTO?tb_stu (stuNo, sex, stuName, bir, native, nation, classNum)?VALUES('2014210104', '男', '王玲啊', '1998-02-22', '重慶', '漢', 'CS1401');
?簡寫插入命令,嚴(yán)格按照表結(jié)構(gòu)順序插入,不用填寫column_list()
????????INSERT INTO?tb_stu?VALUES('2014210103', '王玲', '女', '1998-02-21', '安徽', '漢', 'CS1401');
????? ? 17.1.2 為表的指定字段插入數(shù)據(jù)
?沒有填寫值的字段,必須允許值為NULL或者有默認(rèn)值
????????INSERT INTO?tb_stu (stuNo, sex, stuName, bir, classNum)?VALUES('2014210105', '女', '王玲吧', '1998-02-23', 'CS1401');
????? ? 17.1.3 同時插入多條數(shù)據(jù)記錄
????????INSERT INTO tb_stu VALUES('2014210108', '王玲', '女', '1998-02-21', '安徽', '漢', 'CS1401'),
???????????????????????????????????????????????('2014210106', '王玲1', '女', '1998-02-24', '安徽', '漢', 'CS1401'),
???????????????????????????????????????????????('2014210107', '王玲2', '女', '1998-02-21', '安徽', '漢', 'CS1401');
????? ? 17.1.4 插入查詢結(jié)果
????????INSERT INTO tb_stu2 SELECT * FROM tb_stu WHERE sex = '男';
????? ? 17.1.5 使用REPLACE語句插入表數(shù)據(jù)
????????如果插入一條主鍵或者候選鍵相同的字段,用INSERT會插入失敗,因為主鍵和候選鍵必須唯一。
????? ? 這種情況下用REPLACE替換INSERT,那么將原來的記錄刪除,在插入新的記錄
????????REPLACE INTO?tb_stu2 VALUES('2014210103', '王琳琳', '女', '1998-03-21', '成都', '回', 'CS1401');
? ? 17.2 修改數(shù)據(jù)記錄(UPDATE SET)
????? ? 17.2.1 修改特定數(shù)據(jù)記錄
?必須用WHERE指定哪條特定記錄,否則將全部更新!見17.2.2
????? ??UPDATE?tb_stu2?SET?stuName='王林', sex='女'?WHERE?stuNo = '2014210103';
????? ? 17.2.2 修改所有數(shù)據(jù)記錄
????????UPDATE tb_stu2 SET stuName='王林', sex='女';
????? ? 17.2.3 帶子查詢的修改
????? ? 略
? ? 17.3 刪除數(shù)據(jù)記錄(DELETE FROM)
????? ? 17.3.1 刪除特定數(shù)據(jù)記錄
????????必須用WHERE指定哪條特定記錄,否則將全部更新!見17.3.3
????????DELETE FROM?tb_stu2?WHERE?stuNo='2014210108';
????? ? 17.3.2 帶子查詢的刪除
? ? ? ? 略
????? ? 17.3.3 刪除所有數(shù)據(jù)記錄(刪除數(shù)據(jù)后保留表定義:)
????? ? 逐條刪除表記錄:
????????DELETE FROM?tb_stu2;
????? ? 效率更高的TRUNCATE:先DROP TABLE tb_stu2; 再CREATE TABLE tb_stu2.........;
????? ? TRUNCATE tb_stu2;
18. 索引
18.1 概述
18.1.1 查詢優(yōu)化,全文搜索和索引式搜索
18.1.2?索引按性質(zhì)分類
?普通索引:索引列值可以為NULL或重復(fù)值? ? ? ? ? ? 唯一性索引UNIQUE: 索引值不能重復(fù),但可以為NULL? ? ? ? ? ? 主鍵索引:唯一性索引的一種,列值除了不能重復(fù),也不能為NULL? ? ? ? ? ? 聚簇索引:索引順序是數(shù)據(jù)存儲的物理存儲順序,一個表只能有一個聚簇索引,solidDB和InnoDB可以支持聚簇索引? ? ? ? ? ? 全文索引:只能建立再VCHAR或TEXT的列上,只能在MyISAM數(shù)據(jù)庫引擎創(chuàng)建全文索引
18.1.3 按使用分類
????????????單列索引:一個索引只在一個表的一個列上????????????組合索引:一個索引建立在一個表的多個列上
18.2 查看數(shù)據(jù)表上所建立的索引
? ? 下列查看索引等價:
? ? SHOW INDEX FROM tb_stu \G;
SHOW INDEX FROM db_school.tb_stu?\G;
SHOW INDEX FROM tb_stu FROM db_school?\G;
????*************************** 1. row ***************************????
????? ? ??? ? ?Table: tb_score #索引所在表
? ?? ?Non_unique: 0????????? ? #該索引是否不是唯一索引
? ? ????Key_name: PRIMARY? ?#索引名稱
?Seq_in_index: 1
?Column_name: stuNo????? ? #建立索引的列名
?Collation: A????????????? ? #說明是何種排序的索引A:ASC升序;D:DESC降序
? ? ? ?Cardinality: 10
? ? ? ? ?Sub_part: NULL
?Packed: NULL
? ? ? ? ? ? ? ? ?Null:
? ? ? ?Index_type: BTREE
? ? ? ? ?Comment:
Index_comment:
*************************** 2. row ***************************
。。。。。。
18.3 創(chuàng)建索引
????除了普通索引用?INDEX(col_name)?創(chuàng)建外,在MySQL中主鍵、唯一性是創(chuàng)建表時系統(tǒng)默認(rèn)創(chuàng)建
注意用CREATE INDEX?...?ON 和 用ALTER TABLE ... ADD的語法區(qū)別
18.3.1 使用CREATE TABLE創(chuàng)建索引
?不創(chuàng)建任何索引的TABLE:
????????CREATE TABLE tb_stu2(
????????????stuNo CHAR(10) NOT NULL,
????????????stuName CHAR(20),
????????????sex CHAR(2),
????????????bir DATE,
????????????native CHAR(20),
????????????nation CHAR(10),
????????????classNum CHAR(6)
????????)Engine = InnoDB;
????????mysql>?SHOW INDEX FROM tb_stu2 \G
????????Empty set (0.00 sec) #查詢不到任何索引信息
?創(chuàng)建普通索引:
????????CREATE TABLE tb_stu1(
????????????stuNo CHAR(10) NOT NULL,
????????????stuName CHAR(20),
????????????sex CHAR(2),
????????????bir DATE,
????????????native CHAR(20),
????????????nation CHAR(10),
????????????classNum CHAR(6),
????????????INDEX(stuName)
????????)Engine = InnoDB;
?創(chuàng)建唯一性索引:
????????CREATE TABLE tb_stu2(
????????????stuNo CHAR(10) NOT NULL?UNIQUE,
????????????stuName CHAR(20),
????????????sex CHAR(2),
????????????bir DATE,
????????????native CHAR(20),
????????????nation CHAR(10),
????????????classNum CHAR(6)
????????)Engine = InnoDB;
????????創(chuàng)建主鍵索引:
創(chuàng)建PRIMARY KEY時默認(rèn)創(chuàng)建主鍵索引
????????CREATE TABLE tb_score1(
????????????stuNo CHAR(10),
????????????courseNo CHAR(5),
????????????CONSTRAINT PK_socre PRIMARY KEY(stuNo, courseNo),
????????????CONSTRAINT FK_socr1 FOREIGN KEY(stuNo) REFERENCES tb_stu(stuNo),
????????????CONSTRAINT FK_socr2 FOREIGN KEY(courseNo) REFERENCES tb_course(courseNo)
????????)Engine = InnoDB;
18.3.2使用CREATE INDEX創(chuàng)建索引(在已有表上)
創(chuàng)建普通索引:
?CREATE INDEX?INDEX_stu?ON?tb_stu2(stuName);
創(chuàng)建基于字段值前綴字符的普通索引:
CREATE INDEX?INDEX_course?ON?tb_course(courseName(3) DESC);
創(chuàng)建組合索引:
?CREATE INDEX?INDEX_stu1?ON?tb_stu2(stuName, stuNo DESC);
18.3.3使用ALTER TABLE創(chuàng)建索引(在已有表上)
建立普通索引:
ALTER TABLE?tb_stu2?ADD?INDEX?index_stuName(stuName);
建立主鍵和唯一性索引參考第三章,系統(tǒng)自動創(chuàng)建
18.4 刪除索引
18.4.1 使用DROP INDEX ...ON語句刪除索引
?DROP INDEX?INDEX_stu?ON?tb_stu2;
18.4.2 使用ALTER TABLE...DROP INDEX語句刪除索引
ALTER TABLE?tb_stu2?DROP INDEX?index_stuName;
18.5 進一步說明
18.5.1 過多使用索引的問題
會降低更新表中數(shù)據(jù)(INSERT、UPDATE、DELETE)的速度;
增加磁盤存儲空間
18.5.2 使用索引建議
在頻繁(INSERT、UPDATE、DELETE)的表上,盡量少創(chuàng)建索引
數(shù)據(jù)量小的表最好不建索引
使用組合索引時,嚴(yán)格遵循最左前綴法則
在查詢表達式中經(jīng)常使用、有較多不同值的字段上建立索引。例如sex只有男女選項,不建索引
對VARCHAR,CHAR這樣的字符變量建立索引,最好使用前幾個字符簡歷索引而不是全部字段建索引以提高效率
19 視圖VIEW
19.1 概述
?視圖與數(shù)據(jù)庫的區(qū)別:
VIEW是一張?zhí)摂M表,是建立在對數(shù)據(jù)庫中真實存在的表的查詢基礎(chǔ)上的
VIEW是由SQL語句定義,行、列來源于定義視圖查詢所引用的真是表(基表、源表)或基表的計算值,在引用視圖時動態(tài)生成
VIEW不是以數(shù)據(jù)集的形式存在于數(shù)據(jù)庫中,它所對應(yīng)的數(shù)據(jù)是存儲在視圖所引用的真是表中
VIEW本身不存儲數(shù)據(jù)
?視圖的優(yōu)點:
用于集中各個表中分散的數(shù)據(jù),方便查詢
簡化查詢語句
重用SQL語句。若基表中的數(shù)據(jù)被更新等操作,VIEW使用的是更新后的數(shù)據(jù),因此應(yīng)用程序可重用之前的SQL語句
通過權(quán)限設(shè)置,屏蔽基表權(quán)限,開啟VIEW權(quán)限達到保護數(shù)據(jù)安全的目的
多用戶共享所需數(shù)據(jù)
可以通過視圖重新定義檢索出的數(shù)據(jù)格式,并組織到其他應(yīng)用中輸出
19.2 創(chuàng)建視圖
創(chuàng)建視圖v_stu,并且之后在v_stu上的每次修改都必須滿足sex=‘男’
CREATE OR REPLACE?VIEW?v_stu?AS?SELECT * FROM tb_stu WHERE sex = '男'?WITH CHECK OPTION;
創(chuàng)建v_score_avg,并按照stuNo排序
CREATE OR REPLACE VIEW v_score_avg AS SELECT stuNo, AVG(score) FROM tb_score GROUP BY stuNo;
19.3 刪除視圖
類似于DROP DATABASE... 和 DROP TABLE...
?DROP VIEW?IF EXISTS v_stu;
19.4 修改視圖定義
類似于ALTER?TABLE...
ALTER VIEW?v_stu?AS?SELECT stuNo, stuName, classNum FROM tb_stu WHERE sex = '男' AND nation = '漢'?WITH CHECK OPTION;
?CREATE OR REPLACE VIEW?v_stu?AS?SELECT stuNo, stuName, classNum FROM tb_stu WHERE sex = '男' AND nation = '漢'?WITH CHECK OPTION;
19.5 查看視圖定義
類似于SHOW CREATE TABLE ... 和 SHOW COLUMNS FROM ...
SHOW CREATE?VIEW?v_stu\G
SHOW?COLUMNS FROM?v_stu\G
19.6 更新試圖數(shù)據(jù)
如同更新表中數(shù)據(jù),略
19.7 查詢視圖數(shù)據(jù)
SELECT * FROM v_stu;
類似于查詢TABLE,略
19.8 進一步說明
需要權(quán)限
視圖數(shù)目沒有限制
視圖可以嵌套
如果查詢視圖使用ORDER BY子句,且創(chuàng)建視圖的SELECT中也有ORDER BY,那么視圖查詢的ORDER BY會被SELECT的ORDER BY 覆蓋
視圖不能索引、也不能有觸發(fā)器和默認(rèn)值
VIEW可以和TABLE聯(lián)表查詢
如果視圖由多個條件或者聯(lián)表查詢組成,那么可能占用很多計算機資源。需要測試性能
20. 觸發(fā)器
20.1 觸發(fā)器
具體而言,觸發(fā)器就是MySQL響應(yīng)INSERT、UPDATE、DELETE語句而自動執(zhí)行的MySQL語句。其他mysql不支持
20.2?創(chuàng)建觸發(fā)器
? ? CREATE TRIGGER?tb_stu_insert——trigger?AFTER INSERT ON?tb_stu?FOR EACH ROW?SET?@str = 'add a stu!';
????查看TRIGGER
?SHOW TRIGGERS;
INSERT INTO tb_stu VALUES('2018110105', '張曉勇', '男', '1997-12-11', '山西', '漢', 'AC1301');
??SELECT @str;
+-------------+
| @str? ? ? ? ?|
+-------------+
| add a stu! |
+-------------+
20.3 刪除觸發(fā)器
?DROP TRIGGER?IF EXISTS tb_stu_insert;
20.4 使用觸發(fā)器(NEW和OLD虛擬表的使用)
20.4.1 INSERT 觸發(fā)器
CREATE TRIGGER tb_stu_insert_trigger AFTER INSERT ON tb_stu FOR EACH ROW SET @str =?NEW.stuNo;
????20.4.1 UPDATE 觸發(fā)器
CREATE TRIGGER tb_stu_delete_trigger AFTER DELETE ON tb_stu FOR EACH ROW SET @str =?OLD.stuNo;
????? ? 20.4.1 DELETE 觸發(fā)器
CREATE TRIGGER tb_stu_update_trigger BEFORE UPDATE ON tb_stu FOR EACH ROW SET NEW.nation = OLD.native;
20.5 進一步說明
21. 事件EVENT
EVENT 與 TRIGGER的區(qū)別:事件是基于特定時間周期觸發(fā)來執(zhí)行任務(wù);觸發(fā)器是基于某個表所產(chǎn)生的事件觸發(fā)
21.1 事件
查看事件調(diào)度器:
?SHOW VARIABLES?LIKE 'EVENT_SCHEDULER'; 或者
SHOW VARIABLES?LIKE 'EVENT%'; 或者
SELECT?@@EVENT_SCHEDULER;
若時間調(diào)度器未啟用,則開啟:
?SET GLOBAL EVENT_SCHEDULER?= 1; 或者
SET GLOBAL EVENT_SCHEDULER = TRUE;
21.2?創(chuàng)建事件
DELIMITER $$
CREATE?EVENT?IF NOT EXISTS event_insert
ON SCHEDULE?EVERY?1 MONTH
STARTS?CURDATE()?+ INTERVAL?1 MONTH
???????ENDS?'2019-12-31'
DO
BEGIN
IF YEAR(CURDATE()) < 2013 THEN
INSERT INTO tb_stu VALUES(NULL, '張曉勇', '男', '1997-12-11', '山西', '漢', 'AC1301');
END IF;
END$$
查看事件:
?SHOW EVENTS;
21.3 修改事件
關(guān)閉事件:
?ALTER EVENT?event_insert?DISABLE;
重新開啟事件:
ALTER EVENT event_insert?ENABLE;
重命名事件名:
ALTER EVENT event_insert?RENAME TO?e_insert;
? ? 21.4?刪除事件
?DROP EVENT?IF EXISTS event_name;
22. 存儲過程與存儲函數(shù)
22.1 存儲過程
22.1.1 創(chuàng)建存儲過程
DELIMITER !!
CREATE PROCEDURE IF NOT EXISTS sp_update_sex(IN sno CHAR(10), IN ssex CHAR(2))
?BEGIN
UPDATE tb_stu SET sex = ssex WHERE stuNo = sno;
?END!!
????? ? 22.1.2?存儲過程體
22.1.2.1 局部變量
?DECLARE?sno CHAR(10);#不帶默認(rèn)值
DECLARE?sno CHAR(10)?DEFAULT?'2018110105';#帶默認(rèn)值
22.1.2.2 SET語句
SET?sno = '2018110105';
22.1.2.3 SELECT INTO語句
22.1.2.4 流程控制語句
22.1.2.5 游標(biāo)
????? ? 22.1.3?調(diào)用存儲過程
?CALL?sp_update_sex('2018110105', '男');
????? ? 22.1.4?刪除存儲過程
DROP PROCEDURE IF EXISTS?sp_update_sex;
22.2 存儲函數(shù)
22.2.1 創(chuàng)建存儲函數(shù)
?CREATE FUNCTION?IF NOT EXISTS fn_search(sno CHAR(10))
?RETURNS?CHAR(2)
?DETERMINISTIC
BEGIN
DECLARE SSEX CHAR(2);
?SELECT?sex?INTO?SSEX FROM tb_stu WHERE sno = stuNo;
IF SSEX IS NULL THEN
RETURN (SELECT '沒有該學(xué)生');
ELSE IF SSEX = '女' THEN
RETURN (SELECT '女');
ELSE
RETURN?(SELECT '男');
END IF;
END$$
????22.2.1 調(diào)用存儲函數(shù)
?SELECT?funcName('2018110105');
????? ? 22.2.1 刪除存儲函數(shù)
DROP FUNCTION IF EXISTS funcName;
23. 訪問控制與安全管理
24. 備份與恢復(fù)
書中例子備份:
CREATE TABLE tb_class(
classNo CHAR(6),
className VARCHAR(20) NOT NULL,
department VARCHAR(30) NOT NULL,
grade SMALLINT,
classNum TINYINT,
CONSTRAINT PK_class PRIMARY KEY(classNo),
CONSTRAINT UQ_class UNIQUE(className)
)Engine = InnoDB;
INSERT INTO tb_class VALUES('AC1301', '會計13-1班',? ? ?'會計學(xué)院',? ?2013, 35),
? ?('AC1302', '會計13-2班',? ? ?'會計學(xué)院',? ?2013, 35),
? ?('CS1401', '計算機14-1班',? ?'計算機學(xué)院', 2014, 35),
? ?('IS1301', '信息系統(tǒng)13-1班', '信息學(xué)院',? ?2013, NULL),
? ?('IS1401', '信息系統(tǒng)14-1班', '信息學(xué)院',? ?2014, 30);
CREATE TABLE tb_course(
courseNo CHAR(6),
courseName CHAR(20),
credit INT,
courseHour INT,
term CHAR(2),
priorCourse CHAR(6),
CONSTRAINT PK_course PRIMARY KEY(courseNo),
CONSTRAINT FK_course FOREIGN KEY(priorCourse) REFERENCES tb_course(courseNo),
CONSTRAINT CK_course CHECK(credit = courseHour/16)
)Engine = InnoDB;
INSERT INTO tb_course VALUES('11003', '管理學(xué)',? ? ? ? ? ? ? 2, 32, '2', NULL),
? ? ('11005', '會計學(xué)',? ? ? ? ? ? ? 3, 48, '3', NULL),
? ? ('21001', '計算機基礎(chǔ)',? ? ? ? ? 3, 48, '1', NULL),
? ? ('21002', 'OFFICE高級應(yīng)用',? ? ? 3, 48, '2', '21001'),
? ? ('21004', '程序設(shè)計',? ? ? ? ? ? 4, 64, '2', '21001'),
? ? ('21005', '數(shù)據(jù)庫',? ? ? ? ? ? ? 4, 64, '4', '21004'),
? ? ('21006', '操作系統(tǒng)',? ? ? ? ? ? 4, 64, '5', '21001'),
? ? ('31001', '管理信息系統(tǒng)',? ? ? ? 3, 48, '3', '21004'),
? ? ('31002', '信息系統(tǒng)_分析與設(shè)計', 2, 32, '4', '31001'),
? ? ('31005', '項目管理',? ? ? ? ? ? 3, 48, '5', '31001');
CREATE TABLE tb_stu(
stuNo CHAR(10),
stuName CHAR(20) NOT NULL,
sex CHAR(2),
bir DATE,
native CHAR(20),
nation CHAR(10) DEFAULT '漢',
classNum CHAR(6),
CONSTRAINT PK_stu1 PRIMARY KEY(stuNo),
CONSTRAINT FK_stu2 FOREIGN KEY(classNum) REFERENCES tb_class(classNo)
)ENGINE = InnoDB;
INSERT INTO tb_stu VALUES('2013110101', '張曉勇', '男', '1997-12-11', '山西',? ?'漢',? ?'AC1301'),
?('2013110103', '王一敏', '女', '1996-03-25', '河北',? ?'漢',? ?'AC1301'),
?('2013110201', '江山',? ?'女', '1996-09-17', '內(nèi)蒙古', '錫伯', 'AC1302'),
?('2013110202', '李明',? ?'男', '1997-01-14', '廣西',? ?'壯',? ?'AC1302'),
?('2013310101', '黃菊',? ?'女', '1995-09-30', '北京',? ?'漢',? ?'IS1301'),
?('2013310103', '吳昊',? ?'男', '1995-11-18', '河北',? ?'漢',? ?'IS1301'),
?('2014210101', '劉濤',? ?'男', '1997-04-30', '湖南',? ?'侗',? ?'CS1401'),
?('2014210102', '郭志堅', '男', '1997-02-21', '上海',? ?'漢',? ?'CS1401'),
?('2014310101', '王林',? ?'男', '1996-10-09', '河南',? ?'漢',? ?'IS1401'),
?('2014310102', '李怡然', '女', '1996-12-31', '遼寧',? ?'漢',? ?'IS1401');
CREATE TABLE tb_score(
stuNo CHAR(10),
courseNo CHAR(6),
score FLOAT CHECK(score >= 0 AND score <= 100),
CONSTRAINT PK_score PRIMARY KEY(stuNo, courseNo),
CONSTRAINT FK_score1 FOREIGN KEY(stuNo) REFERENCES tb_stu(stuNo),
CONSTRAINT FK_score2 FOREIGN KEY(courseNo) REFERENCES tb_course(courseNo)
)Engine = InnoDB;
INSERT INTO tb_score VALUES('2013110101', '11003', 90),
? ?('2013110101', '21001', 86),
? ?('2013110103', '11003', 89),
? ?('2013110103', '21001', 88),
? ?('2013110201', '11003', 78),
? ?('2013110201', '21001', 92),
? ?('2013110202', '11003', 82),
? ?('2013110202', '21001', 85),
? ?('2013310101', '21004', 83),
? ?('2013310101', '31002', 68),
? ?('2013310103', '21004', 80),
? ?('2013310103', '31002', 76),
? ?('2014210101', '21002', 93),
? ?('2014210101', '21004', 89),
? ?('2014210102', '21002', 95),
? ?('2014210102', '21004', 88),
? ?('2014310101', '21001', 79),
? ?('2014310101', '21004', 80),
? ?('2014310102', '21001', 91),
? ?('2014310102', '21004', 87);
CREATE TABLE S(
SNO CHAR(5),
SNAME VARCHAR(20) NOT NULL,
STATUS SMALLINT,
CITY VARCHAR(20),
CONSTRAINT PK_s PRIMARY KEY(SNO),
CONSTRAINT UQ_s UNIQUE(SNAME),
CONSTRAINT CK_s CHECK(CITY != 'London' OR STATUS = 20)
)Engine = InnoDB;
CREATE TABLE P(
PNO CHAR(5),
PNAME VARCHAR(15),
COLOR VARCHAR(10) CHECK(COLOR IN('Red', 'Yellow', 'Green', 'Blue')),
WEIGHT FLOAT,
CONSTRAINT PK_p PRIMARY KEY(PNO)
)Engine = InnoDB;
CREATE TABLE SP(
SNO CHAR(5),
PNO CHAR(5),
QTY INT,
CONSTRAINT PK_sp PRIMARY KEY(SNO, PNO),
CONSTRAINT FK_sp1 FOREIGN KEY(SNO) REFERENCES S(SNO),
CONSTRAINT FK_sp2 FOREIGN KEY(PNO) REFERENCES P(PNO)
)Engine = InnoDB;
INSERT INTO S VALUES('S1', 'Smith', 20, 'London'),
? ? ('S2', 'Jones', 10, 'Paris'),
? ? ('S3', 'Blake', 30, 'Paris'),
? ? ('S4', 'Clark', 20, 'London'),
? ? ('S5', 'Adams', 30, 'Athens'),
? ? ('S6', 'Brown', NULL, 'New York');
INSERT INTO P VALUES('P1', 'Nut', 'Red', 12),
? ? ('P2', 'Bolt', 'Green', 17),
? ? ('P3', 'Screw', 'Blue', 17),
? ? ('P4', 'Screw', 'Red', 14),
? ? ('P5', 'Cam', 'Blue', 12),
? ? ('P6', 'Cog', 'Red', 19);
INSERT INTO SP VALUES('S1', 'P1', 200),
? ? ?('S1', 'P4', 700),
? ? ?('S1', 'P5', 400),
? ? ?('S2', 'P1', 200),
? ? ?('S2', 'P2', 200),
? ? ?('S2', 'P3', 500),
? ? ?('S2', 'P4', 600),
? ? ?('S2', 'P5', 400),
? ? ?('S2', 'P6', 800),
? ? ?('S3', 'P3', 200),
? ? ?('S3', 'P4', 500),
? ? ?('S4', 'P2', 300),
? ? ?('S4', 'P5', 300),
? ? ?('S5', 'P1', 100),
? ? ?('S5', 'P6', 200),
? ? ?('S5', 'P2', 100),
? ? ?('S5', 'P3', 200),
? ? ?('S5', 'P5', 400);