mysql基础入门(参照b站黑马程序员整理)
mysql 基礎
一、 概述:
1、課程內容和數據相關概念
? 數據庫的概念:存儲數據的倉庫,數據是又組織的進行存儲
? 數據庫管理系統:操作和管理數據庫的大型軟件
? SQL: 操作關系型數據庫的編程語言,定義了一套操作關系型數據庫統一標準
2、關系型數據庫:
? 建立在關系模型基礎上,由多張表相關連接的二維表組成的數據庫
? 數據模型:
? 客戶端 --> DBMS --> 數據庫1、數據庫2 --> 表1、表2
二、SQL
? 1、SQL通用語法:關鍵字建議大寫
? 2、SQL分類:DDL(Data Definition Language)、DML(Data Manipulation Language)、DQL(Data Query Language)、DCL(Data Control Language).
? 3、DDL: 數據庫定義語言,創建數據庫、創建表
? a、查詢數據庫:
? 語法: SHOW DATABASES; —> 查詢所有數據庫
? 語法: SELECT DATABASE(); —>查詢當前數據庫
? b、創建數據庫
? 語法: CREATE DATABASE [ IF NOT EXISTS ] 數據庫名 [ DEFAULT CHARSET 字符集(UTF-8)] [ COLLATE 排序規則 ];
? c、刪除數據庫
? 語法: DROP DATABASE [ IF EXISTS ] 數據庫名;
? d、使用數據庫
? 語法: USE 數據庫名;
? e、表操作-> 創建&查詢表
? 使用數據庫后,查看表 :SHOW TABLES;
? 查詢表結構 :DESC 表名;
? 查詢指標的創建語句 : SHOW CREATE TABLE 表名;
? 創建表結構:
? 語法:CREATE TABLE 表名(
? 字段1 字段1類型 [ COMMENT 字段1 注釋 ],
? 字段2 字段2類型 [ COMMENT 字段2 注釋 ],
? ……
? 字段n 字段n類型 [ COMMENT 字段n 注釋 ]
? ) [ COMMENT 表注釋 ];
? f、 表操作 --> 數據類型:mysql 數據類型分為很多,主流的是數值型、字符串類型、日 期時間類型
? 01: MySQL 數值數據類型
? 02:MySQL 字符串數據類型
? char 和 vachar 相比 char的性能比vachar 的性能更好。
? 03: MySQL 日期型數據類型
? 04 : 案例:
? g 表操作–>修改
? 01 添加字段:ALTER TABLE 表名 ADD 字段名 字段類型[(長度)] [COMMENT ‘備注‘] [約束];
? 02 修改字段:
? 修改字段類型:
? 語法:ALTER TABLE 表名 MODIFY 字段名 新數據類型 [(長度)] ;
? 修改字段名和字段類型:
? 語法:ALTER TABLE 表名 CHANGE 字段名 新字段名 數據類型[(長度)] [COMMENT ‘備注’] [約束];
? 案例 : 將tb_emp 的nickname修改為username 數據類型為 varchar(30)
? ALTER TABLE tb_emp CHANGE nickname username varchar(30);
? 03 刪除表字段
? 語法:ALTER TABLE 表名 DROP 字段名;
? 案例 :刪除 tb_emp的username 字段;
? 語法:ALTER TABLE tb_emp DROP username;
? 04 修改表名
? ALTER TABLE 表名 RENAME TO 新表名;
? 案例: 修改tb_emp 的表名為 tb_employee
? 語法: ALTER TABLE tb_emp RENAME TO tb_employee;
? 05 表操作 -->刪除表: 刪除表時,表的數據也會被刪除。
? 刪除指定表 不安全模式,刪除表后 無法恢復 慎用
? 語法: DROP TABLE [ IF EXISTS ] 表名;
? 刪除指定表,并重新創建一個具有相同結構的空表
? 語法: TRUNCATE TABLE 表名;
? 案例: 刪除tb_user 表 DROP TABLE IF EXISTS tb_user;
? 案例: 刪除 tb_employee 表 并保留其表結構
? 語法: TRUNCATE TABLE tb_employee;
? 4、DML: 數據庫操作語言,用于對數據表中的數據進行增刪改操作
? a、INSERT 插入(增加)數據(黑馬 P12課程 需要重新觀看一次)
? 給指定字段插入數據:
? 語法: INSERT INTO 表名 (字段名1,字段名2,…) VALUES (value1,value2,…);
? 備注: 字段名1和value1 對應 字段名2 和value2 對應,…
? 給表的全部字段插入數據
? 語法: INSERT INTO 表名 VALUES (值1,值2,…);
? 備注: 此時必須將值的數據全部和字段進行對應
? 批量插入:
? 語法: INSERT INTO 表名 (字段名1,字段名2,…) VALUES (value1,value2,…),(value1,value2,…),(value1,value2,…),…;
? 語法: INSERT INTO 表名 VALUES (值1,值2,…),(值1,值2,…),(值1,值2,…),…;
? 注意:插入數據時,字段的順序要和給定的值的順序一一對應,字符串和日期應該包含在引號中,給定的數值不能超過字段定義的大小
? b、UPDATE 修改數據
? 語法: UPDATE 表名 SET 字段1=值1,字段2=值2,… [WHERE 條件…];
? 注意: 修改語句的條件可以有,也可以沒有,如果沒有條件,那么會修改整個表的數據
? 案例:
# 案例 將所有員工的入職日期修改為“2021-01-18” update tb_employee SET entry='2021-01-18';? c、DELETE 刪除數據
? DELETE 語句的條件可以有,也可以沒有,如果沒有條件,那么會刪除整張表的數據 DELETE 語句不能刪除某一個字段的值(可以使用update 語句)
? 語法: DELETE FROM 表名 WHERE 條件
? 5、DQL: 數據庫查詢語言,用來查詢數據庫中的表記錄
? 查詢關鍵字 SELECT
? 完整格式
? 語法: SELECT * [ 字段1 [ AS 別名 ],字段2,… ] FROM 表名1 [ AS 別名 ],[ 表名2,… ] [ WHERE 條件1 AND 條件2 AND… ] [ GROUP BY 分組字段1,分組字段2,… ] [ HAVING 分組后條件列表 ] [ ORDER BY 排序字段列表 ] [ LIMIT 分頁參數 ]
? 如圖:
? a、基本查詢:
? 01: 查詢多個字段 SELECT 字段列表 FROM 表名
? 語法: SELECT * FROM 表名;
? 語法: SELECT 字段1 [AS 別名1],字段2 [AS 別名2],… FROM 表名;
? 去除重復記錄: DISTINCT 關鍵字 , 語法:SELECT DISTINCT 字段列表 FROM 表名;
? 案例: 見下方腳本塊
DROP TABLE IF EXISTS employee;# 創建表 employee CREATE TABLE employee (id int COMMENT '編號',workno VARCHAR(10) COMMENT '員工編號',name VARCHAR(10) COMMENT '員工姓名',gender CHAR(1) COMMENT '性別',age TINYINT UNSIGNED COMMENT '年齡',idcard CHAR(18) COMMENT '身份證',workaddress varchar(50) COMMENT '工作地址',entry DATE COMMENT '入職時間' ) COMMENT '員工表';# 插入 數據 INSERT INTO employee(id, workno, name, gender, age, idcard, workaddress, entry) values (1, '1', '柳巖', '女', 20, '123456789012345670', '北京', '2000-01-01'),(2, '2', '張無忌', '男', 18, '123456789012345671', '北京', '2005-09-01'),(3, '3', '韋一笑', '男', 38, '123456789012345672', '上海', '2005-08-01'),(4, '4', '趙敏', '女', 18, '123456789012345673', '北京', '2009-12-01'),(5, '5', '小昭', '女', 16, '123456789012345674', '上海', '2007-07-01'),(6, '6', '楊逍', '男', 28, '123456789012345675', '北京', '2006-01-01'),(7, '7', '范瑤', '男', 40, '123456789012345676', '北京', '2005-05-01'),(8, '8', '黛綺絲', '女', 38, '123456789012345677', '天津', '2015-05-01'),(9, '9', '范涼涼', '女', 45, '123456789012345678', '北京', '2010-04-01'),(10, '10', '陳丕亮', '男', 53, '123456789012345679', '上海', '2011-01-01'),(11, '11', '張士誠', '男', 55, '12345678901234567a', '江蘇', '2015-05-01'),(12, '12', '常遇春', '男', 32, '12345678901234567b', '北京', '2004-02-01'),(13, '13', '張三豐', '男', 88, '12345678901234567c', '江蘇', '2020-11-01'),(14, '14', '滅絕', '女', 65, '12345678901234567d', '北京', '2019-05-01'),(15, '15', '胡青牛', '男', 70, '12345678901234567x', '西安', '2018-04-01'),(16, '16', '周芷若', '女', 18, null, '西安', '2012-06-01');# 查詢所有字段 SELECT * FROM employee; SELECT id,name,workno,idcard,workaddress,gender,age,entry from employee;# 查詢指定字段SELECT id, name, gender FROM employee;# 查詢所有員工的工作地址 起別名SELECT workaddress as '工作地址' FROM employee;# 查詢工作地址,不重復 SELECT distinct workaddress FROM employee;? 02: 條件查詢
語法: SELECT 字段列表 FROM 表名 WHERE 條件列表;
? 案例: 見 下方代碼塊
-- 條件查詢# 1 查詢年齡等于18的員工 SELECT * FROM employee WHERE age = 18;# 2 查詢年齡小于20的員工 SELECT * FROM employee WHERE age<20;# 3 查詢年齡小于等于28的員工 SELECT * FROM employee WHERE age <=28;# 4 查詢沒有身份證號碼的員工 SELECT * FROM employee WHERE idcard is null ;# 5 查詢有身份證號碼的員工 SELECT * FROM employee WHERE idcard is not null;# 6 查詢年齡不等于88 的員工信息 SELECT * FROM employee WHERE age!= 88;# 7 查詢年齡在15歲到28歲的員工 SELECT * FROM employee WHERE age between 15 and 28;# 8 查詢性別為女的員工 SELECT * FROM employee WHERE gender = '女';# 9 查詢年齡等于18或者20 或者40 的員工 SELECT * FROM employee WHERE age in (18,20,40);# 10 查詢姓名為兩個字的員工信息 SELECT * FROM employee WHERE name like '__';# 11 查詢身份證號最后一位是X的員工 SELECT * FROM employee WHERE idcard like '%X';? 03:聚合函數
? 語法: SELECT 聚合函數( 字段名) FROM 表名;
? 案例: 見下
-- 聚合函數# 1 統計該表中的員工數量 SELECT COUNT(id) FROM employee;# 2 統計該表中的員工平均年齡 SELECT name,AVG(age) FROM employee;# 3 統計員工的最大年齡 SELECT name,MAX(age) FROM employee;# 4 統計員工的最小年齡 SELECT name,MIN(age) FROM employee;# 5 統計員工的年齡之和 SELECT SUM(age) FROM employee;? 04: 分組查詢
? 語法:SELECT 字段列表 FROM 表名 [WHERE 條件列表] GROUP BY 分組字段名[HAVING 分組后過濾條件];
? 注意: WHERE 和 HAVING 的區別
? 1: 執行的時機不同,WHERE是在分組之前執行,不滿足WHERE條件的不參與分組;而HAVING是分組之后對查詢出的結果進行過濾。
? 2: 判斷的時機不同,WHERE 不能對聚合函數進行判斷,而HAVING 能
*** 執行順序: WHERE > 聚合函數 > having
*** 分組之后,查詢的字段一般為聚合函數和分組字段,查詢其他字段沒有任何意義。
案例:
-- 分組查詢# 1 根據性別分組,統計男性員工和女性員工的數量 SELECT COUNT(gender) as '男性人數',(SELECT count(gender) FROM employee WHERE gender='女') as '女性人數' FROM employee WHERE gender='男';SELECT sum(IF(gender='男',1,0)) as '男性人數',sum(IF(gender='女',1,0)) as '女性人數' FROM employee;# 2 根據性別分組,統計男性員工和女性員工的平均年齡 SELECT gender '性別', AVG(age) '平均年齡' FROM employee GROUP BY gender;SELECT AVG(IF(gender='男',age,null)) AS '男性平均年齡', AVG(IF(gender='女',age,null)) AS '女性平均年齡' FROM employee;# 3 查詢年齡小于45的員工,并根據工作地址分組,獲取員工數量大于等于3的工作地址 SELECT workaddress,count(id) emp_sum FROM employee WHERE age<45 GROUP BY workaddress HAVING emp_sum >=3;? 05: 排序查詢
? SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1,字段2 排序方式2;
? 排序方式:
? ASC 升序 (默認值)
? DESC 降序
? 案例:
-- 排序查詢# 1 根據年齡對員工進行升序排序 SELECT * FROM employee ORDER BY age ;# 2 根據入職時間對員工降序排序 SELECT * FROM employee ORDER BY entry DESC ;# 3 根據年齡升序排序,年齡相同按照入職年齡降序排序 SELECT * FROM employee ORDER BY age asc ,entry DESC ;? 06: 分頁查詢
? SELECT 字段列表 FROM 表名 LIMIT 起始索引,查詢記錄數;
? 注意:
? 起始索引從0 開始,起始索引=(查詢頁碼-1)* 每頁記錄數據
? 分頁查詢是數據庫的方言,不同的數據庫有不同的實現,MySQL中的是LIMIT
? 如果查詢的是第一頁的數據,起始索引可以省略,直接簡寫為LIMIT10
? 案例:
-- 分頁查詢# 1 查詢第一頁的員工數據,每頁展示10條記錄 SELECT * FROM employee LIMIT 10;# 2 查詢第二頁的員工數據,每頁展示10條記錄 (2-1)*10 = 起始索引 SELECT * FROM employee LIMIT 10,10;練習 :
# 1 查詢年齡為20,21,22,23的員工信息 SELECT * FROM employee WHERE age in (20,21,22,23); SELECT * FROM employee WHERE age BETWEEN 20 AND 23;# 2 查詢性別為男,并且年齡在20-40(含)以內的姓名為三個字的員工 SELECT * FROM employee WHERE gender ='男' AND age >=20 and age <=40 and name like '___'; SELECT * FROM employee WHERE gender ='男' AND age BETWEEN 20 and 40 and name like '___';# 3 統計員工表中,年齡小于60歲,男性員工和女性員工的人數 SELECT SUM(IF(gender='男',1,0)) AS '男性人數', SUM(IF(gender='女',1,0)) AS '女性人數' FROM employee WHERE age < 60# 4 查詢所有年齡小于等于35歲員工的姓名和年齡,并對查詢結果按年齡升序排序,如果年齡相同按入職時間降序排序 SELECT name,age,entry FROM employee WHERE age <=35 ORDER BY age,entry DESC;# 5 查詢性別為男,且年齡在20-40歲(含)以內的前五個員工信息,并對查詢結果按年齡升序排序,年齡相同按入職時間升序排序 SELECT * FROM (SELECT * FROM employee WHERE gender ='男' AND age >20 and age <=40 LIMIT 5) res ORDER BY res.age,res.entry;總結:
SQL的編寫順序
SELECT 字段列表 FROM 表名列表 WHERE 條件列表 GROUP BY 分組字段列表 HAVING 分組后條件列表 ORDER BY 排序字段列表 LIMIT 分頁參數
SQL 執行順序
FROM 表名列表 WHERE 條件列表 GROUP BY 分組字段列表 HAVING 分組后條件列表 SELECT 字段列表 ORDER BY 排序字段列表 LIMIT 分頁參數
? 6、DCL: 數據庫控制語言,用來創建數據庫用戶、控制數據庫的訪問、權限
? a 、管理用戶
? 01: 查詢用戶
? Use mysql;
? SELECT * FROM user;
? 02: 創建用戶
? CREATE USER ‘用戶名‘@‘主機名‘ IDENTIFIED BY ‘密碼‘;
? 03: 修改用戶密碼
? ALTER USER ‘用戶名‘@’主機名’ IDENTIFIED WITH mysql_native_password BY ‘新密碼‘;
? 04: 刪除用戶
? DROP USER ‘用戶名‘@’主機名’ ;
? 注意: 主機名可以通過 % 來通配
案例:
-- 管理用戶 # 查詢用戶 Use mysql; SELECT * FROm user; # 創建用戶 # 1. 創建用戶 itcast 只能在當前主機localhost訪問,密碼為123456 CREATE USER 'itcast'@'localhost' IDENTIFIED BY '123456';# 2. 創建用戶 heima 可以在任意主機訪問該數據庫,密碼為123456 CREATE USER 'heima'@'%' IDENTIFIED BY '123456';# 修改用戶 # 修改用戶heima 的密碼為 1234 ALTER USER 'heima'@'%' IDENTIFIED WITH mysql_native_password by '1234';# 刪除用戶 # 刪除itcast@localhost 用戶 DROP USER 'heima'@'%'; DROP USER 'itcast'@'localhost';? b: 權限控制
? 01:查詢權限
? SHOW GRANTS FOR ‘用戶名‘@’主機名’;
? 02:授予權限
? GRANT 權限列表 ON 數據庫名.表名 TO ‘用戶名‘@’主機名’;
? 03:撤銷權限
? REVOKE 權限列表 ON 數據庫名.表名 FROM ‘用戶名‘@’主機名’;
? 注意:
? 多個權限之間通過逗號分隔。
? 授權和回收權限時,數據庫名和表名可以通過 * 來進行通配,代表所有
? 總結:
三、函數
? 1、字符串函數
練習:
-- ---------------------函數演示---------------------------- -- concat 將兩個字符串拼接 SELECT concat('hello',' mysql');-- lower 轉換成小寫 SELECT lower('HELLO');-- upper 轉換成大寫 SELECT upper('hello');-- LPAD(a,b,c),用字符c在字符a的左邊補全到b位 select LPAD('0',3,'01');SELECT LPAD('1',4,'0');-- RPAD(a,b,c) 用字符c在字符a的右邊補全到b位 SELECT RPAD('1',5,'20');-- TRIM 去除目標字符串的首尾空格 SELECT TRIM(' HELLO, WORLD ');-- SUBSTRING(str,start,len) 將字符串從指定位置起(包含,下標以1開頭)截取指定長度,并返回 SELECT SUBSTRING('HELLO,WORLD',3,3);# 1, 將企業的工號統一改為五位 如 1號員工的工號為00001 10號員工的工號為00010 update employee set workno=LPAD(workno,5,'0');? 2、數值函數
練習:
# 2 數值函數 -- CEIL(X) 對x進行向上取整 SELECT CEIL(21.2); # 22-- FLOOR(x) 對x進行向下取整 SELECT FLOOR(22.1); # 22-- MOD(x,y) 返回x/y的模(余數) SELECT MOD(22,3); # 1-- rand() 返回0-1的隨機數 SELECT RAND();-- round(x,y),求x的四舍五入的值,保留y位小數 SELECT ROUND(2.2132100212,8); #2.21321002# 通過數據庫的函數,生成一個六位數的隨機驗證碼 SELECT LPAD(ROUND(rand()*1000000,0),6,0);? 3、日期函數
練習:
-- ------------------------日期函數-------------------- # curdate() 返回當前日期 SELECT CURDATE(); # curtime() 返回當前時間 SELECT CURTIME(); # now() 返回當前時間和日期 SELECT NOW(); # YEAR(date) 獲取指定date的年份 SELECT YEAR('2021-04-21'); # MONTH(date) 獲取指定date的月份 SELECT MONTH('2022-11-20'); # DAY(date) 獲取指定date的日期 SELECT DAY('2021-11-22'); # DATE_ADD(date,INTERVAL expr type) 返回日期/時間值加上一個時間間隔expr后的時間值 SELECT DATE_ADD('2022-11-21',INTERVAL 210 year ); # DATEDIFF(DATE1,DATE2) 返回起始時間DATE1 和結束時間DATE2之間的天數,一般較大的日期放在第一個參數,較小的日期放在第二個參數上 SELECT DATEDIFF('2022-11-22','2022-04-21');# 查詢所有員工的入職天數,并根據入職天數倒序排序 SELECT * FROM (SELECT DATEDIFF(CURDATE(),entry) as day_from_now FROM employee) res ORDER BY res.day_from_now desc;SELECT DATEDIFF(CURDATE(),entry) AS '入職天數' FROM employee ORDER BY entry asc ;? 4、流程函數
練習:
-- ------------------------流程函數-------------------- # IF(condition,t,f) 如果滿足condition 條件,那么值為t ,否則為f SELECT IF(true,'ok','error');SELECT IF(false,'ok','ERROR');# IFNULL(VALUE1,VALUE2) 如果VALUE1不為空,返回VALUE1 ,否則返回VALUE2 SELECT IFNULL('ok','default');SELECT IFNULL('','default');SELECT IFNULL(null,'default');# CASE WHEN [val1] THEN[res1] ... ELSE[DEFAULT] END 如果val1為true,返回res1,否則返回default默認值 SELECT CASE WHEN 1=2 THEN 'ok' else 'default' end; # 查詢員工表中的姓名和工作地址(北京/上海----> 一線城市, 其他的二線城市) SELECT name , (CASE WHEN workaddress in('北京','上海') THEN '一線城市' ELSE '二線城市' END) AS '工作地址' FROM employee ;SELECT name, (case workaddress when '上海' then '一線城市' when '北京' then '一線城市' else '二線城市' end) as '工作地址' FROM employee;# case[expr] WHEN [val1] THEN [res1]... ELSE[DEFAULT] END 如果expr的值等于val1, 返回res1,... 否則返回default 默認值 SELECT case 1 WHEN 2 THEN 'ok' ELSE 'default' END;總結:
四、約束
? 01:表內約束
概念:約束是作用于表中字段上的規則,用戶限制存儲在表中的數據
目的: 保證數據庫中數據的正確性、有效性和完整性。
分類:
| 非空約束 | 限制該字段的數據不能為null | NOT NULL |
| 唯一約束 | 保證該字段的所有數據都是唯一、不重復的 | UNIQUE |
| 主鍵約束 | 主鍵是一行數據的唯一標識,要求非空且唯一 | PRIMARY KEY |
| 默認約束 | 保存數據時,如果未指定該字段的值,則采用默認值 | DEFAULT |
| 檢查約束(8.0.16 版本之后) | 保證字段值滿足某一個條件 | CHECK |
| 外鍵約束 | 用來讓兩張表的數據之間建立連接,保證數據的一致性和完整性 | FOREIGN KEY |
注意: 約束是作用域表字段上的,可以通過創建表和修改表的時候添加約束。
約束演示:
外鍵約束:
? 概念:外鍵用來讓兩張表的數據之間建立連接,從而保證數據的一致性和完整性
創建員工和部門表
DROP DATABASE IF EXISTS itheima; CREATE DATABASE itheima; use itheima; DROP TABLE IF EXISTS dept; CREATE TABLE dept(id int auto_increment primary key comment '主鍵,id唯一標識符',deptName varchar(50) not null comment '部門名稱' ) comment '部門表'; INSERT INTO dept (id, deptName) VALUES (1,'研發部'), (2,'市場部'), (3,'財務部'), (4,'銷售部'), (5,'總經辦');DROP TABLE IF EXISTS emp; CREATE TABLE emp(id int auto_increment primary key comment'編號,唯一標識符',name varchar(50) not null comment '姓名',age int comment '年齡',job varchar(50) comment '職位',salary int comment '薪資',entrydate date comment '入職時間',managerid int comment '直系領導ID',dept_id int comment '部門ID' ) COMMENT '員工表'; # alter table emp add age int comment '年齡';INSERT INTO emp(id, name,age,job, salary, entrydate, managerid, dept_id) VALUES(1,'金庸',66,'總裁',20000,'2000-01-01',null,5),(2,'張無忌',20,'項目經理',15200,'2005-01-01',1,1),(3,'楊瀟',33,'開發',8400,'2011-01-01',2,1),(4,'韋一笑',48,'開發',11000,'2006-01-01',2,1),(5,'常遇春',43,'開發',10500,'2002-01-01',2,1),(6,'小昭',19,'開發實習生',3200,'2018-01-01',2,1);部門表和員工表在在數據庫層面沒有創建外鍵管理,不能保證數據的一致性和完整性。
添加外鍵的語法:
CREATE TABLE 表名(字段名 數據類型.....[CONSTRAINT] [外鍵名稱] FOREIGN KEY (外鍵字段名稱) REFERENCES 主表(主表列名) );ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵字段名稱) REFERENCES 主表(主表列名);案例:
-- 添加外鍵 ALTER TABLE emp ADD CONSTRAINT fk_emp_deptId_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id); -- 刪除外鍵 ALTER TABLE emp drop foreign key fk_emp_deptId_dept_id;外鍵約束:
刪除/更新行為:
語法:
ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵字段) REFERENCES 主表名(主表字段) ON UPDATE CASCADE ON DELETE CASCADE;
案例:
-- 添加外鍵 ALTER TABLE emp ADD CONSTRAINT fk_emp_deptId_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id); -- 刪除外鍵 ALTER TABLE emp drop foreign key fk_emp_deptId_dept_id;ALTER TABLE emp add constraint fk_emp_deptId_dept_id foreign key(dept_id) references dept(id) ON DELETE cascade on UPDATE cascade;總結:
五、多表查詢
? 01:多表關系
? 在實際項目開發過程中,會根據業務需求及業務模塊之間的關系,分析并設計表結構,基于業務之間相互關聯,所以各個表之間也存在相互關聯關系,具體分為三種,如:
? 一對一:
? 案例: 用戶與用戶詳情的關系
? 關系: 一對一關系,多用于單表拆分,將一張表的基礎子彈放在一張表中其他詳情字段放在另一張表中,用以提升效率。
?
? 一對多(多對一):
? 案例: 一個部門對應多個員工,一個員工對應一個部門。
? 實現方式:在多的一方創建外鍵,指向一的一方。
示例:
? 多對多:
? 案例: 學生和課表的關系 ,一個學生可以對應多門課,一個課程對應有多個學生學習
? 實現方式:建立第三張表作為中間表,中間表至少包含兩個外鍵,分別外鍵關聯學生表和課程表
示例:
圖示:
? 02:多表查詢概述: 指從多張表中查詢數據
? 多表查詢的笛卡爾積現象: 笛卡爾積是指在數據學中,兩個集合的所有組合情況,(在多表查詢時,我們需要消除無效的笛卡爾積)。
? 03:內連接 —> 相當于查詢A集合和B集合的部分數據
? 隱式內聯:
? 語法:SELECT 字段列表 FROM 表1,表2 WHERE 條件…;
? 顯式內聯:
? 語法:SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 連接條件…;
實例:
-- --------內聯演示----------- # 查詢每一個員工的姓名,及關聯部門的名稱(使用隱式內聯實現) SELECT e.name , d.deptName from emp e,dept d where e.dept_id = d.id;# 查詢每一個員工的姓名,及關聯部門的名稱(使用顯示內聯實現) SELECT e.name , d.deptName from emp e inner join dept d on e.dept_id = d.id;? 04:外連接
? 左外連接: 查詢坐標所有數據,以及兩張表交集部分數據
? 右外連接: 查詢右表所有數據,以及兩張表交集部分數據
演示:
# 查詢emp表的所有數據,和對應的部門信息(左外連接) SELECT * FROM emp e left join dept d on d.id = e.dept_id;# 查詢dept表的所有數據,和對應的員工信息(右外連接)SELECT * FROM emp e right join dept d on d.id = e.dept_id;? 05:
? a:自查詢 —> 當前表與自身的連接查詢,自連接必須使用別名
? 自連接語法:
? SELECT 字段列表 FROM 表A,別名A JOIN 表A 別名B ON 條件…
? 自連接查詢可以是外連接查詢,也可以是內連接查詢。
? 示例:
# 查詢員工及其領導的名字 SELECT a.name as '員工姓名',b.name as '領導姓名' FROM emp a join emp b on a.managerid = b.id; # 查詢所有員工及其領導的名字 ,如果員工沒有領導也要查詢出來 SELECT a.name as '員工姓名',b.name as '領導姓名' FROM emp a left join emp b on a.managerid= b.id;? b:聯合查詢 --> union ,union all
? 對于union查詢,就是把多次查詢的結果合并起來,形成一個新的查詢結果集
? 語法: SELECT 字段列表 FROM 表A …
? UNION [ ALL ]
? SELECT 字段列表 FROM 表B…;
? 注意:對于聯合查詢的多張表的列 數據必須保持一致,字段類型也需要保持一致。
實例:
-- 連接查詢 使用union 和union all # 將薪資低于10000和年齡大于50的所有員工查詢出來 SELECT * FROM emp where salary< 10000 union all SELECT * FROM emp WHERE age >50;? 07:子查詢
? 概念: SQL語句中嵌套SELECT 語句,稱為嵌套查詢,又稱為子查詢
? 語法: SELECT * FROM tmp WHERE column in (SELECT column from tmp2);
? 子查詢的外層可以是任意的 INSERT / UPDATE / DELETE / SELECT 語句中的一個。
? 根據子查詢的查詢結果分為:
? 標量子查詢: 子查詢結果為單個值(數字、字符串、日期等),這種是最簡單的形式。
? 常見的操作符為:= <> > < <= >=
? 列子查詢: 子查詢的結果為一列(可以是多行)
? 常見的操作符: IN 、NOT IN 、ANY 、SOME、 ALL
? IN :在指定的集合范圍之內,多選一
? NOT IN :不在指定的集合范圍內
? ANY :子查詢返回列表中,有任意一個滿足即可
? SOME : 與ANY等同,使用SOME的地方都可以使用ANY
? ALL :子查詢返回列表的所有值都必須滿足
示例:
-- --------列子查詢--------# 1. 查詢'銷售部'和'市場部'的所有員工信息 SELECT * FROM emp WHERE dept_id in (select id from dept WHERE deptName in ('市場部','銷售部'));# 2. 查詢比財務部所有人工資都高的員工信息 SELECT * FROM emp WHERE salary > (select max(salary) From emp group by dept_id having dept_id = (select id from dept where deptName= '財務部'));SELECT * FROM emp WHERE salary > all (select salary from emp where dept_id = (select id from dept where deptName='財務部'));# 3. 查詢比研發部其中任意一人工資高的員工信息SELECT * FROM emp WHERE salary > any (select salary FROM emp WHERE dept_id = (SELECT id from dept where deptName='研發部'));? 行子查詢: 子查詢的結果為一行(也可以是多行),這種子查詢稱為行子查詢
? 常用操作符: = 、<> 、IN 、NOT IN
? 注意:條件中的多個字段順序應當和子查詢的字段順序一致,否則會沒有數據
# 查詢和張無忌工資相同、直屬領導相同的的員工信息 SELECT * FROM emp where (managerid,salary) = (SELECT salary,managerid from emp where name ='張無忌');?
? 表子查詢: 子查詢結果為多行多列
? 常用操作符:IN
? 示例:
# 查詢 楊瀟 張無忌 工資相同、直系領導相同的員工信息SELECT * FROM emp where (salary,managerid) in (select salary,managerid from emp where name in ('張無忌','楊瀟'));# 查詢入職日期是'2006-01-01'之后的日期,及其部門信息。SELECT * FROM (select * from emp where entrydate >'2006-01-01') e left join dept d on e.dept_id = d.id;? 08:多表查詢案例
六、事務
? 1: 事務簡介:是一組操作的集合,他是一個不可分割的工作單位,事務會把所有的操作作為一個整體一起向系統提交或者撤銷操作請求,即這些操作要么同時成功,要么同時失敗。
? 具體例子 參見 轉賬業務。
MySQL 默認是事務自動提交,也就是說,當執行一條DML SQL語句,MySQL 會隱式的提交事務
? 2: 事務操作
– 方式一:設置手動事務
? 01:查看 / 設置 事務的提交方式
? SELECT @@autocommit;
? # 設置手動提交
? SET @@autocommit=0;
? 02:提交事務
? COMMIT;
? 03:回滾事務
? ROLLBACK;
– 方式二:開啟事務模式
? 01:開啟事務
? START TRANSACTION 或 BEGIN;
? 02:提交事務
? COMMIT;
? 03:回滾事務
? ROLLBACK;
? 3:事務四大特性
? a、原子行(ATOMICITY): 事務是不可分割的最小操作單元,那么全部成功,要么全部失敗
? b、一致性(CONSISITENCY):事務完成時,必須是所有的數據都保持一致狀態。
? c、隔離性(ISOLATION): 數據庫系統提供的隔離機制,保證事務在不收外部并發操作影響 的獨立環境下運行
? d、持久性(DURABILITY):事務一旦提交或者回滾,他對數據庫的修改是永久的。
? 4:并發事務問題
| 臟讀 | 一個事務讀到另外一個事務還沒有提交的數據 |
| 不可重復讀 | 一個事務先后讀取同一條記錄,但兩次讀取的數據不同,稱之為不可重復讀。 |
| 幻讀 | 一個事務按照條件查詢數據時,沒有對應的數據行,但是在插入數據時,又發現數據已經存在,好像出現了“幻影” |
? 5:事務的隔離級別
| READ UNCOMMITTED | √ | √ | √ |
| READ COMMITTED | × | √ | √ |
| REPEATABLE READ(默認) | × | × | √ |
| SERIALIZABLE | × | × | × |
查看事務隔離級別
? SELECT @@TRANSACTION_ISOLATION;
設置事務隔離級別
? SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ;
事務的隔離級別也高,數據越安全,但是性能越低。
事務總結:
希望對您有幫助。求點贊+關注。
總結
以上是生活随笔為你收集整理的mysql基础入门(参照b站黑马程序员整理)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工作375-input readonly
- 下一篇: 黑马程序员MySQL-视图SQL笔记