mysql: dbs 數據庫系統 bdms 數據庫管理系統 bda 數據庫管理員 db 數據庫 dba經過dbms來操做db! 關係型數據庫和非關係型數據庫 登陸mysql mysql -h主機地址 -u用戶名 -p密碼 查詢全部的數據庫 show databases; 建立數據庫 create database [if not exists ] 數據庫名稱; 刪除數據庫 drop database [if exists ] 數據庫名稱; 結構語言分類 DDL(數據定義語言) create drop alter 建立刪除以及修改數據庫,表,存儲過程,觸發器,索引.... DML(數據操做語言) insert delete update 用來操做數據庫中的數據 DQL(數據查詢語言) select 用來查詢數據庫中的數據 DCL(數據控制語言) grant(受權) revoke(撤銷) TCL(事務控制語言) begin savepoint (設置回滾點) rollback commit grant 查詢 to 用戶名; revoke 查詢 from 用戶名; crud(增刪改查) 建立用戶 create user 用戶名@‘地址’ identified by ‘密碼’; 給用戶受權 01. grant all on *.* to 用戶名; 02. grant all on *.* to 用戶名@‘地址’; 刷新系統權限 flush privileges; 刪除用戶 全部的用戶都存儲在mysql數據庫中的user表中 01. delete from mysql.user where user='t13'; 02. delete from mysql.user where user='t13' and host='localhost'; 邏輯運算符 and && 與 or || 或 not ! 非 USE 切換到指定的數據庫 若是沒有切換數據庫,須要在表名前面加上數據庫名稱! USE mysql; SELECT `host`,`user` FROM `user`; 數據類型 int double 在mysql中使用的是decimal(a,b) a指定指定小數點左邊和右邊能夠存儲的十進制數字的最大個數,最大精度38。 b指定小數點右邊能夠存儲的十進制數字的最大個數。小數位數必須是從 0 到 a之間的值。默認小數位數是 0 在oracle中常常 使用 **** number **** char 固定長度 例子: 性別 是 char類型 長度是10 可是咱們的實際輸入的長度是2, 那麼存儲的時候也是10個空間! 資源浪費 varchar 可變長度 例子: 性別 是 char類型 長度是10 可是咱們的實際輸入的長度是2, 那麼存儲的時候也是2個空間! 日期格式 date yyyy-MM-dd datetime yy-MM-dd hh:mm:ss time hh:mm:ss timestamp 1970到如今 yyyyMMddhhmmss year yyyy 1901 約束類型 主鍵約束 primary key (pk) 用於設置表的主鍵,用來確保該行的惟一性 外鍵 foreign key (fk) 用於創建表與表之間的關係 非空約束 not null 字段不容許爲空 默認約束 default 字段的默認值 惟一約束 unique key(uk) 字段的值是惟一的能夠是null,但只能有一個 自動增加 auto_increment 設置列的自動增加(標識列),一般用於設置主鍵 建立表 若是是關鍵字 那麼使用反引號 `` esc下面的鍵 create table [if not exists] 表名( 字段1 數據類型 [約束,索引,註釋], 字段2 數據類型 [約束,索引,註釋], 字段3 數據類型 [約束,索引,註釋] )[表類型][表字符集][註釋] 有符號類型 和 無符號類型 有符號類型 :能夠取負值 無符號類型:默認是0! 0--類型的長度 ZEROFILL屬性:若是位數不夠,前面用零補齊! 若某數值字段指定了ZEROFILL屬性, 將自動添加UNSIGNED屬性! 建立學生表 CREATE TABLE IF NOT EXISTS student( studentNo INT(4) NOT NULL PRIMARY KEY COMMENT '學號', loginPwd VARCHAR(20) NOT NULL COMMENT '密碼', studentName VARCHAR(50) NOT NULL COMMENT '姓名', sex CHAR(2) NOT NULL DEFAULT'男' COMMENT '性別', gradeID INT(4) UNSIGNED COMMENT '年級編號', phone VARCHAR(50) COMMENT '電話', address VARCHAR(255) DEFAULT'地址不詳' COMMENT '地址', bornDate DATETIME COMMENT '出生日期', email VARCHAR(50) COMMENT '郵箱帳號', identityCard VARCHAR(18) UNIQUE KEY COMMENT '身份證號' )COMMENT='學生表'; 修改表中的數據 -- 修改表名 把 student表名 改爲 stu ALTER TABLE student RENAME AS stu; -- 給表中增長 微信 字段 不爲空 惟一 ALTER TABLE student ADD wechat VARCHAR(20) UNIQUE KEY; -- 修改表中 微信 字段的長度爲50 ALTER TABLE student MODIFY wechat VARCHAR(50); -- 刪除表中 微信 字段 ALTER TABLE student DROP wechat; -- 修改studentName字段的名稱爲 stuName ALTER TABLE student CHANGE `name` stuName VARCHAR(20); 建立subject(科目表) CREATE TABLE IF NOT EXISTS `subject`( subjectNo INT(4) AUTO_INCREMENT PRIMARY KEY COMMENT '課程編號', subjectName VARCHAR(50) COMMENT '課程名稱', classHour INT(4) COMMENT '學時', gradeID INT(4) COMMENT '年級編號' )COMMENT='科目表' CHARSET='utf8'; 遇到的問題 在使用AUTO_INCREMENT 必須和PRIMARY KEY 聯合使用! 標識列 是 自增列! 主鍵是 惟一! 建立年級表 CREATE TABLE IF NOT EXISTS grade( gradeID INT(4) COMMENT '年級編號', gradeName VARCHAR(10) COMMENT '年級名稱' )COMMENT='年級表'; 添加主鍵的語法 ALTER TABLE 表名 ADD CONSTRAINT 主鍵名 PRIMARY KEY 表名(主鍵字段); -- 給年級表中id設置成主鍵 ALTER TABLE grade ADD CONSTRAINT pk_grade_gradeID PRIMARY KEY(gradeID); 建立成績表 CREATE TABLE IF NOT EXISTS result( studentNo INT(4) NOT NULL PRIMARY KEY COMMENT '學號', subjectNo INT(4) NOT NULL COMMENT '課程編號', examDate DATETIME NOT NULL COMMENT '考試日期 ', studentResult INT(4) NOT NULL COMMENT '考試成績' )COMMENT='成績表' charset='utf8' engine=InnoDB; 外鍵的語法: ALTER TABLE 表名 ADD CONSTRAINT 外鍵名 FOREIGN KEY(外鍵字段) REFERENCES 關聯表名(關聯字段); 建立student表和grade表的關係 學生應該屬於某個年級 外鍵必須創建在 從表上! ALTER TABLE student ADD CONSTRAINT fk_student_grade FOREIGN KEY(gradeID) REFERENCES grade(gradeID); 問題: 前提已經創建了 主外鍵關係 若是說有三個年級,編號分別是 1 2 3 那麼也有三個學生 對應的關係是 第1個學生 1年級 第2個學生 2年級 第3個學生 2年級 01.有沒有這種狀況 有個學生的年級編號是4 ?? 主表中沒有數據! 從表沒法建立! 02.可不能夠刪除年級表2年級或者1年級??? 不能刪除!由於從表中還有關聯數據! 03.若是咱們非得刪除年級 怎麼辦?? 先把從表中的關聯數據刪除 ,以後再刪除主表中的數據! 聯合主鍵 將多列設置成主鍵! -- 給成績表設置聯合主鍵 ALTER TABLE result ADD PRIMARY KEY pk_result (studentno,subjectno,examdate); mysql數據庫中經常使用的兩種 存儲 引擎 MyISAM InnoDB 事務處理 不支持 支持 外鍵約束 不支持 支持 全文索引 支持 不支持 使用的場景: MyISAM:不能使用事務,空間小,適合查詢! InnoDB:多適用於增刪改,安全性高!事務的併發處理! -- 查詢當前默認的存儲引擎 SHOW VARIABLES LIKE 'storage_engine%'; -- 修改存儲引擎 -- 找到安裝路徑下面的my.ini文件 -- 加入 default-storage-engine=InnoDB 數據庫表的存儲位置 InnoDB類型的文件 *.frm :表結構定義文件 *.ibd : 數據文件 MyISAM類型的文件 *.frm :表結構定義文件 *.MYD :數據文件 *.MYI :索引文件 DML和DQL 增刪改查 SELECT * FROM grade 新增 insert -- 向年級表中新增3條數據 INSERT INTO grade(gradeID,gradeName) VALUES(4,'4年級'); INSERT INTO grade(gradeID,gradeName) VALUES(5,'5年級'); INSERT INTO grade(gradeID,gradeName) VALUES(6,'6年級'); -- 刪除 456 DELETE FROM grade WHERE gradeID>3; DELETE FROM grade WHERE gradeID=4 OR gradeID=5 OR gradeID=6; DELETE FROM grade WHERE gradeID IN (4,5,6); -- 同時插入多條數據 oracle數據庫不支持 INSERT INTO grade(gradeID,gradeName) VALUES(4,'4年級'),(5,'5年級'),(6,'6年級'); -- 修改gradeID=1的年級名稱爲 one UPDATE grade SET gradeName='one' WHERE gradeID=1 -- delete 刪除表中全部的數據 DELETE FROM grade; delete 和 truncate的區別 01.delete begin (開啓事務) select * from grade;(查詢年級表中全部的數據) delete from grade; (刪除年級表中全部的數據) select * from grade;(查詢年級表中全部的數據,沒有數據) rollback; (事務回滾) select * from grade;(查詢年級表中全部的數據,刪除的數據恢復) commit (提交事務) 02.truncate begin (開啓事務) select * from grade;(查詢年級表中全部的數據) truncate table grade; (刪除年級表中全部的數據) select * from grade;(查詢年級表中全部的數據,沒有數據) rollback; (事務回滾) select * from grade;(查詢年級表中全部的數據,沒有數據) commit (提交事務) 區別: 01.delete後面能夠拼接where條件,刪除指定的行! truncate只能刪除表中全部的數據!不能有where! 02.delete能夠回滾,數據庫能夠恢復! truncate 不能事務混滾,數據不能夠恢復! 03.truncate執行效率高! 事務的特性 ACID 事務:一條或者多條sql語句的集合! 原子性 (Atomicity):在事務中的操做,要麼都執行,要麼都不執行! 一致性(Consistency):事務必須保證數據庫從一個一致性的狀態變成另外一個一致性的狀態! 隔離性(Isolation):每一個事務之間互不干擾!哪怕是併發執行也不干擾! 持久性(Durability):事務一旦被改變,那麼對數據庫中數據的影響是永久性的! 查詢 將查詢結果保存到 新表中! create table newStudent (select stuName,address from student) view (視圖) :不佔物理空間! 使用 具體的列 代替 * select * from student; select stuName,age ,address from student; 使用別名 SELECT gradeID AS 年級編號,gradeName '年級 名稱' FROM grade; 格式 01. 列名 AS 別名 02. 列名 別名 03. 若是別名中有特殊符號,必須把 別名用 單引號 引發來! 查詢年級表中 id不等於1的數據 <> != SELECT gradeID,gradeName FROM grade WHERE gradeid <> 1 + 必須是相同的數據類型,能轉換成2進制的數據! 若是有一個列是null 總體返回null! 咱們一般使用 concat來作合併 SELECT CONCAT(loginPwd,',',studentNAME) AS 合併列 FROM STUDENT 使用is null 的時候 要確保 查詢的列 能夠爲空! null: 01.標識 空值 02.不是0,也不是空串"" 03.只能出如今定義 容許爲null的字段 04.只能使用is null 或者is not null 進行比較! SELECT * FROM student WHERE loginPwd IS NULL 聚合函數 count() 查詢某個字段的行數 max()查詢某個字段的最大值 min()查詢某個字段的最小值 sum()查詢某個字段的和 avg()查詢某個字段的平均值 -- 查詢成績表的總成績 SELECT SUM(studentResult) FROM result; -- 查詢成績的平均值 SELECT AVG(studentResult) FROM result; -- 查詢成績的最高分 SELECT MAX(studentResult) FROM result; -- 查詢成績的最低分 SELECT MIN(studentResult) FROM result; -- 查詢有成績的總數 SELECT COUNT(studentResult) FROM result; 經常使用的字符函數 -- concat(str1,str2...strN) 鏈接字符串 SELECT CONCAT('h','el','lo') FROM DUAL; -- insert(str,begin,length,newStr) 替換字符串 -- str初始的字符串 begin 開始的位置 從1開始 -- length 替換長度 newStr替換的字符串 SELECT INSERT('hello',2,3,'55555') FROM DUAL; -- subString(str,begin,length) 截取字符串 SELECT SUBSTRING('hello',2,3) FROM DUAL; -- lower(str)轉換成小寫 -- upper(str)轉換成大寫 dual 咱們稱之爲 僞表! 在mysql中是一個擺設 select 9*9; select 9*9 from dual; select * from dual; 報錯 oracle中 必須使用 from dual; select 9*9 from dual; 正確的 select 9*9 ; 錯誤 dual是一個只有一行一列的表! 只能查詢! 不能對 dual進行增刪改! 和並列 DROP TABLE IF EXISTS `testa`; CREATE TABLE `testa` ( `name` varchar(20) DEFAULT NULL, `subject` varchar(20) DEFAULT NULL, `score` double DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `testa`(`name`,`subject`,`score`) values ('張三','語文',80),('李四','語文',90),('王五','語文',70),('張三','數學',60),('李四','數學',98),('王五','數學',100); -- 須要成績和科目 在一列 顯示 根據name分組 SELECT `name` AS 姓名, GROUP_CONCAT(`subject`,':',score) AS 成績 FROM testa GROUP BY `name`; -- 經常使用的日期和時間函數 -- 獲取 年月日 SELECT CURDATE() FROM DUAL; -- 獲取 時分秒 SELECT CURTIME() FROM DUAL; -- 獲取 年月日 時分秒 SELECT NOW() FROM DUAL; -- 獲取年份 SELECT YEAR(NOW()) FROM DUAL; SELECT YEAR(CURDATE()) FROM DUAL; -- 獲取小時 SELECT HOUR(NOW()) FROM DUAL; SELECT HOUR(CURTIME()) FROM DUAL; -- 獲取分鐘 SELECT MINUTE(NOW()) FROM DUAL; SELECT MINUTE(CURTIME()) FROM DUAL; -- 獲取當前日期是本年的第幾周 SELECT WEEK(NOW()) FROM DUAL; -- 獲取兩個日期之間的天數 SELECT DATEDIFF(NOW(),'2015-06-01') FROM DUAL; -- 獲取給定日期以後的日期 SELECT ADDDATE(NOW(),30) FROM DUAL; -- 天花板函數 SELECT CEIL(3.0) FROM DUAL; SELECT CEIL(3.1) FROM DUAL; SELECT FLOOR(3.9) FROM DUAL; -- 返回0-1之間的隨機數 SELECT RAND() FROM DUAL; -- 四捨五入 SELECT ROUND(2.4) FROM DUAL; -- 查詢全部年級編號爲1的學員信息,按學號升序排序 SELECT * FROM student WHERE GradeID=1 ORDER BY Studentno ASC; -- 顯示前4條記錄 SELECT * FROM student WHERE GradeID=1 ORDER BY Studentno ASC LIMIT 0,4; -- 每頁4條,顯示第2頁,即從第5條記錄開始顯示4條數據 SELECT * FROM student WHERE GradeID=1 ORDER BY Studentno ASC LIMIT 4,4 -- 子查詢 -- 把一個查詢的結果 當成另外一個查詢的 字段,條件或者表! SELECT studentName FROM student -- 只能經過student 表 查詢出 學生對應的 年級名稱 -- 01. 先查詢出 學生 武松 對應的 年級編號 SELECT GradeID FROM student WHERE studentName='武松' -- 02.根據年級編號 取 年級名稱 SELECT gradeName FROM grade WHERE GradeID=??? SELECT gradeName FROM grade WHERE GradeID =(SELECT GradeID FROM student WHERE studentName='武松') -- 查詢年級編號是1或者2 的 全部學生列表 SELECT * FROM student WHERE gradeId IN(1,2) -- 查詢 年級名稱是 大一或者大二的全部學生信息 -- 學生表 中沒有 年級名稱 可是有年級編號 -- 01.根據 年級名稱 查詢出 編號 SELECT gradeID FROM grade WHERE gradeName IN('大一','大二'); -- 02.再根據id查詢學生信息 SELECT * FROM student WHERE gradeID IN (SELECT gradeID FROM grade WHERE gradeName IN('大一','大二')) -- 查詢參加 最近一次 高等數學-1 考試成績的學生的最高分和最低分 -- 01. 發現成績表中 沒有 科目名稱 只有編號!根據名稱取編號 SELECT SubjectNo FROM `subject` WHERE subjectName='高等數學-1' -- 02.查詢最近一次 高等數學-1 考試的時間 SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT SubjectNo FROM `subject` WHERE subjectName='高等數學-1') -- 全部最近考試的成績 SELECT * FROM result WHERE ExamDate='2013-11-11 16:00:00' -- 03.開始獲取最高分和 最低分 SELECT MAX(studentResult) AS 最高分, MIN(studentResult) AS 最低分 FROM result WHERE SubjectNo=(SELECT SubjectNo FROM `subject` WHERE subjectName='高等數學-1') AND ExamDate= (SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT SubjectNo FROM `subject` WHERE subjectName='高等數學-1')) -- 查詢 高等數學-1 考試成績是 60 分的 學生信息 -- 01.根據 科目名稱 獲取 科目編號 SELECT SubjectNo FROM `subject` WHERE SubjectName='高等數學-1' -- 02.根據編號 查詢 全部的學生編號 SELECT studentNo FROM result WHERE SubjectNo=(SELECT SubjectNo FROM `subject` WHERE SubjectName='高等數學-1') AND StudentResult=60; -- 成績=60 -- 03.查詢學生信息 SELECT * FROM student WHERE studentNo IN (SELECT studentNo FROM result WHERE SubjectNo=(SELECT SubjectNo FROM `subject` WHERE SubjectName='高等數學-1') AND StudentResult=60) -- 使用in替換 等於(=)的子查詢語句! -- in後面的子查詢能夠返回多條記錄! -- not in :不在某個範圍以內 -- 查詢未參加 「高等數學-1」 課程最近一次考試的在讀學生名單 -- 01.根據 科目名稱 獲取 科目編號 SELECT SubjectNo FROM `subject` WHERE SubjectName='高等數學-1' -- 02.獲取最近一次考試時間 SELECT MAX(ExamDate) FROM result WHERE SubjectNo= (SELECT SubjectNo FROM `subject` WHERE SubjectName='高等數學-1') -- 03.查詢沒參加的學生編號 SELECT studentNo,StudentName FROM student WHERE studentNo NOT IN ( SELECT StudentNo FROM result WHERE SubjectNo= (SELECT SubjectNo FROM `subject` WHERE SubjectName='高等數學-1') AND ExamDate= (SELECT MAX(ExamDate) FROM result WHERE SubjectNo= (SELECT SubjectNo FROM `subject` WHERE SubjectName='高等數學-1')) ) 高級查詢 SELECT * FROM `grade`INNER JOIN `student` 笛卡爾積 :兩個表數據的乘積! 兩個表的內鏈接 SELECT * FROM `grade`INNER JOIN `student` ON grade.`GradeID`=student.`GradeId` on 兩個表經過那一列創建關聯關係 -- exists的使用 -- 01. 用於檢測表,數據庫等等 是否存在 -- 02. 檢查子查詢中是否會返回一行數據!其實子查詢並不返回任何數據! 值返回 true或者false! SELECT * FROM Student WHERE EXISTS(SELECT NULL) SELECT * FROM Student WHERE EXISTS(SELECT 9*9) SELECT * FROM Student WHERE EXISTS(SELECT StudentName FROM student) SELECT * FROM Student WHERE EXISTS(SELECT studentName FROM Student WHERE studentName='張三') SELECT * FROM Student WHERE studentName IN(SELECT studentName FROM Student) -- in 效果等同於 =any SELECT * FROM Student WHERE studentName =ANY(SELECT studentName FROM Student) -- all 大於子查詢語句中的 最大值 >(1,2,3) >3 SELECT * FROM student WHERE studentNo>ALL (SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005)) -- any 大於子查詢語句中的 最小值 >(1,2,3) >1 SELECT * FROM student WHERE studentNo>ANY (SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005)) -- some 和any功能同樣 SELECT * FROM student WHERE studentNo>SOME (SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005)) -- 檢查「高等數學-1」 課程最近一次考試成績 -- 若是有 80分以上的成績,顯示分數排在前5名的學員學號和分數 -- 不使用exists -- 01.查詢「高等數學-1」 課程 對應的編號 SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' -- 02.查詢最近的考試成績 SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') -- 03. 在02的基礎上 加條件 成績大於80 SELECT * FROM result WHERE ExamDate= (SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1')) AND StudentResult>80 -- 04.優化 SELECT studentNo,StudentResult FROM result WHERE ExamDate= (SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1')) AND StudentResult>80 ORDER BY StudentResult DESC LIMIT 0,5 -- 使用exists -- 檢查「高等數學-1」 課程最近一次考試成績 -- 若是有 80分以上的成績,顯示分數排在前5名的學員學號和分數 -- 01.查詢「高等數學-1」 課程 對應的編號 SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' -- 02.查詢最近的考試成績 SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') -- 03.查詢學號和成績 SELECT StudentNo,StudentResult FROM result WHERE EXISTS ( SELECT * FROM result WHERE subjectNo=( SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' ) AND ExamDate=( SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') ) AND StudentResult>80 ) AND subjectNo=( SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' ) AND ExamDate=( SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') ) ORDER BY StudentResult DESC LIMIT 0,5 -- not exists -- 檢查「高等數學-1」課程最近一次考試成績 -- 若是所有未經過考試(60分及格),認爲本次考試偏難,計算的該次考試平均分加5分 -- 01.查詢「高等數學-1」 課程 對應的編號 SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' -- 02.查詢最近的考試成績 SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') -- 03.查詢成績大於60的 反着來 SELECT StudentResult FROM result WHERE StudentResult>60 AND SubjectNo=( SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' ) AND ExamDate=( SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') ) -- 04. 若是所有未經過考試,考試平均分加5分 SELECT AVG(StudentResult)+5 FROM result WHERE NOT EXISTS ( SELECT StudentResult FROM result WHERE StudentResult>60 AND SubjectNo=( SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' ) AND ExamDate=( SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') ) ) AND SubjectNo=( SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1' ) AND ExamDate=( SELECT MAX(ExamDate) FROM result WHERE SubjectNo=(SELECT subjectNo FROM `subject` WHERE SubjectName='高等數學-1') ) -- 若是有 年級名稱是大二 的學生,就 查詢出 年級名稱是大一的 全部學生信息 -- 01.先查詢出 對應的年級編號 SELECT GradeId FROM grade WHERE GradeName='大一' SELECT GradeId FROM grade WHERE GradeName='大二' -- 02.在學生表中是否存在 年級名稱是大二 的學生 SELECT * FROM student WHERE gradeID=( SELECT GradeId FROM grade WHERE GradeName='大二' ) -- 03.若是有查詢出 年級名稱是大一的 全部學生信息 SELECT * FROM student WHERE EXISTS ( SELECT * FROM student WHERE gradeID=( SELECT GradeId FROM grade WHERE GradeName='大二' ) ) AND GradeId=( SELECT GradeId FROM grade WHERE GradeName='大一' ) -- 使用子查詢的注意事項 -- 01.任何容許使用表達式的地方均可以使用子查詢 -- 02.只出如今子查詢中可是沒有在父查詢中出現的列,結果集中的列不能包含! sql優化 使用exists 代替 in 使用not exists 代替not in exists 只返回true或者false.不返回結果集 in 返回結果集 -- 查詢姓李的學生信息 % 表明0或者多個字符 _表明一個字符 SELECT * FROM student WHERE StudentName LIKE '李%' SELECT * FROM student WHERE StudentName LIKE '李_' -- 使用in完成上述代碼 SELECT * FROM student WHERE StudentName IN( SELECT studentName FROM student WHERE StudentName LIKE '李%') -- in(多條數據--》返回結果集) -- 使用exists替換 SELECT * FROM student WHERE EXISTS( SELECT studentName FROM student) AND StudentName LIKE '李%' -- exists(有沒有數據) -- 統計每門課程平均分各是多少 GROUP BY 列名 分組 SELECT subjectno,AVG(studentresult) FROM result GROUP BY subjectno -- 查詢出課程平均分大於60的課程編號 和 平均分 SELECT subjectno,AVG(studentresult) FROM result GROUP BY subjectno HAVING AVG(studentresult)>60 -- 分組以後的條件 -- 統計每門課程平均分各是多少 降序排列 SELECT subjectno,AVG(studentresult) FROM result GROUP BY subjectno ORDER BY AVG(studentresult) DESC -- 若是成績相同 再按照 課程編號 升序排序 SELECT subjectno,AVG(studentresult) FROM result GROUP BY subjectno ORDER BY AVG(studentresult) DESC,subjectno -- 分組統計每一個年級的 男女人數 SELECT gradeid 年級編號,sex 性別,COUNT(sex) 人數 FROM student GROUP BY gradeid,sex -- 建立表 CREATE TABLE IF NOT EXISTS examTest( id INT(2) NOT NULL, sex VARCHAR(20) ) -- 同時新增多條數據 INSERT INTO examTest VALUES(1,'男'),(2,'男'),(3,'女'),(4,NULL); SELECT sex AS '性別',COUNT(sex) AS '人數' FROM examTest WHERE sex IS NOT NULL GROUP BY sex ORDER BY COUNT(sex) DESC SELECT sex AS '性別',COUNT(sex) AS '人數' FROM examTest GROUP BY sex HAVING sex IS NOT NULL ORDER BY COUNT(sex) DESC SELECT sex AS '性別',COUNT(sex) AS '人數' FROM examTest WHERE sex IN('男','女') GROUP BY sex ORDER BY COUNT(sex) DESC -- 建立表 CREATE TABLE IF NOT EXISTS mytable( `name` VARCHAR(10) NOT NULL, class INT(4) NOT NULL, sorce DOUBLE NOT NULL ) -- 插入數據 INSERT INTO mytable VALUES ('小黑1',1,88),('小黑2',1,80), ('小黑3',1,68),('小黑4',1,70), ('小黑5',1,98),('小黑6',1,90), ('小白1',2,88),('小白2',2,80), ('小白3',2,68),('小白4',2,70), ('小白5',2,98),('小白6',2,90) -- 找出表中分數的前三名 SELECT * FROM mytable ORDER BY sorce DESC LIMIT 0,3 -- 找出每一個班級的前三名 SELECT * FROM mytable t1 WHERE ( SELECT COUNT(1) FROM mytable t2 WHERE t1.`sorce`<t2.`sorce` AND t1.class=t2.`class` )<3 ORDER BY class,sorce DESC 內鏈接 :經過匹配兩個表中公共列,找到 公共的行! 左外鏈接: 以左表爲準,右表中沒有數據返回null 右外鏈接: 以右表爲準,左表中沒有數據返回null -- 輸出學生姓名以及對應的年級名稱 內鏈接 SELECT StudentName,GradeName FROM student INNER JOIN grade ON student.`GradeId`=grade.`GradeID` -- 隱式內鏈接 SELECT StudentName,GradeName FROM student,grade WHERE student.`GradeId`=grade.`GradeID` -- 查詢 考試 課程編號是1的 學生姓名 以及年級名稱 和科目名稱以及成績 01. SELECT s.StudentName,GradeName,SubjectName ,studentResult FROM student s INNER JOIN grade g ON (s.gradeID=g.gradeID) INNER JOIN `subject` b ON(g.gradeID=b.gradeID) INNER JOIN result r ON (b.subjectNo=r.subjectNo) AND s.studentNo=r.studentNo AND b.subjectNo=1 02. SELECT StudentName,GradeName,SubjectName ,studentResult FROM student s,grade g,`subject` b,result r WHERE s.gradeID=g.gradeID AND g.gradeID=b.gradeID AND s.studentNo=r.studentNo AND b.subjectNo=r.subjectNo AND b.subjectNo=1 -- 查詢的列 不在同一個表中! 必須使用鏈接查詢!創建關聯關係! -- 臨時表只有當前鏈接可見 隨鏈接的關閉 自動刪除 -- 臨時表的增刪改 不會影響到 真表 CREATE TEMPORARY TABLE myStudent (SELECT * FROM student) SELECT * FROM myStudent DELETE FROM mystudent -- 臨時表的數據刪除 SELECT * FROM student -- 不會影響到真表 自鏈接 -- 自鏈接 把一個表當成多個表來使用 關鍵是 使用別名 SELECT * FROM teacher -- 查詢 老師3 的姓名和 對應的 導師的姓名 -- t1 老師 t2 導師 老師的導師編號=== 導師的編號 SELECT t1.`name` AS a,t2.`name` AS 導師姓名 FROM teacher t1,teacher t2 WHERE t1.`name`='老師3' AND t2.id=t1.tid 事務 事務的特性 ACID 事務:一條或者多條sql語句的集合! 原子性 (Atomicity):在事務中的操做,要麼都執行,要麼都不執行! 一致性(Consistency):事務必須保證數據庫從一個一致性的狀態變成另外一個一致性的狀態! 隔離性(Isolation):每一個事務之間互不干擾!哪怕是併發執行也不干擾! 持久性(Durability):事務一旦被改變,那麼對數據庫中數據的影響是永久性的! 模擬 銀行轉帳! -- 建立數據庫 CREATE DATABASE myBank; -- 切換指定的數據庫 USE myBank; -- 建立表 CREATE TABLE IF NOT EXISTS bank( customerName VARCHAR(10) NOT NULL COMMENT '用戶名', currentMoney DECIMAL(10,2) NOT NULL COMMENT '帳戶餘額' ); -- 插入數據 INSERT INTO bank VALUES('小黑',50000),('小白',500000); -- 小黑 給小白 轉帳10000 -- 修改兩條數據 -- 01.小黑-10000 -- 02.小白+10000 UPDATE bank SET currentMoney=currentMoney-10000 WHERE customerName='小黑'; -- 故意寫錯字段名稱 讓02 報錯 UPDATE bank SET currentMoneysss=currentMoney+10000 WHERE customerName='小白'; -- 開啓事務 START TRANSACTION 或者 BEGIN -- 01.02 爲一個事務 BEGIN UPDATE bank SET currentMoney=currentMoney-10000 WHERE customerName='小黑'; UPDATE bank SET currentMoneysss=currentMoney+10000 WHERE customerName='小白'; -- 事務回滾 ROLLBACK -- 提交事務 COMMIT UPDATE bank SET currentMoney=500000 WHERE customerName='小黑'; -- 證實mysql是默認提交事務的! SET autocommit=0(關閉事務自動提交) | 1(開啓事務自動提交) -- 關閉事務自動提交 SET autocommit=0; BEGIN; -- 開啓事務 UPDATE bank SET currentMoney=currentMoney-10000 WHERE customerName='小黑'; UPDATE bank SET currentMoney=currentMoney+10000 WHERE customerName='小白'; COMMIT; -- 手動提交事務 UPDATE bank SET currentMoney=10000; ROLLBACK; -- 事務回滾 SET autocommit=1; -- 恢復自動提交 事務的隔離級別 爲何 引入了 事務隔離級別?? 在數據庫操做中,爲了有效保證併發讀取數據的正確性,提出的事務隔離級別。 更新丟失 兩個事務都同時更新一行數據,一個事務對數據的更新把另外一個事務對數據的更新覆蓋了。這是由於系統沒有執行任何的鎖操做,所以併發事務並無被隔離開來。 髒讀 一個事務讀取到了另外一個事務未提交的數據操做結果。這是至關危險的,由於極可能全部的操做都被回滾。 不可重複讀 不可重複讀(Non-repeatable Reads):一個事務對同一行數據重複讀取兩次,可是卻獲得了不一樣的結果。 包括如下狀況: (1)虛讀:事務T1讀取某一數據後,事務T2對其作了修改,當事務T1再次讀該數據時獲得與前一次不一樣的值。 (2) 幻讀(Phantom Reads):事務在操做過程當中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據或者缺乏了第一次查詢中出現的數據(這裏並不要求兩次查詢的SQL語句相同)。這是由於在兩次查詢過程當中有另一個事務插入數據形成的。 解決方案: 使用事務隔離級別 案例一: 容許髒讀取 -- 查詢mysql默認的事務隔離級別 (可重複讀取 repeatable-read ) SELECT @@tx_isolation; -- 修改事務 隔離級別 SET tx_isolation='read-uncommitted'; 容許髒讀取,不容許更新丟失 案例二: 禁止更新丟失 在doc窗口中 bengin update 一張表的數據 不回滾 也不 提交 在 sqlyong中 操做同一張表,發現不容許,在等待! 未受權讀取 也稱爲讀未提交(Read Uncommitted):容許髒讀取,但不容許更新丟失。若是一個事務已經開始寫數據,則另一個事務則不容許同時進行寫操做,但容許其餘事務讀此行數據。該隔離級別能夠經過「排他寫鎖」實現。 受權讀取 也稱爲讀提交(Read Committed):容許不可重複讀取,但不容許髒讀取。這能夠經過「瞬間共享讀鎖」和「排他寫鎖」實現。讀取數據的事務容許其餘事務繼續訪問該行數據,可是未提交的寫事務將會禁止其餘事務訪問該行。 可重複讀取(Repeatable Read) 可重複讀取(Repeatable Read):禁止不可重複讀取和髒讀取,可是有時可能出現幻讀數據。這能夠經過「共享讀鎖」和「排他寫鎖」實現。讀取數據的事務將會禁止寫事務(但容許讀事務),寫事務則禁止任何其餘事務。 序列化(Serializable) 序列化(Serializable):提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接着一個地執行,不能併發執行。僅僅經過「行級鎖」是沒法實現事務序列化的,必須經過其餘機制保證新插入的數據不會被剛執行查詢操做的事務訪問到。 隔離級別越高,越能保證數據的完整性和一致性,可是對併發性能的影響也越大。對於多數應用程序,能夠優先考慮把數據庫系統的隔離級別設爲Read Committed。它可以避免髒讀取,並且具備較好的併發性能。儘管它會致使不可重複讀、幻讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,能夠由應用程序採用悲觀鎖或樂觀鎖來控制。 博文鏈接 :http://lvwenwen.iteye.com/blog/2045951 視圖: -- 視圖 是一張虛擬的表 01.表示一張表的部分數據或者是多張表的綜合數據! 02.結構和數據都是創建在對真表的查詢基礎之上的! 03.視圖中存放的數據其實就是對真實表的引用! 對視圖中的數據進行添加,更新刪除都會影響到真實的表! 04.一個真實的表能夠建立N個視圖! 05.若是視圖關聯了多表,不容許增 刪!單表能夠增刪改 06.視圖通常都是使用查詢! -- 建立一個視圖 只獲取 學生姓名 編號 以及考試成績 CREATE VIEW view_student_result AS SELECT s.studentNo 學生編號,studentName 學生姓名, studentResult 考試成績 FROM student s,result r WHERE s.`studentNo`=r.`studentNo` -- 查詢視圖中的內容 SELECT * FROM view_student_result -- 查詢mysql數據庫中全部的視圖 SELECT * FROM information_schema.views; -- 刪除視圖 DROP VIEW view_student_result; -- 建立一個表的視圖 學生姓名,地址,手機號 CREATE VIEW view_student AS SELECT studentName 學生姓名,address 地址,phone 手機號 FROM student -- 查詢視圖 SELECT * FROM view_student -- 索引:是一種有效組合數據的方式!目的就是快速或者某個記錄! 提升了數據庫的檢索速度! mysql索引按存儲類型分2種: 01.B-樹索引(BTREE):INNODB,MyISAM 支持 02.哈希索引 01.普通索引:容許在定義爲索引的列中 出現 重複值和空值! 02.惟一索引:索引列不容許出現重複值,可是能夠出現一個空值! 03.主鍵索引:建立主鍵的時候,系統會默認建立一個主鍵索引!惟一!不能爲空! 04.複合索引:將咱們的多個列組合起來!(name,sid)姓名和身份證號! 05.全文索引:容許值的全文查詢!容許空值和重複值!適合在一個內容比較多的列!text! 06.空間索引:對空間數據類型的列創建的索引! -- 查詢指定表的索引 SHOW INDEX FROM student; TABLE:索引所在的表 Non_unique:索引是否惟一 0:惟一 1:不惟一 key_name:索引名稱 seq_in_index:該列在索引中的位置 column_name:定義所用的列名稱 null:該列是否爲空 index_type:索引類型 -- 給姓名增長 普通索引 CREATE INDEX index_studentName ON student(studentName); -- 給學生姓名和身份證號 增長 組合索引 CREATE INDEX index_name_sid ON student(studentName,identityCard) -- 刪除索引 DROP INDEX index_name_sid ON student; DROP INDEX index_studentName ON student; -- 建立索引的原則 01.常常被查詢的列 02.常常用做選擇的列 03.常常排序,分組的列 04.常常用做鏈接的列(主鍵/外鍵) 使用索引時的注意事項: 01.查詢時減小使用*返回所有的列,不要返回不須要的列! 02.索引儘可能要少,在字節數小的列上創建索引! 03.where字句中有多個條件表達式的時候,包含索引的列要放在其餘表達式以前! 04.在order by的字句中避免使用表達式! sql 語句的執行 順序 5.查詢 select 1.找表 from 2.條件 where 3.分組 group by 4.條件 having 6.排序 order by 7.分頁 limit 數據庫的恢復和備份 爲保證帳戶密碼安全,命令中可不寫密碼,但參數「-p」必須有,回車後根據提示寫密碼! 數據庫的備份 cmd進入命令行 mysqldump -u用戶名 -p 數據庫名稱 >指定的文件 數據庫的恢復 前提是必需要有對應的數據庫 mysql -u用戶名 -p <指定的文件 1. mysql爲DOS命令 2.在執行該語句以前,必須在MySQL服務器中建立新數據庫,若是不存在恢復數據庫過程將會出錯 軟件項目開發週期中數據庫設計 01.需求分析階段:分析客戶的業務和數據處理需求 02.概要設計階段:設計數據庫的E-R模型圖,確認需求信息的正確和完整 03.詳細設計階段:應用三大範式審覈數據庫結構 04.代碼編寫階段:物理實現數據庫,編碼實現應用 05.軟件測試階段:…… 06.安裝部署:…… 數據庫設計步驟: 01.收集信息 02.標識實體 03.標識每一個實體的屬性 04.標識實體之間的關係 E-R圖: 01.矩形 實體 02.橢圓形 屬性 03.菱形 實體與實體的關係 1 : 一對一 1:N: 一對多 M:N: 多對多 必須知足 三大範式 第一範式確保每列的原子性 第二範式要求每一個表只描述一件事情 第三範式要求表中各列必須和主鍵直接相關,不能間接相關