約束
外來鍵約束
-
外來鍵約束概念
- 讓表和表之間產生關係,從而保證資料的準確性!
-
建表時新增外來鍵約束
- 為什麼要有外來鍵約束
-- 建立db2資料庫
CREATE DATABASE db2;
-- 使用db2資料庫
USE db2;
-- 建立user使用者表
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT, -- id
NAME VARCHAR(20) NOT NULL -- 姓名
);
-- 新增使用者資料
INSERT INTO USER VALUES (NULL,'張三'),(NULL,'李四'),(NULL,'王五');
-- 建立orderlist訂單表
CREATE TABLE orderlist(
id INT PRIMARY KEY AUTO_INCREMENT, -- id
number VARCHAR(20) NOT NULL, -- 訂單編號
uid INT -- 訂單所屬使用者
);
-- 新增訂單資料
INSERT INTO orderlist VALUES (NULL,'hm001',1),(NULL,'hm002',1),
(NULL,'hm003',2),(NULL,'hm004',2),
(NULL,'hm005',3),(NULL,'hm006',3);
-- 新增一個訂單,但是沒有所屬使用者。這合理嗎?
INSERT INTO orderlist VALUES (NULL,'hm007',8);
-- 刪除王五這個使用者,但是訂單表中王五還有很多個訂單呢。這合理嗎?
DELETE FROM USER WHERE NAME='王五';
-- 所以我們需要新增外來鍵約束,讓兩張表產生關係
- 外來鍵約束格式
CONSTRAINT 外來鍵名 FOREIGN KEY (本表外來鍵列名) REFERENCES 主表名(主表主鍵列名)
- 建立表新增外來鍵約束
-- 建立user使用者表
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT, -- id
NAME VARCHAR(20) NOT NULL -- 姓名
);
-- 新增使用者資料
INSERT INTO USER VALUES (NULL,'張三'),(NULL,'李四'),(NULL,'王五');
-- 建立orderlist訂單表
CREATE TABLE orderlist(
id INT PRIMARY KEY AUTO_INCREMENT, -- id
number VARCHAR(20) NOT NULL, -- 訂單編號
uid INT, -- 訂單所屬使用者
CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id) -- 新增外來鍵約束
);
-- 新增訂單資料
INSERT INTO orderlist VALUES (NULL,'hm001',1),(NULL,'hm002',1),
(NULL,'hm003',2),(NULL,'hm004',2),
(NULL,'hm005',3),(NULL,'hm006',3);
-- 新增一個訂單,但是沒有所屬使用者。無法新增
INSERT INTO orderlist VALUES (NULL,'hm007',8);
-- 刪除王五這個使用者,但是訂單表中王五還有很多個訂單呢。無法刪除
DELETE FROM USER WHERE NAME='王五';
- 刪除外來鍵約束
-- 標準語法
ALTER TABLE 表名 DROP FOREIGN KEY 外來鍵名;
-- 刪除外來鍵
ALTER TABLE orderlist DROP FOREIGN KEY ou_fk1;
- 建表後新增外來鍵約束
-- 標準語法
ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名 FOREIGN KEY (本表外來鍵列名) REFERENCES 主表名(主鍵列名);
-- 新增外來鍵約束
ALTER TABLE orderlist ADD CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id);
外來鍵的級聯更新和級聯刪除(瞭解)
- 什麼是級聯更新和級聯刪除
- 當我想把user使用者表中的某個使用者刪掉,我希望該使用者所有的訂單也隨之被刪除
- 當我想把user使用者表中的某個使用者id修改,我希望訂單表中該使用者所屬的訂單使用者編號也隨之修改
- 新增級聯更新和級聯刪除
-- 新增外來鍵約束,同時新增級聯更新 標準語法
ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名 FOREIGN KEY (本表外來鍵列名) REFERENCES 主表名(主鍵列名) ON UPDATE CASCADE;
-- 新增外來鍵約束,同時新增級聯刪除 標準語法
ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名 FOREIGN KEY (本表外來鍵列名) REFERENCES 主表名(主鍵列名) ON DELETE CASCADE;
-- 新增外來鍵約束,同時新增級聯更新和級聯刪除 標準語法
ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名 FOREIGN KEY (本表外來鍵列名) REFERENCES 主表名(主鍵列名) ON UPDATE CASCADE ON DELETE CASCADE;
-- 刪除外來鍵約束
ALTER TABLE orderlist DROP FOREIGN KEY ou_fk1;
-- 新增外來鍵約束,同時新增級聯更新和級聯刪除
ALTER TABLE orderlist ADD CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id) ON UPDATE CASCADE ON DELETE CASCADE;
-- 將王五使用者的id修改為5 訂單表中的uid也隨之被修改
UPDATE USER SET id=5 WHERE id=3;
-- 將王五使用者刪除 訂單表中該使用者所有訂單也隨之刪除
DELETE FROM USER WHERE id=5;
多表設計
一對一(瞭解)
- 分析
- 人和身份證。一個人只有一個身份證,一個身份證只能對應一個人!
- 實現原則
- 在任意一個表建立外來鍵,去關聯另外一個表的主鍵
- SQL演示
-- 建立db5資料庫
CREATE DATABASE db5;
-- 使用db5資料庫
USE db5;
-- 建立person表
CREATE TABLE person(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
-- 新增資料
INSERT INTO person VALUES (NULL,'張三'),(NULL,'李四');
-- 建立card表
CREATE TABLE card(
id INT PRIMARY KEY AUTO_INCREMENT,
number VARCHAR(50),
pid INT UNIQUE,
CONSTRAINT cp_fk1 FOREIGN KEY (pid) REFERENCES person(id) -- 新增外來鍵
);
-- 新增資料
INSERT INTO card VALUES (NULL,'12345',1),(NULL,'56789',2);
- 圖解
一對多
- 分析
- 使用者和訂單。一個使用者可以有多個訂單!
- 商品分類和商品。一個分類下可以有多個商品!
- 實現原則
- 在多的一方,建立外來鍵約束,來關聯一的一方主鍵
- SQL演示
/*
使用者和訂單
*/
-- 建立user表
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
-- 新增資料
INSERT INTO USER VALUES (NULL,'張三'),(NULL,'李四');
-- 建立orderlist表
CREATE TABLE orderlist(
id INT PRIMARY KEY AUTO_INCREMENT,
number VARCHAR(20),
uid INT,
CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id) -- 新增外來鍵約束
);
-- 新增資料
INSERT INTO orderlist VALUES (NULL,'hm001',1),(NULL,'hm002',1),(NULL,'hm003',2),(NULL,'hm004',2);
/*
商品分類和商品
*/
-- 建立category表
CREATE TABLE category(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10)
);
-- 新增資料
INSERT INTO category VALUES (NULL,'手機數碼'),(NULL,'電腦辦公');
-- 建立product表
CREATE TABLE product(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30),
cid INT,
CONSTRAINT pc_fk1 FOREIGN KEY (cid) REFERENCES category(id) -- 新增外來鍵約束
);
-- 新增資料
INSERT INTO product VALUES (NULL,'華為P30',1),(NULL,'小米note3',1),
(NULL,'聯想電腦',2),(NULL,'蘋果電腦',2);
- 圖解
多對多
- 分析
- 學生和課程。一個學生可以選擇多個課程,一個課程也可以被多個學生選擇!
- 實現原則
- 需要藉助第三張表中間表,中間表至少包含兩個列,這兩個列作為中間表的外來鍵,分別關聯兩張表的主鍵
- SQL演示
-- 建立student表
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
-- 新增資料
INSERT INTO student VALUES (NULL,'張三'),(NULL,'李四');
-- 建立course表
CREATE TABLE course(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10)
);
-- 新增資料
INSERT INTO course VALUES (NULL,'語文'),(NULL,'數學');
-- 建立中間表
CREATE TABLE stu_course(
id INT PRIMARY KEY AUTO_INCREMENT,
sid INT, -- 用於和student表的id進行外來鍵關聯
cid INT, -- 用於和course表的id進行外來鍵關聯
CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id), -- 新增外來鍵約束
CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id) -- 新增外來鍵約束
);
-- 新增資料
INSERT INTO stu_course VALUES (NULL,1,1),(NULL,1,2),(NULL,2,1),(NULL,2,2);
- 圖解
多表查詢
多表查詢-資料準備
- SQL語句
-- 建立db6資料庫
CREATE DATABASE db6;
-- 使用db6資料庫
USE db6;
-- 建立user表
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT, -- 使用者id
NAME VARCHAR(20), -- 使用者姓名
age INT -- 使用者年齡
);
-- 新增資料
INSERT INTO USER VALUES (1,'張三',23);
INSERT INTO USER VALUES (2,'李四',24);
INSERT INTO USER VALUES (3,'王五',25);
INSERT INTO USER VALUES (4,'趙六',26);
-- 訂單表
CREATE TABLE orderlist(
id INT PRIMARY KEY AUTO_INCREMENT, -- 訂單id
number VARCHAR(30), -- 訂單編號
uid INT, -- 外來鍵欄位
CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id)
);
-- 新增資料
INSERT INTO orderlist VALUES (1,'hm001',1);
INSERT INTO orderlist VALUES (2,'hm002',1);
INSERT INTO orderlist VALUES (3,'hm003',2);
INSERT INTO orderlist VALUES (4,'hm004',2);
INSERT INTO orderlist VALUES (5,'hm005',3);
INSERT INTO orderlist VALUES (6,'hm006',3);
INSERT INTO orderlist VALUES (7,'hm007',NULL);
-- 商品分類表
CREATE TABLE category(
id INT PRIMARY KEY AUTO_INCREMENT, -- 商品分類id
NAME VARCHAR(10) -- 商品分類名稱
);
-- 新增資料
INSERT INTO category VALUES (1,'手機數碼');
INSERT INTO category VALUES (2,'電腦辦公');
INSERT INTO category VALUES (3,'菸酒茶糖');
INSERT INTO category VALUES (4,'鞋靴箱包');
-- 商品表
CREATE TABLE product(
id INT PRIMARY KEY AUTO_INCREMENT, -- 商品id
NAME VARCHAR(30), -- 商品名稱
cid INT, -- 外來鍵欄位
CONSTRAINT cp_fk1 FOREIGN KEY (cid) REFERENCES category(id)
);
-- 新增資料
INSERT INTO product VALUES (1,'華為手機',1);
INSERT INTO product VALUES (2,'小米手機',1);
INSERT INTO product VALUES (3,'聯想電腦',2);
INSERT INTO product VALUES (4,'蘋果電腦',2);
INSERT INTO product VALUES (5,'中華香菸',3);
INSERT INTO product VALUES (6,'玉溪香菸',3);
INSERT INTO product VALUES (7,'計生用品',NULL);
-- 中間表
CREATE TABLE us_pro(
upid INT PRIMARY KEY AUTO_INCREMENT, -- 中間表id
uid INT, -- 外來鍵欄位。需要和使用者表的主鍵產生關聯
pid INT, -- 外來鍵欄位。需要和商品表的主鍵產生關聯
CONSTRAINT up_fk1 FOREIGN KEY (uid) REFERENCES USER(id),
CONSTRAINT up_fk2 FOREIGN KEY (pid) REFERENCES product(id)
);
-- 新增資料
INSERT INTO us_pro VALUES (NULL,1,1);
INSERT INTO us_pro VALUES (NULL,1,2);
INSERT INTO us_pro VALUES (NULL,1,3);
INSERT INTO us_pro VALUES (NULL,1,4);
INSERT INTO us_pro VALUES (NULL,1,5);
INSERT INTO us_pro VALUES (NULL,1,6);
INSERT INTO us_pro VALUES (NULL,1,7);
INSERT INTO us_pro VALUES (NULL,2,1);
INSERT INTO us_pro VALUES (NULL,2,2);
INSERT INTO us_pro VALUES (NULL,2,3);
INSERT INTO us_pro VALUES (NULL,2,4);
INSERT INTO us_pro VALUES (NULL,2,5);
INSERT INTO us_pro VALUES (NULL,2,6);
INSERT INTO us_pro VALUES (NULL,2,7);
INSERT INTO us_pro VALUES (NULL,3,1);
INSERT INTO us_pro VALUES (NULL,3,2);
INSERT INTO us_pro VALUES (NULL,3,3);
INSERT INTO us_pro VALUES (NULL,3,4);
INSERT INTO us_pro VALUES (NULL,3,5);
INSERT INTO us_pro VALUES (NULL,3,6);
INSERT INTO us_pro VALUES (NULL,3,7);
INSERT INTO us_pro VALUES (NULL,4,1);
INSERT INTO us_pro VALUES (NULL,4,2);
INSERT INTO us_pro VALUES (NULL,4,3);
INSERT INTO us_pro VALUES (NULL,4,4);
INSERT INTO us_pro VALUES (NULL,4,5);
INSERT INTO us_pro VALUES (NULL,4,6);
INSERT INTO us_pro VALUES (NULL,4,7);
- 架構器圖解
多表查詢-笛卡爾積查詢(瞭解)
- 有兩張表,獲取這兩個表的所有組合情況
- 要完成多表查詢,需要消除這些沒有用的資料
- 多表查詢格式
SELECT
列名列表
FROM
表名列表
WHERE
條件...
- 笛卡爾積查詢
-- 標準語法
SELECT 列名 FROM 表名1,表名2,...;
-- 查詢user表和orderlist表
SELECT * FROM USER,orderlist;
多表查詢-內連線查詢
- 查詢原理
- 內連線查詢的是兩張表有交集的部分資料(有主外來鍵關聯的資料)
- 顯式內連線
-- 標準語法
SELECT 列名 FROM 表名1 [INNER] JOIN 表名2 ON 條件;
-- 查詢使用者資訊和對應的訂單資訊
SELECT * FROM USER INNER JOIN orderlist ON user.id=orderlist.uid;
SELECT * FROM USER JOIN orderlist ON user.id=orderlist.uid;
-- 查詢使用者資訊和對應的訂單資訊,起別名
SELECT * FROM USER u JOIN orderlist o ON u.id=o.uid;
-- 查詢使用者姓名,年齡。和訂單編號
SELECT
u.`name`, -- 姓名
u.`age`, -- 年齡
o.`number` -- 訂單編號
FROM
USER u -- 使用者表
JOIN
orderlist o -- 訂單表
ON
u.`id` = o.`uid`;
- 隱式內連線
-- 標準語法
SELECT 列名 FROM 表名1,表名2 WHERE 條件;
-- 查詢使用者姓名,年齡。和訂單編號
SELECT
u.`name`, -- 姓名
u.`age`, -- 年齡
o.`number` -- 訂單編號
FROM
USER u, -- 使用者表
orderlist o -- 訂單表
WHERE
u.`id`=o.`uid`;
多表查詢-外連線查詢
-
左外連線
- 查詢原理
- 查詢左表的全部資料,和左右兩張表有交集部分的資料
- 基本演示
- 查詢原理
-- 標準語法
SELECT 列名 FROM 表名1 LEFT [OUTER] JOIN 表名2 ON 條件;
-- 查詢所有使用者資訊,以及使用者對應的訂單資訊
SELECT
u.`name`, -- 姓名
u.`age`, -- 年齡
o.`number` -- 訂單編號
FROM
USER u -- 使用者表
LEFT OUTER JOIN
orderlist o -- 訂單表
ON
u.`id`=o.`uid`;
-
右外連線
- 查詢原理
- 查詢右表的全部資料,和左右兩張表有交集部分的資料
- 基本演示
- 查詢原理
-- 基本語法
SELECT 列名 FROM 表名1 RIGHT [OUTER] JOIN 表名2 ON 條件;
-- 查詢所有訂單資訊,以及訂單所屬的使用者資訊
SELECT
u.`name`, -- 姓名
u.`age`, -- 年齡
o.`number` -- 訂單編號
FROM
USER u -- 使用者表
RIGHT OUTER JOIN
orderlist o -- 訂單表
ON
u.`id`=o.`uid`;
多表查詢-子查詢
-
子查詢介紹
- 查詢語句中巢狀了查詢語句。我們就將巢狀查詢稱為子查詢!
-
子查詢-結果是單行單列的
- 可以作為條件,使用運算子進行判斷!
- 基本演示
-- 標準語法
SELECT 列名 FROM 表名 WHERE 列名=(SELECT 聚合函式(列名) FROM 表名 [WHERE 條件]);
-- 查詢年齡最高的使用者姓名
SELECT MAX(age) FROM USER; -- 查詢出最高年齡
SELECT NAME,age FROM USER WHERE age=26; -- 根據查詢出來的最高年齡,查詢姓名和年齡
SELECT NAME,age FROM USER WHERE age = (SELECT MAX(age) FROM USER);
-
子查詢-結果是多行單列的
- 可以作為條件,使用運算子in或not in進行判斷!
- 基本演示
-- 標準語法
SELECT 列名 FROM 表名 WHERE 列名 [NOT] IN (SELECT 列名 FROM 表名 [WHERE 條件]);
-- 查詢張三和李四的訂單資訊
SELECT id FROM USER WHERE NAME='張三' OR NAME='李四'; -- 查詢張三和李四使用者的id
SELECT number,uid FROM orderlist WHERE uid=1 OR uid=2; -- 根據id查詢訂單
SELECT number,uid FROM orderlist WHERE uid IN (SELECT id FROM USER WHERE NAME='張三' OR NAME='李四');
-
子查詢-結果是多行多列的
- 可以作為一張虛擬表參與查詢!
- 基本演示
-- 標準語法
SELECT 列名 FROM 表名 [別名],(SELECT 列名 FROM 表名 [WHERE 條件]) [別名] [WHERE 條件];
-- 查詢訂單表中id大於4的訂單資訊和所屬使用者資訊
SELECT * FROM USER u,(SELECT * FROM orderlist WHERE id>4) o WHERE u.id=o.uid;
多表查詢練習
- 查詢使用者的編號、姓名、年齡。訂單編號
/*
分析:
使用者的編號、姓名、年齡 user表 訂單編號 orderlist表
條件:user.id = orderlist.uid
*/
SELECT
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者姓名
t1.`age`, -- 使用者年齡
t2.`number` -- 訂單編號
FROM
USER t1, -- 使用者表
orderlist t2 -- 訂單表
WHERE
t1.`id` = t2.`uid`;
- 查詢所有的使用者。使用者的編號、姓名、年齡。訂單編號
/*
分析:
使用者的編號、姓名、年齡 user表 訂單編號 orderlist表
條件:user.id = orderlist.uid
查詢所有使用者,使用左外連線
*/
SELECT
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者姓名
t1.`age`, -- 使用者年齡
t2.`number` -- 訂單編號
FROM
USER t1 -- 使用者表
LEFT OUTER JOIN
orderlist t2 -- 訂單表
ON
t1.`id` = t2.`uid`;
- 查詢所有的訂單。使用者的編號、姓名、年齡。訂單編號
/*
分析:
使用者的編號、姓名、年齡 user表 訂單編號 orderlist表
條件:user.id = orderlist.uid
查詢所有訂單,使用右外連線
*/
SELECT
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者姓名
t1.`age`, -- 使用者年齡
t2.`number` -- 訂單編號
FROM
USER t1 -- 使用者表
RIGHT OUTER JOIN
orderlist t2 -- 訂單表
ON
t1.`id` = t2.`uid`;
- 查詢使用者年齡大於23歲的資訊。顯示使用者的編號、姓名、年齡。訂單編號
/*
分析:
使用者的編號、姓名、年齡 user表 訂單編號 orderlist表
條件:user.age > 23 AND user.id = orderlist.uid
*/
/*
select
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者姓名
t1.`age`, -- 使用者年齡
t2.`number` -- 訂單編號
from
user t1, -- 使用者表
orderlist t2 -- 訂單表
where
t1.`age` > 23
and
t1.`id` = t2.`uid`;
*/
SELECT
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者姓名
t1.`age`, -- 使用者年齡
t2.`number` -- 訂單編號
FROM
USER t1 -- 使用者表
LEFT OUTER JOIN
orderlist t2 -- 訂單表
ON
t1.`id` = t2.`uid`
WHERE
t1.`age` > 23;
- 查詢張三和李四使用者的資訊。顯示使用者的編號、姓名、年齡。訂單編號
/*
分析:
使用者的編號、姓名、年齡 user表 訂單編號 orderlist表
條件:user.id = orderlist.uid AND user.name IN ('張三','李四');
*/
SELECT
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者姓名
t1.`age`, -- 使用者年齡
t2.`number` -- 訂單編號
FROM
USER t1, -- 使用者表
orderlist t2 -- 訂單表
WHERE
t1.`id` = t2.`uid`
AND
-- (t1.`name` = '張三' OR t1.`name` = '李四');
t1.`name` IN ('張三','李四');
- 查詢商品分類的編號、分類名稱。分類下的商品名稱
/*
分析:
商品分類的編號、分類名稱 category表 分類下的商品名稱 product表
條件:category.id = product.cid
*/
SELECT
t1.`id`, -- 分類編號
t1.`name`, -- 分類名稱
t2.`name` -- 商品名稱
FROM
category t1, -- 商品分類表
product t2 -- 商品表
WHERE
t1.`id` = t2.`cid`;
- 查詢所有的商品分類。商品分類的編號、分類名稱。分類下的商品名稱
/*
分析:
商品分類的編號、分類名稱 category表 分類下的商品名稱 product表
條件:category.id = product.cid
查詢所有的商品分類,使用左外連線
*/
SELECT
t1.`id`, -- 分類編號
t1.`name`, -- 分類名稱
t2.`name` -- 商品名稱
FROM
category t1 -- 商品分類表
LEFT OUTER JOIN
product t2 -- 商品表
ON
t1.`id` = t2.`cid`;
- 查詢所有的商品資訊。商品分類的編號、分類名稱。分類下的商品名稱
/*
分析:
商品分類的編號、分類名稱 category表 分類下的商品名稱 product表
條件:category.id = product.cid
查詢所有的商品資訊,使用右外連線
*/
SELECT
t1.`id`, -- 分類編號
t1.`name`, -- 分類名稱
t2.`name` -- 商品名稱
FROM
category t1 -- 商品分類表
RIGHT OUTER JOIN
product t2 -- 商品表
ON
t1.`id` = t2.`cid`;
- 查詢所有的使用者和所有的商品。顯示使用者的編號、姓名、年齡。商品名稱
/*
分析:
使用者的編號、姓名、年齡 user表 商品名稱 product表 中間表 us_pro
條件:us_pro.uid = user.id AND us_pro.pid = product.id
*/
SELECT
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者名稱稱
t1.`age`, -- 使用者年齡
t2.`name` -- 商品名稱
FROM
USER t1, -- 使用者表
product t2, -- 商品表
us_pro t3 -- 中間表
WHERE
t3.`uid` = t1.`id`
AND
t3.`pid` = t2.`id`;
- 查詢張三和李四這兩個使用者可以看到的商品。顯示使用者的編號、姓名、年齡。商品名稱
/*
分析:
使用者的編號、姓名、年齡 user表 商品名稱 product表 中間表 us_pro
條件:us_pro.uid = user.id AND us_pro.pid = product.id AND user.name IN ('張三','李四')
*/
SELECT
t1.`id`, -- 使用者編號
t1.`name`, -- 使用者名稱稱
t1.`age`, -- 使用者年齡
t2.`name` -- 商品名稱
FROM
USER t1, -- 使用者表
product t2, -- 商品表
us_pro t3 -- 中間表
WHERE
(t3.`uid` = t1.`id` AND t3.`pid` = t2.`id`)
AND
-- (t1.`name` = '張三' or t1.`name` = '李四');
t1.`name` IN ('張三','李四');
多表查詢-自關聯查詢
- 自關聯查詢介紹
- 同一張表中有資料關聯。可以多次查詢這同一個表!
- 自關聯查詢演示
-- 建立員工表
CREATE TABLE employee(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
mgr INT,
salary DOUBLE
);
-- 新增資料
INSERT INTO employee VALUES (1001,'孫悟空',1005,9000.00),
(1002,'豬八戒',1005,8000.00),
(1003,'沙和尚',1005,8500.00),
(1004,'小白龍',1005,7900.00),
(1005,'唐僧',NULL,15000.00),
(1006,'武松',1009,7600.00),
(1007,'李逵',1009,7400.00),
(1008,'林沖',1009,8100.00),
(1009,'宋江',NULL,16000.00);
-- 查詢所有員工的姓名及其直接上級的姓名,沒有上級的員工也需要查詢
/*
分析:
員工姓名 employee表 直接上級姓名 employee表
條件:employee.mgr = employee.id
查詢左表的全部資料,和左右兩張表交集部分資料,使用左外連線
*/
SELECT
t1.name, -- 員工姓名
t1.mgr, -- 上級編號
t2.id, -- 員工編號
t2.name -- 員工姓名
FROM
employee t1 -- 員工表
LEFT OUTER JOIN
employee t2 -- 員工表
ON
t1.mgr = t2.id;
檢視
檢視的概念
- 檢視是一種虛擬存在的資料表
- 這個虛擬的表並不在資料庫中實際存在
- 作用是將一些比較複雜的查詢語句的結果,封裝到一個虛擬表中。後期再有相同複雜查詢時,直接查詢這張虛擬表即可
- 說白了,檢視就是將一條SELECT查詢語句的結果封裝到了一個虛擬表中,所以我們在建立檢視的時候,工作重心就要放在這條SELECT查詢語句上
檢視的好處
- 簡單
- 對於使用檢視的使用者不需要關心表的結構、關聯條件和篩選條件。因為這張虛擬表中儲存的就是已經過濾好條件的結果集
- 安全
- 檢視可以設定許可權 , 致使訪問檢視的使用者只能訪問他們被允許查詢的結果集
- 資料獨立
- 一旦檢視的結構確定了,可以遮蔽表結構變化對使用者的影響,源表增加列對檢視沒有影響;源表修改列名,則可以通過修改檢視來解決,不會造成對訪問者的影響
檢視資料準備
-- 建立db7資料庫
CREATE DATABASE db7;
-- 使用db7資料庫
USE db7;
-- 建立country表
CREATE TABLE country(
id INT PRIMARY KEY AUTO_INCREMENT,
country_name VARCHAR(30)
);
-- 新增資料
INSERT INTO country VALUES (NULL,'中國'),(NULL,'美國'),(NULL,'俄羅斯');
-- 建立city表
CREATE TABLE city(
id INT PRIMARY KEY AUTO_INCREMENT,
city_name VARCHAR(30),
cid INT, -- 外來鍵列。關聯country表的主鍵列id
CONSTRAINT cc_fk1 FOREIGN KEY (cid) REFERENCES country(id)
);
-- 新增資料
INSERT INTO city VALUES (NULL,'北京',1),(NULL,'上海',1),(NULL,'紐約',2),(NULL,'莫斯科',3);
檢視的建立
- 建立檢視語法
-- 標準語法
CREATE VIEW 檢視名稱 [(列名列表)] AS 查詢語句;
- 普通多表查詢,查詢城市和所屬國家
-- 普通多表查詢,查詢城市和所屬國家
SELECT
t1.*,
t2.country_name
FROM
city t1,
country t2
WHERE
t1.cid = t2.id;
-- 經常需要查詢這樣的資料,就可以建立一個檢視
- 建立檢視基本演示
-- 建立一個檢視。將查詢出來的結果儲存到這張虛擬表中
CREATE
VIEW
city_country
AS
SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;
- 建立檢視並指定列名基本演示
-- 建立一個檢視,指定列名。將查詢出來的結果儲存到這張虛擬表中
CREATE
VIEW
city_country2 (city_id,city_name,cid,country_name)
AS
SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;
檢視的查詢
- 查詢檢視語法
-- 標準語法
SELECT * FROM 檢視名稱;
- 查詢檢視基本演示
-- 查詢檢視。查詢這張虛擬表,就等效於查詢城市和所屬國家
SELECT * FROM city_country;
-- 查詢指定列名的檢視
SELECT * FROM city_country2;
-- 查詢所有資料表,檢視也會查詢出來
SHOW TABLES;
- 查詢檢視建立語法
-- 標準語法
SHOW CREATE VIEW 檢視名稱;
- 查詢檢視建立語句基本演示
SHOW CREATE VIEW city_country;
檢視的修改
- 修改檢視表中的資料
-- 標準語法
UPDATE 檢視名稱 SET 列名=值 WHERE 條件;
-- 修改檢視表中的城市名稱北京為北京市
UPDATE city_country SET city_name='北京市' WHERE city_name='北京';
-- 查詢檢視
SELECT * FROM city_country;
-- 查詢city表,北京也修改為了北京市
SELECT * FROM city;
-- 注意:檢視表資料修改,會自動修改源表中的資料
- 修改檢視表結構
-- 標準語法
ALTER VIEW 檢視名稱 [(列名列表)] AS 查詢語句;
-- 查詢檢視2
SELECT * FROM city_country2;
-- 修改檢視2的列名city_id為id
ALTER
VIEW
city_country2 (id,city_name,cid,country_name)
AS
SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;
檢視的刪除
- 刪除檢視
-- 標準語法
DROP VIEW [IF EXISTS] 檢視名稱;
-- 刪除檢視
DROP VIEW city_country;
-- 刪除檢視2,如果存在則刪除
DROP VIEW IF EXISTS city_country2;
檢視的總結
- 檢視是一種虛擬存在的資料表
- 這個虛擬的表並不在資料庫中實際存在
- 說白了,檢視就是將一條SELECT查詢語句的結果封裝到了一個虛擬表中,所以我們在建立檢視的時候,工作重心就要放在這條SELECT查詢語句上
- 檢視的好處
- 簡單
- 安全
- 資料獨立
備份與還原
命令列方式
-
備份
- 使用SecureCRT工具連線到Linux系統,輸入:mysqldump -u root -p 資料庫名稱 > 檔案儲存路徑
mysqldump -u root -p db1 > /root/mysql/db1.sql
- 進入檔案儲存路徑,檢視檔案是否存在
cd mysql
ls
-
恢復
- 登入mysql資料庫
mysql -u root -p
- 刪除已經備份的資料庫
drop database db1
- 重新建立名稱相同的資料庫
create database db1;
- 使用該資料庫
use db1;
- 匯入檔案執行:source 備份檔案路徑;
source /root/mysql/db1.sql;
圖形化介面方式
- 備份
- 恢復