多表查詢,用戶權限DCL,數據庫的備份與還原
一.多表查詢
同時查詢多張表獲取到需要的數據組成完整的信息返回給用戶。
多表查詢分類:
數據準備:
-- 多表查詢
create database crmpro;
use crmpro;
-- 創建部門表(主表)
CREATE TABLE dept (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
INSERT INTO dept (NAME) VALUES ('開發部'),('市場部'),('財務部'),('銷售部');
-- 創建員工表(從表)
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
gender CHAR(1), -- 性別(sex)
salary DOUBLE, -- 工資
join_date DATE, -- 入職日期
dept_id INT -- 外鍵字段
);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孫空','男',7200,'2013-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('豬戒','男',3600,'2010-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白精','女',5000,'2015-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘精','女',4500,'2011-03-14',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('沙僧','男',6666,'2017-03-04',null);
此時該表是一對多的關係
(1)笛卡爾積
select ... from 左表,右表;
笛卡爾積:
-- 查詢二張表
SELECT * FROM emp,dept;
SELECT COUNT(*) FROM emp,dept;
(2)內連接
* 功能
拿左表的記錄去匹配由標的記錄,若符合條件顯示(二張表的交集)
* 語法
1)隱式內連接:看不到join關鍵字,條件使用where指定
select ... from 左表,右表 where 連接條件;
2)顯示內連接【推薦】:使用Inner jion。。。on語句,可以省略inner。
select ... from 左表 [inner] join 右表 on 連接條件;
-- 內連接
-- 隱式內連接
SELECT * FROM emp e,dept d WHERE e.dept_id = d.id;
-- 顯示內連接
SELECT * FROM emp e INNER JOIN dept d ON e.dept_id = d.id;
-- 查詢唐僧的 id,姓名,性別,工資和所在部門名稱
-- 1.確定查詢表
SELECT * FROM emp e INNER JOIN dept d;
-- 2.確定連接條件
SELECT * FROM emp e INNER JOIN dept d ON e.dept_id = d.id;
-- 3.確定顯示字段
SELECT e.id,e.name,e.gender,e.salary,d.name FROM emp e INNER JOIN dept d ON e.dept_id = d.id;
-- 4.確定業務條件
SELECT e.id,e.name,e.gender,e.salary,d.name FROM emp e INNER JOIN dept d ON e.dept_id = d.id WHERE e.name = '唐僧';
(3)外連接
1. 左外連接
功能
展示左表全部,再去匹配右表記錄,若條件符合顯示,若條件不符合顯示NULL
語法
select ... from 左表 left [outer] join 右表 on 連接條件;
1. 右外連接
功能
展示右表全部,再去匹配左表記錄,若條件符合顯示,若條件不符合顯示NULL
語法
select ...from 左表 right [outer] join 右表 on 連接條件;
//左外連接(推薦)
// 查詢所有員工信息及對應的部門名稱
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.dept_id = d.id;
//查詢所有部門及對應的員工信息
SELECT * FROM dept d LEFT JOIN emp e ON e.dept_id = d.id;
//右外連接
//查詢所有部門及對應的員工信息
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.dept_id = d.id;
(4)子查詢(嵌套)
* 功能
一條select語句執行結果,作爲另一條select語法的一部分
* 語法
1)查詢結果單值
SELECT MAX(salary) FROM emp;
2)查詢結果單列多值
SELECT salary FROM emp;
3)查詢結果多列多值
SELECT * FROM emp;
* 規律
子查詢結果爲單列,肯定作爲條件在where後面使用
select ... from 表名 where 字段 in (子查詢);
子查詢結果爲多列,一般作爲虛擬表在from後面使用
select ... from (子查詢) as 表別名;
# 子查詢
# 子查詢結果爲單值
-- 查詢工資最高的員工是誰?
SELECT * FROM emp WHERE salary = (SELECT MAX(salary) FROM emp);
-- 查詢工資小於平均工資的員工有哪些?
-- === 先求出平均工資
SELECT AVG(salary) FROM emp;
-- ===查詢低於平均工資的員工
SELECT * FROM emp WHERE salary < (SELECT AVG(salary) FROM emp);
# 子查詢結果爲單列多行
-- 查詢工資大於5000的員工,來自於哪些部門的名字
--=== 查詢工資大於5000的員工
SELECT dept_id FROM emp WHERE salary >5000;
-- === 來自於哪些部門的名字
SELECT * FROM dept WHERE id IN(SELECT dept_id FROM emp WHERE salary >5000);
-- 查詢開發部與財務部所有的員工信息
-- ==== 根據部門名稱,查詢部門主鍵
SELECT id FROM dept WHERE `name` IN('開發部','財務部');
--====根據部門id查詢員工信息
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE `name` IN('開發部','財務部'));
# 子查詢結果爲多列多行
-- 1 查詢出`dept`,包括部門名稱
-- 方案一
-- ==== 查詢出2011年以後入職的員工信息
SELECT * FROM emp WHERE join_date > '2011-1-1';
-- ====通過臨時表跟部門表關聯
SELECT * FROM (SELECT * FROM emp WHERE join_date > '2011-1-1') e LEFT JOIN dept d ON e.dept_id = d.id;
-- 方案二
-- ==== 先實現二張表關聯
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.dept_id = d.id;
-- ==== 再過濾2011年以後入職的
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.dept_id = d.id WHERE e.join_date > '2011-1-1';
(5)案例
其實我們在企業開發過程中,根據不同的業務需求往往需要通過2張及以上表中去查詢需要的數據。其實不管幾張表的查詢,都是有規律可循的、
準備數據:
//多表案例
create database crmpro;
use crmpro;
// 部門表
CREATE TABLE dept (
id INT PRIMARY KEY auto_increment, -- 部門id
dname VARCHAR(50), -- 部門名稱
loc VARCHAR(50) -- 部門位置
);
// 添加4個部門
INSERT INTO dept(id,dname,loc) VALUES
(10,'教研部','北京'),
(20,'學工部','上海'),
(30,'銷售部','廣州'),
(40,'財務部','深圳');
//職務表
CREATE TABLE job (
id INT PRIMARY KEY,
jname VARCHAR(20), -- 職務名稱
description VARCHAR(50) -- 職務描述
);
// 添加4個職務
INSERT INTO job (id, jname, description) VALUES
(1, '董事長', '管理整個公司,接單'),
(2, '經理', '管理部門員工'),
(3, '銷售員', '向客人推銷產品'),
(4, '文員', '使用辦公軟件');
//員工表
CREATE TABLE emp (
id INT PRIMARY KEY, -- 員工id
ename VARCHAR(50), -- 員工姓名
job_id INT, -- 職務id 外鍵
mgr INT , -- 上級領導
joindate DATE, -- 入職日期
salary DECIMAL(7,2), -- 工資 99999.99
bonus DECIMAL(7,2), -- 獎金 99999.99
dept_id INT, -- 所在部門編號 外鍵
CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);
//添加員工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
(1001,'孫悟空',4,1004,'2001-12-17','8000.00',NULL,20),
(1002,'盧俊義',3,1006,'2011-02-20','16000.00','3000.00',30),
(1003,'林沖',3,1006,'2007-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2009-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2008-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2012-05-01','28500.00',NULL,30),
(1007,'劉備',2,1009,'2011-09-01','24500.00',NULL,10),
(1008,'豬八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'羅貫中',1,NULL,'2005-11-17','50000.00',NULL,10),
(1010,'吳用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2004-12-03','9500.00',NULL,30),
(1013,'小白龍',4,1004,'2003-12-03','30000.00',NULL,20),
(1014,'關羽',4,1007,'2002-01-23','13000.00',NULL,10);
//工資等級表
CREATE TABLE salarygrade (
grade INT PRIMARY KEY, -- 等級
losalary INT, -- 最低工資
hisalary INT -- 最高工資
);
//添加5個工資等級
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);
幾張表的關係:
-- 查詢所有員工信息。顯示員工編號,員工姓名,工資,職務名稱,職務描述
-- === 確定幾張表?
SELECT * FROM emp e INNER JOIN job j;
-- === 確定連接條件
SELECT * FROM emp e INNER JOIN job j ON e.job_id = j.id;
-- === 確定顯示字段(列)
SELECT e.id,e.ename,e.salary,j.jname,j.description FROM emp e INNER JOIN job j ON e.job_id = j.id;
// 查詢所有員工信息。顯示員工編號,員工姓名,工資,職務名稱,職務描述,部門名稱,部門位置
//- 確定幾張表?
SELECT * FROM emp e
INNER JOIN job j
INNER JOIN dept d;
// 確定連接條件
SELECT * FROM emp e
INNER JOIN job j ON e.job_id = j.id
INNER JOIN dept d ON e.dept_id = d.id;
// 確定顯示字段
SELECT e.id,e.ename,e.salary,j.jname,j.description,d.dname,d.loc FROM emp e
INNER JOIN job j ON e.job_id = j.id
INNER JOIN dept d ON e.dept_id = d.id;
-- 查詢所有員工信息。顯示員工姓名,工資,職務名稱,職務描述,部門名稱,部門位置,工資等級
-- 確定幾張表
SELECT * FROM emp e
INNER JOIN job j
INNER JOIN dept d
INNER JOIN salarygrade sg;
-- 確定連接條件
SELECT * FROM emp e
INNER JOIN job j ON e.job_id = j.id
INNER JOIN dept d ON e.dept_id = d.id
INNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;
-- 確定顯示字段
SELECT e.ename,e.salary,j.jname,j.description,d.dname,d.loc,sg.grade FROM emp e
INNER JOIN job j ON e.job_id = j.id
INNER JOIN dept d ON e.dept_id = d.id
INNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;
-- 查詢經理的信息。顯示員工姓名,工資,職務名稱,職務描述,部門名稱,部門位置,工資等級
--
SELECT e.ename,e.salary,j.jname,j.description,d.dname,d.loc,sg.grade FROM emp e
INNER JOIN job j ON e.job_id = j.id
INNER JOIN dept d ON e.dept_id = d.id
INNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary
WHERE j.jname = '經理';
規律:
* 多表查詢會產生笛卡爾積
* 消除笛卡爾積
連接條件 = 表個數-1
* 步驟
1)確定幾張表
2)確定連接條件
3)確定顯示字段
4)確定業務條件
-- 查詢出部門編號、部門名稱、部門位置、部門人數
--查詢出部門編號、部門名稱、部門位置
SELECT * FROM dept;
-- 部門人數(員工表:分組+聚合 )
SELECT dept_id,COUNT(*) AS total FROM emp GROUP BY dept_id;
-- 部門表左外關聯臨時表
SELECT d.id,d.dname,d.loc,e.total FROM dept d
LEFT JOIN (SELECT dept_id,COUNT(*) AS total FROM emp GROUP BY dept_id) e ON d.id = e.dept_id;
查詢每個員工的名稱及其上級領導的名稱(自關聯)
SELECT
yuangong.id,
yuangong.ename,
lingdao.id,
lingdao.ename
FROM
emp yuangong
LEFT OUTER JOIN emp lingdao
ON yuangong.mgr = lingdao.id ;
自關聯查詢公式:
select * from 員工表(emp)left join 領導表(emp) on 員工外鍵 = 領導.主鍵;
二.用戶權限DCL
進入公司後,有專門的DBA數據庫管理員,爲你創建一個新用戶,授予一定的權限
1. 創建用戶
語法:
create user '用戶名'@'主機名' identified by '密碼';
注意:
主機名:限定客戶端登錄ip
指定ip:127.0.0.1 (localhost)
任意ip:%
2. 授權用戶
語法:
grant 權限1,權限2... on 數據庫名.表名 to '用戶名'@'主機名';
注意:
權限:
select、insert、delete、update、create...
all 所有權限
數據庫名.* 指定庫下面所有的表
3. 查看權限
語法:
show grants for '用戶名'@'主機名';
4. 撤銷授權
語法:
revoke 權限1,權限2... on 數據庫名.表名 from '用戶名'@'主機名';
注意:
權限:
select、insert、delete、update、create...
all 所有權限
數據庫名.* 指定庫下面所有的表
5. 刪除用戶
語法:
drop user '用戶名'@'主機名';
6. 密碼管理
1.超級管理員
set password for '用戶名'@'主機名'=password('新密碼');
2.普通用戶
set password=password('新密碼');
-- 創建用戶
CREATE USER 'tom'@'%' IDENTIFIED BY '123';
-- user1用戶只能在localhost這個IP登錄mysql服務器
CREATE USER 'user1'@'localhost' IDENTIFIED BY '123';
-- user2用戶可以在任何電腦上登錄mysql服務器
CREATE USER 'user2'@'%' IDENTIFIED BY '123';
-- 授權
GRANT SELECT ON crmpro.dept TO 'tom'@'%' ;
給user1用戶分配對test這個數據庫操作的權限
GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON test.* TO 'user1'@'localhost';
給用戶user2用戶賦予全部數據庫的全部權限
GRANT ALL ON *.* TO 'user2'@'%';
-- 查看權限
SHOW GRANTS FOR 'tom'@'%' ;
查看user1用戶的權限
SHOW GRANTS FOR 'user1'@'localhost';
-- 撤銷權限
REVOKE SELECT ON crmpro.dept FROM 'tom'@'%' ;
撤銷user1用戶對test操作的權限
REVOKE ALL ON test.* FROM 'user1'@'localhost';
-- 密碼管理
-- 加密函數
SELECT PASSWORD('123');
-- 超級管理幫你找回密碼
SET PASSWORD FOR 'tom'@'%'= PASSWORD('999');
-- 刪除用戶
DROP USER 'tom'@'%' ;
三,數據庫備份與還原
dos命令行操作
1. 備份
格式:
mysqldump -u用戶名 -p 需要備份數據庫名 > 導出路徑(*.sql)
實例:
mysqldump -uroot -proot crmpro > d:bak.sql
缺點:
通過命令備份的只有表結構和數據,沒有建庫語句...
2. 還原
格式:
mysql -u用戶名 -p < 導入路徑(*.sql)
實例:
mysql -uroot -p < d:bak.sql //還原
source d:bak.sql //還原
利用圖像化工具進行
備份:
還原:
總結:
1.
笛卡爾積查詢:
select * from A , B 表示兩個表數據的乘積
內連接
顯示內連接
select * from A [inner] join B on 表關聯條件
隱式內連接
select * from A , B where 表關聯條件
外連接
左外連接
select * from A left [outer] join B on 表關聯條件
右外連接
select * from A right [outer] join B on 表關聯條件
子查詢結果是
單列 ,
多數情況下放在 WHERE 後面作爲 條件 select 查詢字段 from 表 where 字段=(子查詢);
子查詢結果是
多列 ,
多數情況下放在 FROM 後面作爲 表 select 查詢字段 from (子查詢)表別名 where 條件;
2.多表查詢規律:
1. 不管我們查詢幾張表,表連接查詢會產出笛卡爾積,我們需要消除笛卡爾積,拿到正確的數據。我
們需要找到表與表之間通過哪個字段關聯起來的(通常是 外鍵=主鍵 )
2. 消除笛卡爾積規律:2張表至少需要1個條件,3張表至少需要2個條件,4張表至少需要3個條件。
(條件數量=表的數量-1),每張表都要參與進來
3. 多表連接查詢步驟: 3.1. 確定要查詢哪些表 3.2. 確定表連接條件 3.3. 確定查詢字段