MySQL
一、引言
1.1 現有的數據存儲方式有哪些?
- Java中存儲數據(變量、對象、數組、集合),數據都是保存在內存中,屬於瞬時狀態數據
- 文件(File)存儲數據,保存在硬盤上,屬於持久化狀態存儲
1.2 以上存儲方式存在哪些缺點?
- 程序停止,數據就沒了。
- 文件存儲的數據:沒有數據類型的區分
- 沒有訪問安全限制
- 沒有備份、恢復機制。
二、 數據庫
2.1 概念
數據庫是 “按照數據結構來組織、存儲、管理數據的倉庫”。是一個可以長期存儲在計算機內的、有組織的、有共享的、可以統一管理的數據集合
2.2 數據庫的分類
- 網狀結構數據庫:以節點形式存儲數據和訪問數據
- 層次結構數據庫:IBM[IMS]。定向有序的樹狀結構實現存儲和訪問。
關係結構數據庫
:Oracle、MySQL、DB2、SQL Server,以表格(Table)形式存儲,多表之間建立關聯關係,通過分類、合併、連接、選取等方式實現訪問。- 非關係型數據庫:MongDB、Redis,使用哈希表,表中以鍵值(key-value)的方式實現特定的鍵和一個指針指向的特定數據
- ElastecSearch
三、數據庫管理系統
3.1 概念
數據庫管理系統:指的是一種操作和管理數據庫的大型軟件,用於建立、使用、維護數據庫,對數據庫進行統一的管理和控制,保證數據庫的安全性和完整性。
用戶通過數據庫管理系統訪問數據庫中的數據
3.2 常見的數據庫管理系統
- Oracle:可以運行在UNIX、Windows等主流操作系統,支持所有的工業標準,並獲得了最高級別的ISO標準安全性認證。
- DB2:IBM公司的,滿足中大公司的需要
- SQL Server:微軟退出的。
- SQLLite:手機端的數據庫
- Mysql:免費、適合中小型企業
四、MySQL
4.1 簡介
MySQL是一個關係型數據庫管理系統,由瑞典MySQL AB公司開發的。屬於Oracle旗下的產品。
MySQL是最流行的關係型數據庫管理系統之一,在WEB應用方面,是最好的應用軟件之一。
4.2 訪問與下載
官網:https://www.mysql.com
4.3 配置環境變量
- Windows:
- 創建MYSQL_HOME:C:\Program Files\MySQL\MySQL Server 5.7
- 追加Path:%MYSQL_HOME%\bin;
4.4 MySQL的目錄結構
核心文件介紹
文件夾名稱 | 內容 |
---|---|
bin | 命令相關文件 |
include | 頭文件 |
lib | 庫文件 |
Share | 字符集、語言等信息 |
4.5 MySQL配置文件
在MySQL安裝目錄中找到my.ini的文件,MySQL的一些配置參數
參數 | 描述 |
---|---|
default-character-set | 客戶端默認字符集 |
character-set-server | 服務端默認字符集 |
port | 客戶端和服務端的端口號 |
default-storage-engine | MySQL的默認存儲引擎INNODB |
五、 SQL
5.1 概念
SQL:結構化查詢語言,用於存取數據、更新、查詢和管理關係數據庫系統的程序設計語言。
5.2 MySQL應用
對於數據庫的操作,需要在連接MySQL的環境下進行指令輸入,並在一行指令的末尾使用 ; 結束
5.3 基本命令
查看MySQL中所有數據庫
#連接到MySQL
mysql> SHOW DATABASES; #顯示當前MySQL中所有的數據庫
創建自定義數據庫
CREATE DATABASE
mysql>CREATE DATABASE nn2002; #創建了名稱爲nn2002的數據庫
mysql>CREATE DATABASE NN2002 CHARACTER SET gbk;#創建數據庫並設置其默認字符集爲GBK
mysql>CREATE DATABASE NN2002 CHARACTER SET GBK COLLATE gbk_chinese_ci;#支持簡體中文和繁體中文
mysql>CREATE DATABASE IF NOT EXISTS NN2002;#如果NN2002不存在,則創建,反之,不創建
刪除數據庫
DROP DATABASE
mysql>DROP DATABASE NN2002;#刪除數據庫
查看數據庫創建信息
SHOW CREATE DATABASE
mysql>SHOW CREATE DATABASE NN2002;# 查看創建數據庫時的基本信息
修改數據庫
ALTER DATABASE
mysql>ALTER DATABASE NN2002 CHARACTER SET UTF8;#修改數據庫nn2002的字符集爲utf-8
使用數據庫
USE
mysql>USE NN2002;#當前環境下,操作NN2002數據庫
查看當前使用的數據庫
SELECT DATABASE();
mysql>SELECT DATABASE();#查看當前使用的數據庫
六、客戶端工具
6.1 Navicat
是一套快速、可靠並且價格便宜的數據庫管理工具,專爲簡化數據庫管理及降低系統管理成本而設。
6.2 SQLyog
也擁有圖形化界面。擁有廣泛的預定義工具和查詢、友好的視覺界面。類似Excel的查詢結果編輯界面
6.3 DataGrip(Idea開發工具集成)
捷克公司的產品。需要付費。如果買了idea,DataGrip通用
七、 執行SQL腳本
創建一個companyDB的數據庫,然後在對象瀏覽器區,右鍵->執行SQL腳本->找到文件,打開->點擊執行
八、 數據查詢【重點】
8.1 數據表的基本結構
關係結構數據庫是以表格(Table)進行數據存儲,表格由
行
和列
組成
8.2 基本查詢
關鍵字 | 描述 |
---|---|
SELECT | 指定要查詢的列 |
FROM | 指定要查詢的表 |
8.2.1 查詢所有列
#查詢t_employees表中所有員工的所有信息
SELECT * FROM t_employees;
SELECT 所有的列名 FROM t_employees;
8.2.2 查詢部分列
#查詢表中的所有員工的編號、姓氏、郵箱
SELECT EMPLOYEE_ID,FIRST_NAME,Email FROM t_employees;
#查詢表中所有員工的編號、部門編號
SELECT EMPLOYEE_ID,DEPARTMENT_ID FROM t_employees;
8.2.3 對列中的數據進行運算
#查詢員工表中所有員工的編號、姓名、年薪
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY * 13 FROM t_employees;
算術運算符 | 描述 |
---|---|
+ | 列與列之間做加法運算 |
- | 列與列之間做減法運算 |
* | 列與列之間做乘法運算 |
/ | 列與列之間做除法運算 |
8.2.4 列的別名
列 AS ‘列名’
#查詢員工表中所有員工的編號、姓名、日薪(列的運算 / 22),列名均爲中文
SELECT EMPLOYEE_ID AS '編號',FIRST_NAME AS '姓',LAST_NAME AS '名',SALARY / 22 AS'日薪' FROM t_employees;
#起別名,沒有對原表的列名發生影響
8.2.5 查詢結果去重
distinct 列名
#查詢員工表中,所有經理的ID編號
SELECT DISTINCT MANAGER_ID AS '經理編號' FROM t_employees;
#查詢員工表中,所有的工資 (去掉重複的)
SELECT DISTINCT SALARY FROM t_employees;
8.3 排序查詢
語法: SELECT 列名 FROM 表名 ORDER BY 排序列名 [排序規則]
排序規則 | 描述 |
---|---|
ASC | 做升序排序 |
DESC | 做降序排序 |
8.3.1 依據單列進行排序
#查詢員工的編號,名字,薪資,按照工資進行升序排序
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees ORDER BY salary ASC;
#查詢員工的編號,名字,薪資,按照姓名進行升序排序
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees ORDER BY FIRST_NAME ASC;
#查詢員工的編號,名字,薪資,按照工資進行降序排序
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees ORDER BY salary DESC;
8.3.2 依據多列進行排序
#查詢員工編號,名字,薪資,按照工資進行升序排序,如果工資相等,按照編號降序排序
SELECT EMPLOYEE_ID,FIRST_NAME,SALARY FROM t_employees
ORDER BY SALARY ASC,EMPLOYEE_ID DESC
#查詢員工編號,名字,薪資,按照工資進行升序排序,如果工資相等,按照姓名降序排序
SELECT EMPLOYEE_ID,FIRST_NAME,SALARY FROM t_employees
ORDER BY SALARY ASC,FIRST_NAME DESC
8.4 條件查詢
語法: SELECT 列名 FROM 表名 WHERE 條件
關鍵字 | 描述 |
---|---|
WHERE | 在查詢結果中,篩選符合條件的查詢結果。條件爲布爾表達式 |
8.4.1 等值判斷(=)
#查詢工資爲2500的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,SALARY FROM t_employees WHERE salary = 2500;
#查詢姓爲Steven的
SELECT EMPLOYEE_ID,FIRST_NAME,SALARY FROM t_employees WHERE FIRST_NAME='Steven';
8.4.2 不等值判斷(>、<、>=、<=、!=、<>)
#查詢員工工資大於6000的員工的信息
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE salary>=6000;
#查詢員工工資不等於2500的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE salary<>2500;(!=同理)
8.4.3 邏輯判斷(and、or、not)
#查詢員工工資在6000~10000的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE salary>=6000 AND salary<=10000;
#查詢工資是10000的或者是9000的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE salary =10000 OR salary = 9000;
#查詢除了工資是10000的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE NOT salary =10000;
8.4.4 區間判斷(between and)
#區間判斷 包含區間邊界的兩個值
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE salary BETWEEN 6000 AND 10000;
8.4.5 NULL值判斷(IS NULL、IS NOT NULL)
- IS NULL
- 列名 IS NULL
- IS NOT NULL
- 列名 IS NOT NULL
#查詢出 沒有經理編號的員工 IS NULL
SELECT EMPLOYEE_ID,FIRST_NAME,MANAGER_ID FROM t_employees
WHERE MANAGER_ID IS NULL;
#查詢出 沒有經理編號以外的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,MANAGER_ID FROM t_employees
WHERE MANAGER_ID IS NOT NULL;
#查詢出 沒有經理編號以外的員工信息(此處NOT爲取反。兩個結果)
SELECT EMPLOYEE_ID,FIRST_NAME,MANAGER_ID FROM t_employees
WHERE NOT MANAGER_ID IS NULL;
8.4.6 枚舉查詢(IN (值1,值2,值n…))
#枚舉查詢 IN (值1,值2,值n...)
#查詢部門編號爲70,80,90的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,DEPARTMENT_ID FROM t_employees
WHERE DEPARTMENT_ID IN(70,80,90);
#枚舉查詢 查詢經理編號爲 124 和100的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,MANAGER_ID FROM t_employees
WHERE MANAGER_ID IN(124,100);
8.4.7 模糊查詢(_、%)
- LIKE
- LIKE _(單個任意字符)
- 列名 LIKE ‘S_’
- LIKE %(任意長度的任意字符 0~n個)
- 列名 LIKE ‘S%’
#模糊查詢,查詢姓氏以S開頭且長度爲6的員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME FROM t_employees
WHERE FIRST_NAME LIKE 'S_____';
#模糊查詢,查詢姓氏以S開頭任意長度的所有員工信息
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME FROM t_employees
WHERE FIRST_NAME LIKE 'S%';
8.4.8 分支結構查詢
CASE
WHEN 條件1 THEN 結果1
WHEN 條件2 THEN 結果2
WHEN 條件3 THEN 結果3
WHEN 條件4 THEN 結果4
ELSE 結果
END
#查詢員工信息(編號、名字、薪資、薪資級別<條件表達式>)
SELECT EMPLOYEE_ID,FIRST_NAME,salary,
CASE
WHEN salary >=10000 THEN 'A'
WHEN salary >=8000 AND salary<10000 THEN 'B'
WHEN salary >=6000 AND salary<8000 THEN 'C'
WHEN salary >=4000 AND salary <6000 THEN 'D'
ELSE 'E'
END AS '薪資級別'
FROM t_employees;
8.5 時間查詢
語法: SELECT 時間函數([參數列表]);
時間函數 | 描述 |
---|---|
SYSDATE() | 當前系統時間(年、月、日、時、分、秒) |
CURDATE() | 獲得當前日期 |
CURTIME() | 獲得當前時間 |
WEEK(DATE) | 獲得指定日期是一年中第幾周 |
YEAR(DATE) | 獲得指定日期的年份 |
MONTH(DATE) | 獲得指定日期的月份 |
DAY(DATE) | 獲得指定日期的天 |
HOUR(DATE) | 獲得指定時間的小時值 |
MINUTE(DATE) | 獲得指定時間的分鐘值 |
SECOND(DATE) | 獲得指定日期的秒值 |
DATEDIFF(DATE1,DATE2) | 獲得DATE1和DATE2之間相隔的天數 |
ADDDATE(DATE,N) | 在指定日期加上N天后的日期 |
8.5.1 獲取時間
#1.當前系統時間
SELECT SYSDATE();
#2.獲得當前日期
SELECT CURDATE();
#3.獲得當前時間
SELECT CURTIME();
#4.獲得指定日期在一年中爲第幾周
SELECT WEEK(CURDATE());
#5.獲取指定日期中的年份
SELECT YEAR(CURDATE());
#6.獲取指定日期中的月份
SELECT MONTH(CURDATE());
#7.獲取指定日期中的日
SELECT DAY(CURDATE());
#8.獲取指定日期中的時
SELECT HOUR(SYSDATE());
#9.獲取指定日期中的分
SELECT MINUTE(SYSDATE());
#10.獲取指定日期中的秒
SELECT SECOND(SYSDATE());
#11.獲取Date1和Date2之間相隔的天數
SELECT DATEDIFF(SYSDATE(),'2019-3-26');
#12.在指定日期之上加N天后的日期
SELECT ADDDATE(SYSDATE(),6);
8.6 字符串查詢
語法:SELECT 字符串函數([參數列表]);
字符串函數 | 說明 |
---|---|
CONCAT(str1,str2,str3…) | 將多個字符串進行拼接 |
INSERT(str,pos,len,newStr) | 將str中指定pos位置開始len長度的內容替換爲newStr |
LOWER(str) | 將指定字符串轉換爲小寫 |
UPPER(str) | 將指定字符串轉換爲大寫 |
SUBSTRING(str,pos,len) | 將str字符串指定pos位置開始截取len個內容 |
8.6.1 字符串函數應用
#1.連接將多個字符串連接在一起
SELECT CONCAT('My','S','QL');
#2.插入替換(下標從1開始)
SELECT INSERT('這是MySQL數據庫',3,5,'Oracle');
#3.轉小寫
SELECT LOWER('MYSQL');
#4.轉大寫
SELECT UPPER('mysql');
#5.截取
SELECT SUBSTRING('巖巖太漂亮了!我的天呀',3,4);
8.7 聚合函數
語法:SELECT 聚合函數(列名) FROM 表名;
聚合函數 | 說明 |
---|---|
COUNT() | 求總行數 |
SUM() | 求單列中所有行的總和 |
AVG() | 求單列中所有行的平均值 |
MAX() | 求單列中所有行的最大值 |
MIN() | 求單列中所有行的最小值 |
8.7.1 求總行數
#1.查詢員工一共多少人
SELECT COUNT(EMPLOYEE_ID) AS '員工總數' FROM t_employees;
SELECT COUNT(MANAGER_ID) AS '經理總數' FROM t_employees;
SELECT COUNT(*) FROM t_employees;
8.7.2 單列總和
#2.查詢員工每個月工資的總和
SELECT SUM(salary) FROM t_employees;
8.7.3 單列平均值
#3.查詢員工每個月工資的平均工資
SELECT AVG(salary) FROM t_employees;
8.7.4 單列最大值
#4.查詢月薪最高的
SELECT MAX(salary) FROM t_employees;
8.7.5 單列最小值
#5.查詢月薪最低的
SELECT MIN(salary) FROM t_employees;
8.8 分組查詢
語法: SELECT 列名 FROM 表名 WHERE 條件 GROUP BY 分組依據(列名)
關鍵字 | 說明 |
---|---|
GROUP BY | 分組依據。如果有WHERE,在WHERE之後生效 |
8.8.1 查詢各部門的總人數
#思路:
#1.先按照部門編號分組(分組依據是:department_id)
#2.再針對各部門的人數進行統計(count)
SELECT DEPARTMENT_ID,COUNT(EMPLOYEE_ID)
FROM t_employees
GROUP BY DEPARTMENT_ID;
8.8.2 查詢各部門的平均工資
#思路:
#1.先按照部門編號分組(分組依據是:department_id)
#2.再針對各部門的工資進行平均計算(AVG())
SELECT DEPARTMENT_ID,AVG(salary) AS '平均工資',COUNT(EMPLOYEE_ID) AS'人數'
FROM t_employees
GROUP BY DEPARTMENT_ID;
8.8.3 查詢各個部門、各個崗位的人數
#思路
#1.按照部門編號進行分組(department_id)
#2.按照崗位名稱進行分組(job_id)
#3.針對每個部門中各個崗位的人數進行統計
SELECT DEPARTMENT_ID AS'部門',JOB_ID AS'崗位',COUNT(EMPLOYEE_ID) AS'人數'
FROM t_employees
GROUP BY DEPARTMENT_ID,JOB_ID;
8.8.4 常見問題
#查詢各個部門的id、總人數、first_name
SELECT DEPARTMENT_ID,COUNT(EMPLOYEE_ID),FIRST_NAME
FROM t_employees
GROUP BY DEPARTMENT_ID;
8.9 分組過濾查詢
語法: SELECT 列名 FROM 表名 WHERE 條件 GROUP BY 分組依據(列名) HAVING 過濾規則
關鍵字 | 說明 |
---|---|
HAVING | 過濾規則是對分組後的數據進行過濾 |
8.9.1 統計部門中的最高工資
#統計部門編號爲60、70、80的部門最高工資
#思路:
#1.確定分組依據 department_id
#2.對分組後的數據進行過濾 過濾規則爲 60 70 80部門編號
#3.分組過濾後的數據,做max()函數處理
SELECT DEPARTMENT_ID,MAX(salary)
FROM t_employees
GROUP BY DEPARTMENT_ID
HAVING DEPARTMENT_ID IN (60,70,80);
#HAVING是在分組之後的數據進行過濾
8.10 限定查詢
語法:SELECT 列名 FROM 表名 LIMIT 起始行,查詢行
關鍵字 | 描述 |
---|---|
LIMIT offset_start,row_count | 限定查詢結果的起始行和總行數 |
8.10.1 查詢前5行記錄
#查詢表中前五名員工的信息
SELECT * FROM t_employees LIMIT 0,5;
8.10.2 查詢範圍記錄
#查詢表中的第二頁數據和第三頁數據
SELECT * FROM t_employees LIMIT 5,5;
SELECT * FROM t_employees LIMIT 10,5;
8.11 查詢總結
8.11.1 SQL語句編寫順序
SELECT 列名 FROM 表名 WHERE 條件 GROUP BY 分組 HAVING 過濾條件 ORDER BY 排序列 LIMIT 起始行,總條數
8.11.2 SQL語句執行順序
#1.執行 FROM : 指定數據來源表
#2.執行WHERE : 對查詢的數據做第一次過濾
#3.執行GROUP BY :分組
#4.執行HAVING : 對分組後的數據做第二次過濾
#5.執行SELECT : 查詢各個字段的值
#6.執行ORDER BY : 排序
#7.執行LIMIT : 限定查詢結果
8.12 子查詢(作爲條件判斷)
語法:SELECT 列名 FROM 表名 WHERE 條件(子查詢結果)
8.12.1 查詢工資大於Bruce的員工信息
#思路
#1.先查詢到Bruce的工資(一行一列)
SELECT SALARY FROM t_employees WHERE first_name = 'Bruce';#6000
#2.查詢大於Bruce工資的員工信息
SELECT * FROM t_employees WHERE SALARY > 6000;
#3.將1 、2 整合爲一條語句
SELECT * FROM t_employees WHERE salary >(SELECT SALARY FROM t_employees WHERE first_name = 'Bruce');
8.13 子查詢(作爲枚舉查詢的條件)
語法:SELECT 列名 FROM 表名 WHERE 列名 IN(子查詢結果)
8.13.1 查詢與King同一部門員工信息
#思路
#1.查詢King所在的部門編號(多行單列)
SELECT DEPARTMENT_ID FROM t_employees WHERE last_name='King';
#2.將 80、90作爲枚舉查詢的條件
SELECT EMPLOYEE_ID,FIRST_NAME,salary
FROM t_employees
WHERE DEPARTMENT_ID IN (80,90)
#3.整合
SELECT EMPLOYEE_ID,FIRST_NAME,salary
FROM t_employees
WHERE DEPARTMENT_ID
IN
(SELECT DEPARTMENT_ID FROM t_employees WHERE last_name='King')
8.13.2 工資高於60部門的所有人的信息
#1.查詢部門編號爲60的工資
SELECT salary FROM t_employees WHERE DEPARTMENT_ID = 60;
#2.查詢高於60部門所有人的工資的員工信息(高於所有人!)
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE salary > ALL
(SELECT salary FROM t_employees WHERE DEPARTMENT_ID = 60);
#3.查詢高於60部門所有人的工資的員工信息(高於部分人!)
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees
WHERE salary > ANY
(SELECT salary FROM t_employees WHERE DEPARTMENT_ID = 60);
8.14 子查詢(作爲一張表)
語法:SELECT 列名 FROM (子查詢結果集) WHERE 條件;
8.14.1 查詢表中部分列的信息,獲得工資大於15000的
#思路
#1.先查詢部分列的信息作爲一張臨時表
SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees;
#2.將子查詢得到的臨時表作爲外部查詢的表
SELECT EMPLOYEE_ID ,FIRST_NAME ,salary
FROM
(SELECT EMPLOYEE_ID,FIRST_NAME,salary FROM t_employees)AS temp
WHERE salary > 15000;
8.15 合併查詢(瞭解)
語法:
8.15.1 合併兩張表的結果(去除重複記錄)
#合併 t1 和t2兩張表的結果。縱向合併,去除重複的記錄
SELECT * FROM t1
UNION
SELECT * FROM t2
8.15.2 合併兩張表的結果(保留重複記錄)
#合併結果集,不去除重複記錄
SELECT * FROM t1
UNION ALL
SELECT * FROM t2
8.16 表連接查詢
8.16.1 內連接查詢(INNER JOIN ON)
#查詢所有有部門的員工信息,顯示部門名稱(不包括沒有部門的員工) SQL標準
SELECT * FROM t_employees
INNER JOIN t_departments
ON t_employees.`DEPARTMENT_ID` = t_departments.`DEPARTMENT_ID`;
#MYSQL標準
SELECT EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_NAME FROM
t_employees,t_departments
WHERE t_employees.`DEPARTMENT_ID` = t_departments.`DEPARTMENT_ID`;
#1.兩張表連接查詢,要有關聯條件。但是關聯條件的列重複了。需要明確查詢的是哪個表的列
#2.表名比較長,表名多次重複出現。容易混淆.可以給別名
SELECT EMPLOYEE_ID,FIRST_NAME,d.DEPARTMENT_ID,DEPARTMENT_NAME FROM t_employees AS e
INNER JOIN t_departments AS d
ON e.`DEPARTMENT_ID` = d.`DEPARTMENT_ID`;
8.16.2 內連接查詢
#查詢所有崗位的員工信息,顯示崗位名稱
SELECT EMPLOYEE_ID,FIRST_NAME,JOB_TITLE
FROM t_employees AS e
INNER JOIN t_jobs AS j
ON e.`JOB_ID` = j.`JOB_ID`;
8.16.3 三表連接查詢
#查詢所有員工工號、名字、部門名稱、部門所在城市的名稱
SELECT EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_NAME,CITY
FROM t_employees AS e
INNER JOIN t_departments AS d
ON e.`DEPARTMENT_ID` = d.`DEPARTMENT_ID`
INNER JOIN t_locations AS l
ON d.`LOCATION_ID` = l.`LOCATION_ID`;
8.16.4 多表連接查詢
#查詢所有員工工號、名字、部門名稱、部門城市名稱、所在城市的國家
SELECT EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_NAME,CITY,COUNTRY_NAME
FROM t_employees AS e
INNER JOIN t_departments AS d
ON e.`DEPARTMENT_ID` = d.`DEPARTMENT_ID`
INNER JOIN t_locations AS l
ON d.`LOCATION_ID` = l.`LOCATION_ID`
INNER JOIN t_countries AS c
ON l.`COUNTRY_ID` = c.`COUNTRY_ID`;
8.16.5 左外連接查詢(LEFT JOIN ON)
#查詢所有員工信息,以及對應的部門名稱(沒有部門的員工,也在查詢結果中,但是部門名稱以NULL填充)
SELECT EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_NAME
FROM t_employees AS e
LEFT JOIN t_departments AS d
ON e.`DEPARTMENT_ID` = d.`DEPARTMENT_ID`;
8.16.6 右外連接查詢(RIGHT JOIN ON)
#查詢所有部門信息,以及部門中的員工信息
#(沒有員工的部門,也在查詢結果中,員工信息以NULL填充)
SELECT EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_NAME
FROM t_employees AS e
RIGHT JOIN t_departments AS d
ON e.`DEPARTMENT_ID` = d.`DEPARTMENT_ID`;
九、 DML操作(增、刪、改)
9.1 新增(INSERT)
9.1.1 添加一條信息
#添加一條員工信息
INSERT INTO t_employees
(EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID)
VALUES('209','Ya','Suo','[email protected]','515.123.6666','2010-03-18','Center',900,NULL,'123','50')
#多行添加,在值列表外邊追加,再寫一個值列表
,('208','Ya','Suo','[email protected]','515.123.6666','2010-03-18','Center',900,NULL,'123','50');
#添加一條城市信息
INSERT INTO t_countries(COUNTRY_ID,COUNTRY_NAME)VALUES('AL','阿爾巴尼亞');
SELECT * FROM t_departments;
#添加一條部門信息
INSERT INTO t_departments(DEPARTMENT_ID,DEPARTMENT_NAME,MANAGER_ID,LOCATION_ID)
VALUES('280','Teach','111','1500')
9.2 修改(UPDATE)
9.2.1 修改一條信息
#修改員工編號爲208的員工名字爲TOM Jackson
UPDATE t_employees
SET FIRST_NAME='TOM', LAST_NAME = 'Jackson'
WHERE EMPLOYEE_ID = '208';
9.3 刪除
DELETE FROM 表名 WHERE 條件
9.3.1 刪除一條信息
#刪除一條員工,編號爲207的
DELETE FROM t_employees
WHERE EMPLOYEE_ID = '207'
9.4 清空(TRUNCATE)
TRUNCATE TABLE 表名;
9.4.1 清空整張表
#清空t2整張表
TRUNCATE TABLE t2;
十、庫表操作
10.1 數據庫創建(CREATE)
CREATE DATABASE 庫名
10.1 創建數據庫
#創建默認字符集的數據庫
CREATE DATABASE MYDB1;
#創建指定字符集的數據庫
CREATE DATABASE MYDB1 CHARACTER SET UTF8;
10.2 修改數據庫
ALTER DATABASE 庫名 操作
10.2.1 修改數據庫的字符集
#修改mydb1的字符集給gbk
ALTER DATABASE MYDB1 CHARACTER SET GBK;
10.3 刪除數據庫
DROP DATABASE 庫名
10.3.1 刪除數據庫
#刪除mydb1數據庫
DROP DATABASE MYDB1;
10.4 數據類型
MySQL大致可以分爲三類:數值、日期/時間、字符串(字符)類型。對於我們建表,約束列的類型有很大的幫助
10.4.1 數值類型
類型 | 大小 | 範圍(有符號) | 範圍(無符號) | 用途 |
---|---|---|---|---|
INT | 4字節 | (-2147483648,2147483647) | (0,4294967295) | 整數值 |
DOUBLE | 8字節 | (-1.797E+308,-2.22E-308) | (0,2.22E-308,1.797E+308) | 雙精度浮點值 |
DOUBLE(M,D) | 8字節,M表示長度,D表示小數位數 | 同上,受M和D的約束。DOUBLE(5,2)-999.99-999.99 | 同上,受M和D的約束 | 雙精度浮點值 |
DECIMAL(M,D) | 保存精確值 | 依賴M和D。 | 依賴M和D | 小數值 |
10.4.2 日期類型
類型 | 大小 | 範圍 | 格式 | 用途 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | ‘-838:59:59’/‘838:59:59’ | HH:MM:SS | 時間值 |
YEAR | 1 | 1901/2155 | YYYY | 年分值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM–DD HH:MM:SS | 混合日期時間值 |
10.4.3 字符串類型
類型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字符 | 定長字符串 CHAR(10) 10個字符 |
VARCHAR | 0-65535 | 可變長字符串 VARCHAR(10) 10個字符 |
BLOB(binary large object) | 0-65535 | 二進制形式的長文本數據 |
TEXT | 0-65535 | 長文本 |
10.5 數據表的創建(CREATE)
…
列名 數據類型 [約束] //最後一列的創建,末尾不需要加逗號
)[charset=utf8]; //根據需要指定表的字符編碼集
10.5.1 創建表
#創建科目表
#科目編號、科目名稱、科目學時
#Subject
CREATE TABLE `Subject`(
subjectId INT,
subjectName VARCHAR(20),
subjectHours INT
)CHARSET=utf8;
INSERT INTO `subject`(subjectid,subjectname,subjecthours)
VALUES(1,'Java',10);
INSERT INTO `subject`(subjectid,subjectname,subjecthours)
VALUES(2,'HTML5',20);
INSERT INTO `subject`(subjectid,subjectname,subjecthours)
VALUES(3,'BIGDATA',5);
十一、約束
11.1 實體完整性約束
表中一行數據代表一個實體(entity),實體完整性約束是標識每一行數據不重複、實體唯一。
11.1.1 主鍵約束
PRIMARY KEY 唯一,標識表中的一行數據,此列的值不可重複,且不能爲NULL
#創建表中,選擇適合做主鍵的列,添加主鍵約束
CREATE TABLE Student(
stuid INT PRIMARY KEY,#標識每一個學生的編號是唯一的,不能爲NULL
stuName VARCHAR(20),
phone VARCHAR(11)
)CHARSET=utf8;
11.1.2 唯一約束
UNIQUE 唯一,標識表中的一行數據,不可重複,可以爲NULL
#表中的手機號列,添加唯一約束!不能重複,但是可以爲NULL
CREATE TABLE Student(
stuid INT PRIMARY KEY,#標識每一個學生的編號是唯一的,不能爲NULL
stuName VARCHAR(20),
phone VARCHAR(11) UNIQUE
)CHARSET=utf8;
11.1.3 自動增長列
AUTO_INCREMENT 自動增長,給主鍵數值列添加自動增長。從1開始,每次加1。不能單獨使用,和主鍵搭配
#爲表中的主鍵列添加自動增長,避免ID重複,也容易忘記
CREATE TABLE Student(
stuid INT PRIMARY KEY AUTO_INCREMENT,#會從1開始,根據添加數據的順序依次+1
stuName VARCHAR(20),
phone VARCHAR(11) UNIQUE
)CHARSET=utf8;
11.2 域完整性約束
限制列的每一個單元格的數據正確性
11.2.1 非空約束
NOT NULL 非空,約束此列的每一個單元格不允許有NULL
#加了NOT NULL的約束列,必須有值
CREATE TABLE emp(
id INT PRIMARY KEY AUTO_INCREMENT,
empName VARCHAR(20)NOT NULL,#約束名字這一列必須有值
address VARCHAR(50) NOT NULL
)CHARSET=utf8;
INSERT INTO emp(empName,address) VALUES(null,'北京市海淀區');#error,課程名稱必須有值
11.2.2 默認值約束
DEFAULT 爲列賦予默認值,當新增的數據不指定值時,可以書寫DEFAULT,以定義好的默認值進行填充
#默認值約束,如果沒有指定值,填充DEFAULT,默認值。
CREATE TABLE emp(
id INT PRIMARY KEY AUTO_INCREMENT,
empName VARCHAR(20)NOT NULL,#約束名字這一列必須有值
address VARCHAR(50) NOT NULL,
sex CHAR(1) DEFAULT '女'
)CHARSET=utf8;
11.2.3 引用完整性約束
語法:CONSTRAINT 引用名 FOREIGN KEY (列名) REFERENCES 被引用表名(列名)
詳解:FOREIGN KEY 引用外部表的某個列的值,新增數據時,約束此列的值必須是被引用表中存在的值
#專業表
CREATE TABLE Speciality(
id INT PRIMARY KEY AUTO_INCREMENT,
SpecialName VARCHAR(20) UNIQUE NOT NULL#唯一,且不能爲空
)CHARSET=utf8;
#課程表
CREATE TABLE `subject`(
subjectid INT PRIMARY KEY AUTO_INCREMENT,
subjecname VARCHAR(20) UNIQUE NOT NULL,
subjecthours INT DEFAULT 20,
specialid INT NOT NULL,
CONSTRAINT fk_subject_specialid
FOREIGN KEY(specialid)
REFERENCES Speciality(id)
)CHARSET=utf8;
SELECT * FROM SUBJECT;
#存在引用關係的表。要先添加被引用的表數據(主鍵表).再添加引用表的數據(外鍵表)
INSERT INTO Speciality (SpecialName) VALUES('Java');
INSERT INTO Speciality (SpecialName) VALUES('HTML5');
INSERT INTO `subject`(subjecname,subjecthours,specialid)
VALUES('JavaSE',10,1);
INSERT INTO `subject`(subjecname,subjecthours,specialid)
VALUES('JavaScript',20,2);
INSERT INTO `subject`(subjecname,subjecthours,specialid)
VALUES('BIGDATA',20,3);#error 約束:主鍵表不存在3.所以外鍵表不能插入3
11.3 約束創建整合
創建帶有約束的表
11.3.1 創建Grade表
列名 | 數據類型 | 約束 | 說明 |
---|---|---|---|
GradeId | INT | 主鍵、自動增長 | 班級編號 |
GradeName | VARCHAR(20) | 唯一、非空 | 班級名稱 |
#創建Grade表
CREATE TABLE Grade(
GradeId INT PRIMARY KEY AUTO_INCREMENT,
GradeName VARCHAR(20) UNIQUE NOT NULL
)CHARSET=utf8;
SELECT * FROM grade;
INSERT INTO Grade(GradeName) VALUES('NN2001');
INSERT INTO Grade(GradeName) VALUES('NN2002');
INSERT INTO Grade(GradeName) VALUES('NN2003');
11.3.2 創建Student表
列名 | 數據類型 | 約束 | 說明 |
---|---|---|---|
student_id | VARCHAR(50) | 主鍵 | 學號 |
student_name | VARCHAR(50) | 非空 | 姓名 |
sex | CHAR(2) | 默認值。男 | 性別 |
borndate | DATE | 非空 | 生日 |
phone | VARCHAR(11) | 無 | 電話 |
GradeId | INT | 非空,外鍵約束:引用班級表的GradeId | 班級編號 |
#創建Student表
CREATE TABLE Student(
student_id VARCHAR(50) PRIMARY KEY,
student_name VARCHAR(50) NOT NULL,
sex CHAR(2) DEFAULT '男',
borndate DATE NOT NULL,
phone VARCHAR(11),
GradeId INT NOT NULL,
CONSTRAINT fk_student_gradeId FOREIGN KEY(GradeId) REFERENCES Grade(GradeId)
)CHARSET=utf8;
SELECT * FROM student;
INSERT INTO student(student_id,student_name,sex,borndate,phone,GradeId)
VALUES('S1001','巖巖',DEFAULT,'2001-06-01',NULL,2);
INSERT INTO student(student_id,student_name,sex,borndate,phone,GradeId)
VALUES('S1002','',DEFAULT,'1999-06-01',NULL,3);
11.4 數據表的修改(ALTER)
語法:ALTER TABLE 表名 修改操作;
11.4.1 向現有表中添加列
#向現有表中添加列
ALTER TABLE Student ADD image BLOB;
#ADD 新列名 數據類型 [約束]
11.4.2 修改表中的列
ALTER TABLE student MODIFY phone VARCHAR(14) NOT NULL
11.4.3 刪除表中的列
ALTER TABLE student DROP image;
11.4.4 改變列名
ALTER TABLE student CHANGE borndate birthday DATE NOT NULL;
11.4.5 修改表名
ALTER TABLE student RENAME stu;
11.5 刪除表(DROP)
DROP TABLE 表名
11.5.1 刪除學生表
DROP TABLE stu
十二、事務
12.1 模擬轉賬
生活中轉賬是轉賬方扣錢,收錢方賬戶價錢。用數據庫操作來模擬現實轉賬。
12.1.1 模擬賬戶轉錢
#1賬號轉錢給2賬戶1000元
#1賬戶扣錢
UPDATE account SET money = money - 1000 WHERE id = 1;
#2賬戶加錢
UPDATE account SET money = money + 1000 WHERE id = 2;
12.1.2 模擬轉賬錯誤
#1賬號轉錢給2賬戶1000元
#1賬戶扣錢
UPDATE account SET money = money - 1000 WHERE id = 1;
#斷電、異常、出錯
#2賬戶加錢
UPDATE account SET money = money + 1000 WHERE id = 2;
12.2 事務的概念
事務是一個原子操作。是一個最小執行單元。可以由一個或多個SQL語句組成,在同一個事務中,所有的SQL語句都成功執行時,整個事務成功!有一個SQL語句執行失敗,整個事務都執行失敗!
12.3 事務的邊界
12.4 事務的原理
數據庫會爲每一個客戶端都維護一個空間獨立的緩存區(回滾段),一個事務中所有的增刪改語句的執行結果都會緩存在回滾段中,只有當事務中所有的SQL語句均正常結束(COMMIT),纔會將回滾段中的數據同步到數據庫。否則無論因爲任何原因失敗了,則整個事務回滾(ROLLBACK);
12.5 事務的特性
表示的是一個事務內的所有操作是一個整體,要麼全部成功,要麼全部失敗。
表示一個事務內有一個操作失敗時,所有的更改過得數據都必須回滾到修改前狀態。
事務查看數據操作時數據所處的狀態,要麼是另一個併發事務修改數據之前的狀態,要麼是另一個併發事務修改它之後的狀態。事務不會查看中間狀態的數據
事務完成之後,對於數據庫的影響是永久性的。
12.6 事務的應用
應用環境:基於增刪改語句的操作結果(均返回操作後受影響的行數),可通過程序邏輯手動控制事務的提交或回滾
12.6.1 事務完成轉賬
#開啓事務
START TRANSACTION;#SET autoCommit = 0;#方式2 設置自動提交爲0 關閉自動提交 | 1 開啓自動提交
#1賬戶扣錢
UPDATE account SET money = money - 1000 WHERE id = 1;
#2賬戶加錢
UPDATE account SET money = money + 1000 WHERE id = 2;
#執行提交 ---成功
COMMIT;
#執行回滾 ---失敗
ROLLBACK;
十三、權限管理
13.1 創建用戶
CREATE USER 用戶名 IDENTIFIED BY 密碼
13.1.1 創建一個用戶
#創建用戶
CREATE USER 'zhangsan' IDENTIFIED BY '123';
13.2 授權
GRANT ALL ON 數據庫.表名 TO 用戶名;
13.2.1 用戶授權
#將companydb數據裏的grade表授權給zhangsan
GRANT ALL ON companydb.`grade` TO 'zhangsan';
#將companydb數據庫裏的所有表授權給zhangsan
GRANT ALL ON companydb.* TO 'zhangsan';
13.3 撤銷權限
REVOKE ALL ON 數據庫.表名 FROM 用戶名
13.3.1 撤銷用戶權限
REVOKE ALL ON companydb.grade FROM 'zhangsan';
13.4 刪除用戶
DROP USER 用戶名;
13.4.1 刪除用戶
DROP USER 'zhangsan';
十四、視圖
14.1 概念
視圖,虛擬表,從一個表中或多個表中查詢出來的結果表,作用和真實表一樣,包含一系列的帶有行和列的數據。視圖中,可以使用SELECT語句查詢數據,也可以使用INSERT、UPDATE、DELETE修改記錄,視圖可以使用戶操作方便,並保障了數據庫系統安全。
14.2 視圖特點
- 優點
- 簡單化,數據所見即所得
- 安全性,只能查詢或修改視圖中鎖能見到的數據
- 邏輯獨立性,可以屏蔽真實表結構變化帶來的影響。
- 缺點
- 性能相對較差,簡單的查詢會稍微複雜
- 修改不方便,當視圖的數據時複雜的聚合視圖時,無法修改。
14.3 視圖的創建
語法:CREATE VIEW 視圖名 AS 查詢數據源表的語句;
14.3.1 創建視圖
#創建一個t_empinfo視圖,該視圖的數據是員工姓名,郵箱,手機號碼
CREATE VIEW t_empinfo
AS
SELECT FIRST_NAME,LAST_NAME,email,PHONE_NUMBER FROM t_employees;
14.3.2 使用視圖
#使用視圖
#查詢,所見即所得
SELECT * FROM t_empinfo WHERE FIRST_NAME='Steven' AND LAST_NAME='King';
#修改。只能修改得到的
UPDATE t_empinfo SET email = 'Kings' WHERE FIRST_NAME='Steven' AND LAST_NAME='King';
14.4 視圖的修改
- 方式一:CREATE OR REPLACE VIEW 視圖名 AS 查詢源表的語句;
- 方式二:ALTER VIEW 視圖名 AS查詢源表的語句;
14.4.1 修改視圖
#方式1
#存在就替換數據,不存在就新建
CREATE OR REPLACE VIEW t_empinfo
AS
SELECT employee_id,FIRST_NAME,LAST_NAME,email,PHONE_NUMBER FROM t_employees;
#方式2
ALTER VIEW t_empinfo
AS
SELECT FIRST_NAME,LAST_NAME,email,PHONE_NUMBER FROM t_employees;
14.5 視圖的刪除
DROP VIEW 視圖名
14.5.1 刪除視圖
DROP VIEW t_empinfo;
14.6 視圖的注意事項
- 注意:
- 視圖不會獨立存儲數據,原表發生改變,視圖的數據也發生改變。沒有優化查詢的性能
- 如果視圖包含以下結構中的一種,則視圖不可更新
- 聚合函數的結果
- GROUP BY分組後的結果
- HAVING篩選過濾後的結果
- UNION、UNION ALL聯合後的結果
十五、 SQL語言分類
- 數據查詢語言DQL (Data Query Language):SELECT、WHERE、ORDER BY 、GROUP BY 、HAVING
- 數據定義語言DDL (Data Definition Language): CREATE、ALTER、DROP
- 數據操作語言DML(Data Manipulation Language):INSERT、UPDATE、DELETE
- 事務處理語言TPL (Transaction Process Language):COMMIT、ROLLBACK
- 數據控制語言DCL (Data Control Language):GRANT、REVOKE