數據庫 = MySQL多表查詢與權限,數據庫備份與還原

多表查詢,用戶權限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

我們現在默認使用的都是root用戶,超級管理員,擁有全部的權限。但是,一個公司裏面的數據庫服務
器上面可能同時運行着很多個項目的數據庫。所以,我們應該可以根據不同的項目建立不同的用戶,分
配不同的權限來管理和維護數據庫。
 

進入公司後,有專門的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. 確定查詢字段

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章