mysql基础入门(参照b站黑马程序员整理)
mysql 基礎(chǔ)
一、 概述:
1、課程內(nèi)容和數(shù)據(jù)相關(guān)概念
? 數(shù)據(jù)庫的概念:存儲數(shù)據(jù)的倉庫,數(shù)據(jù)是又組織的進(jìn)行存儲
? 數(shù)據(jù)庫管理系統(tǒng):操作和管理數(shù)據(jù)庫的大型軟件
? SQL: 操作關(guān)系型數(shù)據(jù)庫的編程語言,定義了一套操作關(guān)系型數(shù)據(jù)庫統(tǒng)一標(biāo)準(zhǔn)
2、關(guān)系型數(shù)據(jù)庫:
? 建立在關(guān)系模型基礎(chǔ)上,由多張表相關(guān)連接的二維表組成的數(shù)據(jù)庫
? 數(shù)據(jù)模型:
? 客戶端 --> DBMS --> 數(shù)據(jù)庫1、數(shù)據(jù)庫2 --> 表1、表2
二、SQL
? 1、SQL通用語法:關(guān)鍵字建議大寫
? 2、SQL分類:DDL(Data Definition Language)、DML(Data Manipulation Language)、DQL(Data Query Language)、DCL(Data Control Language).
? 3、DDL: 數(shù)據(jù)庫定義語言,創(chuàng)建數(shù)據(jù)庫、創(chuàng)建表
? a、查詢數(shù)據(jù)庫:
? 語法: SHOW DATABASES; —> 查詢所有數(shù)據(jù)庫
? 語法: SELECT DATABASE(); —>查詢當(dāng)前數(shù)據(jù)庫
? b、創(chuàng)建數(shù)據(jù)庫
? 語法: CREATE DATABASE [ IF NOT EXISTS ] 數(shù)據(jù)庫名 [ DEFAULT CHARSET 字符集(UTF-8)] [ COLLATE 排序規(guī)則 ];
? c、刪除數(shù)據(jù)庫
? 語法: DROP DATABASE [ IF EXISTS ] 數(shù)據(jù)庫名;
? d、使用數(shù)據(jù)庫
? 語法: USE 數(shù)據(jù)庫名;
? e、表操作-> 創(chuàng)建&查詢表
? 使用數(shù)據(jù)庫后,查看表 :SHOW TABLES;
? 查詢表結(jié)構(gòu) :DESC 表名;
? 查詢指標(biāo)的創(chuàng)建語句 : SHOW CREATE TABLE 表名;
? 創(chuàng)建表結(jié)構(gòu):
? 語法:CREATE TABLE 表名(
? 字段1 字段1類型 [ COMMENT 字段1 注釋 ],
? 字段2 字段2類型 [ COMMENT 字段2 注釋 ],
? ……
? 字段n 字段n類型 [ COMMENT 字段n 注釋 ]
? ) [ COMMENT 表注釋 ];
? f、 表操作 --> 數(shù)據(jù)類型:mysql 數(shù)據(jù)類型分為很多,主流的是數(shù)值型、字符串類型、日 期時間類型
? 01: MySQL 數(shù)值數(shù)據(jù)類型
? 02:MySQL 字符串?dāng)?shù)據(jù)類型
? char 和 vachar 相比 char的性能比vachar 的性能更好。
? 03: MySQL 日期型數(shù)據(jù)類型
? 04 : 案例:
? g 表操作–>修改
? 01 添加字段:ALTER TABLE 表名 ADD 字段名 字段類型[(長度)] [COMMENT ‘備注‘] [約束];
? 02 修改字段:
? 修改字段類型:
? 語法:ALTER TABLE 表名 MODIFY 字段名 新數(shù)據(jù)類型 [(長度)] ;
? 修改字段名和字段類型:
? 語法:ALTER TABLE 表名 CHANGE 字段名 新字段名 數(shù)據(jù)類型[(長度)] [COMMENT ‘備注’] [約束];
? 案例 : 將tb_emp 的nickname修改為username 數(shù)據(jù)類型為 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 表操作 -->刪除表: 刪除表時,表的數(shù)據(jù)也會被刪除。
? 刪除指定表 不安全模式,刪除表后 無法恢復(fù) 慎用
? 語法: DROP TABLE [ IF EXISTS ] 表名;
? 刪除指定表,并重新創(chuàng)建一個具有相同結(jié)構(gòu)的空表
? 語法: TRUNCATE TABLE 表名;
? 案例: 刪除tb_user 表 DROP TABLE IF EXISTS tb_user;
? 案例: 刪除 tb_employee 表 并保留其表結(jié)構(gòu)
? 語法: TRUNCATE TABLE tb_employee;
? 4、DML: 數(shù)據(jù)庫操作語言,用于對數(shù)據(jù)表中的數(shù)據(jù)進(jìn)行增刪改操作
? a、INSERT 插入(增加)數(shù)據(jù)(黑馬 P12課程 需要重新觀看一次)
? 給指定字段插入數(shù)據(jù):
? 語法: INSERT INTO 表名 (字段名1,字段名2,…) VALUES (value1,value2,…);
? 備注: 字段名1和value1 對應(yīng) 字段名2 和value2 對應(yīng),…
? 給表的全部字段插入數(shù)據(jù)
? 語法: INSERT INTO 表名 VALUES (值1,值2,…);
? 備注: 此時必須將值的數(shù)據(jù)全部和字段進(jìn)行對應(yīng)
? 批量插入:
? 語法: INSERT INTO 表名 (字段名1,字段名2,…) VALUES (value1,value2,…),(value1,value2,…),(value1,value2,…),…;
? 語法: INSERT INTO 表名 VALUES (值1,值2,…),(值1,值2,…),(值1,值2,…),…;
? 注意:插入數(shù)據(jù)時,字段的順序要和給定的值的順序一一對應(yīng),字符串和日期應(yīng)該包含在引號中,給定的數(shù)值不能超過字段定義的大小
? b、UPDATE 修改數(shù)據(jù)
? 語法: UPDATE 表名 SET 字段1=值1,字段2=值2,… [WHERE 條件…];
? 注意: 修改語句的條件可以有,也可以沒有,如果沒有條件,那么會修改整個表的數(shù)據(jù)
? 案例:
# 案例 將所有員工的入職日期修改為“2021-01-18” update tb_employee SET entry='2021-01-18';? c、DELETE 刪除數(shù)據(jù)
? DELETE 語句的條件可以有,也可以沒有,如果沒有條件,那么會刪除整張表的數(shù)據(jù) DELETE 語句不能刪除某一個字段的值(可以使用update 語句)
? 語法: DELETE FROM 表名 WHERE 條件
? 5、DQL: 數(shù)據(jù)庫查詢語言,用來查詢數(shù)據(jù)庫中的表記錄
? 查詢關(guān)鍵字 SELECT
? 完整格式
? 語法: SELECT * [ 字段1 [ AS 別名 ],字段2,… ] FROM 表名1 [ AS 別名 ],[ 表名2,… ] [ WHERE 條件1 AND 條件2 AND… ] [ GROUP BY 分組字段1,分組字段2,… ] [ HAVING 分組后條件列表 ] [ ORDER BY 排序字段列表 ] [ LIMIT 分頁參數(shù) ]
? 如圖:
? a、基本查詢:
? 01: 查詢多個字段 SELECT 字段列表 FROM 表名
? 語法: SELECT * FROM 表名;
? 語法: SELECT 字段1 [AS 別名1],字段2 [AS 別名2],… FROM 表名;
? 去除重復(fù)記錄: DISTINCT 關(guān)鍵字 , 語法:SELECT DISTINCT 字段列表 FROM 表名;
? 案例: 見下方腳本塊
DROP TABLE IF EXISTS employee;# 創(chuàng)建表 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 '員工表';# 插入 數(shù)據(jù) 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;# 查詢工作地址,不重復(fù) 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:聚合函數(shù)
? 語法: SELECT 聚合函數(shù)( 字段名) FROM 表名;
? 案例: 見下
-- 聚合函數(shù)# 1 統(tǒng)計該表中的員工數(shù)量 SELECT COUNT(id) FROM employee;# 2 統(tǒng)計該表中的員工平均年齡 SELECT name,AVG(age) FROM employee;# 3 統(tǒng)計員工的最大年齡 SELECT name,MAX(age) FROM employee;# 4 統(tǒng)計員工的最小年齡 SELECT name,MIN(age) FROM employee;# 5 統(tǒng)計員工的年齡之和 SELECT SUM(age) FROM employee;? 04: 分組查詢
? 語法:SELECT 字段列表 FROM 表名 [WHERE 條件列表] GROUP BY 分組字段名[HAVING 分組后過濾條件];
? 注意: WHERE 和 HAVING 的區(qū)別
? 1: 執(zhí)行的時機不同,WHERE是在分組之前執(zhí)行,不滿足WHERE條件的不參與分組;而HAVING是分組之后對查詢出的結(jié)果進(jìn)行過濾。
? 2: 判斷的時機不同,WHERE 不能對聚合函數(shù)進(jìn)行判斷,而HAVING 能
*** 執(zhí)行順序: WHERE > 聚合函數(shù) > having
*** 分組之后,查詢的字段一般為聚合函數(shù)和分組字段,查詢其他字段沒有任何意義。
案例:
-- 分組查詢# 1 根據(jù)性別分組,統(tǒng)計男性員工和女性員工的數(shù)量 SELECT COUNT(gender) as '男性人數(shù)',(SELECT count(gender) FROM employee WHERE gender='女') as '女性人數(shù)' FROM employee WHERE gender='男';SELECT sum(IF(gender='男',1,0)) as '男性人數(shù)',sum(IF(gender='女',1,0)) as '女性人數(shù)' FROM employee;# 2 根據(jù)性別分組,統(tǒng)計男性員工和女性員工的平均年齡 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的員工,并根據(jù)工作地址分組,獲取員工數(shù)量大于等于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 升序 (默認(rèn)值)
? DESC 降序
? 案例:
-- 排序查詢# 1 根據(jù)年齡對員工進(jìn)行升序排序 SELECT * FROM employee ORDER BY age ;# 2 根據(jù)入職時間對員工降序排序 SELECT * FROM employee ORDER BY entry DESC ;# 3 根據(jù)年齡升序排序,年齡相同按照入職年齡降序排序 SELECT * FROM employee ORDER BY age asc ,entry DESC ;? 06: 分頁查詢
? SELECT 字段列表 FROM 表名 LIMIT 起始索引,查詢記錄數(shù);
? 注意:
? 起始索引從0 開始,起始索引=(查詢頁碼-1)* 每頁記錄數(shù)據(jù)
? 分頁查詢是數(shù)據(jù)庫的方言,不同的數(shù)據(jù)庫有不同的實現(xiàn),MySQL中的是LIMIT
? 如果查詢的是第一頁的數(shù)據(jù),起始索引可以省略,直接簡寫為LIMIT10
? 案例:
-- 分頁查詢# 1 查詢第一頁的員工數(shù)據(jù),每頁展示10條記錄 SELECT * FROM employee LIMIT 10;# 2 查詢第二頁的員工數(shù)據(jù),每頁展示10條記錄 (2-1)*10 = 起始索引 SELECT * FROM employee LIMIT 10,10;練習(xí) :
# 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(含)以內(nèi)的姓名為三個字的員工 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 統(tǒng)計員工表中,年齡小于60歲,男性員工和女性員工的人數(shù) SELECT SUM(IF(gender='男',1,0)) AS '男性人數(shù)', SUM(IF(gender='女',1,0)) AS '女性人數(shù)' FROM employee WHERE age < 60# 4 查詢所有年齡小于等于35歲員工的姓名和年齡,并對查詢結(jié)果按年齡升序排序,如果年齡相同按入職時間降序排序 SELECT name,age,entry FROM employee WHERE age <=35 ORDER BY age,entry DESC;# 5 查詢性別為男,且年齡在20-40歲(含)以內(nèi)的前五個員工信息,并對查詢結(jié)果按年齡升序排序,年齡相同按入職時間升序排序 SELECT * FROM (SELECT * FROM employee WHERE gender ='男' AND age >20 and age <=40 LIMIT 5) res ORDER BY res.age,res.entry;總結(jié):
SQL的編寫順序
SELECT 字段列表 FROM 表名列表 WHERE 條件列表 GROUP BY 分組字段列表 HAVING 分組后條件列表 ORDER BY 排序字段列表 LIMIT 分頁參數(shù)
SQL 執(zhí)行順序
FROM 表名列表 WHERE 條件列表 GROUP BY 分組字段列表 HAVING 分組后條件列表 SELECT 字段列表 ORDER BY 排序字段列表 LIMIT 分頁參數(shù)
? 6、DCL: 數(shù)據(jù)庫控制語言,用來創(chuàng)建數(shù)據(jù)庫用戶、控制數(shù)據(jù)庫的訪問、權(quán)限
? a 、管理用戶
? 01: 查詢用戶
? Use mysql;
? SELECT * FROM user;
? 02: 創(chuàng)建用戶
? CREATE USER ‘用戶名‘@‘主機名‘ IDENTIFIED BY ‘密碼‘;
? 03: 修改用戶密碼
? ALTER USER ‘用戶名‘@’主機名’ IDENTIFIED WITH mysql_native_password BY ‘新密碼‘;
? 04: 刪除用戶
? DROP USER ‘用戶名‘@’主機名’ ;
? 注意: 主機名可以通過 % 來通配
案例:
-- 管理用戶 # 查詢用戶 Use mysql; SELECT * FROm user; # 創(chuàng)建用戶 # 1. 創(chuàng)建用戶 itcast 只能在當(dāng)前主機localhost訪問,密碼為123456 CREATE USER 'itcast'@'localhost' IDENTIFIED BY '123456';# 2. 創(chuàng)建用戶 heima 可以在任意主機訪問該數(shù)據(jù)庫,密碼為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: 權(quán)限控制
? 01:查詢權(quán)限
? SHOW GRANTS FOR ‘用戶名‘@’主機名’;
? 02:授予權(quán)限
? GRANT 權(quán)限列表 ON 數(shù)據(jù)庫名.表名 TO ‘用戶名‘@’主機名’;
? 03:撤銷權(quán)限
? REVOKE 權(quán)限列表 ON 數(shù)據(jù)庫名.表名 FROM ‘用戶名‘@’主機名’;
? 注意:
? 多個權(quán)限之間通過逗號分隔。
? 授權(quán)和回收權(quán)限時,數(shù)據(jù)庫名和表名可以通過 * 來進(jìn)行通配,代表所有
? 總結(jié):
三、函數(shù)
? 1、字符串函數(shù)
練習(xí):
-- ---------------------函數(shù)演示---------------------------- -- concat 將兩個字符串拼接 SELECT concat('hello',' mysql');-- lower 轉(zhuǎn)換成小寫 SELECT lower('HELLO');-- upper 轉(zhuǎn)換成大寫 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 去除目標(biāo)字符串的首尾空格 SELECT TRIM(' HELLO, WORLD ');-- SUBSTRING(str,start,len) 將字符串從指定位置起(包含,下標(biāo)以1開頭)截取指定長度,并返回 SELECT SUBSTRING('HELLO,WORLD',3,3);# 1, 將企業(yè)的工號統(tǒng)一改為五位 如 1號員工的工號為00001 10號員工的工號為00010 update employee set workno=LPAD(workno,5,'0');? 2、數(shù)值函數(shù)
練習(xí):
# 2 數(shù)值函數(shù) -- CEIL(X) 對x進(jìn)行向上取整 SELECT CEIL(21.2); # 22-- FLOOR(x) 對x進(jìn)行向下取整 SELECT FLOOR(22.1); # 22-- MOD(x,y) 返回x/y的模(余數(shù)) SELECT MOD(22,3); # 1-- rand() 返回0-1的隨機數(shù) SELECT RAND();-- round(x,y),求x的四舍五入的值,保留y位小數(shù) SELECT ROUND(2.2132100212,8); #2.21321002# 通過數(shù)據(jù)庫的函數(shù),生成一個六位數(shù)的隨機驗證碼 SELECT LPAD(ROUND(rand()*1000000,0),6,0);? 3、日期函數(shù)
練習(xí):
-- ------------------------日期函數(shù)-------------------- # curdate() 返回當(dāng)前日期 SELECT CURDATE(); # curtime() 返回當(dāng)前時間 SELECT CURTIME(); # now() 返回當(dāng)前時間和日期 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 和結(jié)束時間DATE2之間的天數(shù),一般較大的日期放在第一個參數(shù),較小的日期放在第二個參數(shù)上 SELECT DATEDIFF('2022-11-22','2022-04-21');# 查詢所有員工的入職天數(shù),并根據(jù)入職天數(shù)倒序排序 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 '入職天數(shù)' FROM employee ORDER BY entry asc ;? 4、流程函數(shù)
練習(xí):
-- ------------------------流程函數(shù)-------------------- # 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默認(rèn)值 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 默認(rèn)值 SELECT case 1 WHEN 2 THEN 'ok' ELSE 'default' END;總結(jié):
四、約束
? 01:表內(nèi)約束
概念:約束是作用于表中字段上的規(guī)則,用戶限制存儲在表中的數(shù)據(jù)
目的: 保證數(shù)據(jù)庫中數(shù)據(jù)的正確性、有效性和完整性。
分類:
| 非空約束 | 限制該字段的數(shù)據(jù)不能為null | NOT NULL |
| 唯一約束 | 保證該字段的所有數(shù)據(jù)都是唯一、不重復(fù)的 | UNIQUE |
| 主鍵約束 | 主鍵是一行數(shù)據(jù)的唯一標(biāo)識,要求非空且唯一 | PRIMARY KEY |
| 默認(rèn)約束 | 保存數(shù)據(jù)時,如果未指定該字段的值,則采用默認(rèn)值 | DEFAULT |
| 檢查約束(8.0.16 版本之后) | 保證字段值滿足某一個條件 | CHECK |
| 外鍵約束 | 用來讓兩張表的數(shù)據(jù)之間建立連接,保證數(shù)據(jù)的一致性和完整性 | FOREIGN KEY |
注意: 約束是作用域表字段上的,可以通過創(chuàng)建表和修改表的時候添加約束。
約束演示:
外鍵約束:
? 概念:外鍵用來讓兩張表的數(shù)據(jù)之間建立連接,從而保證數(shù)據(jù)的一致性和完整性
創(chuàng)建員工和部門表
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唯一標(biāo)識符',deptName varchar(50) not null comment '部門名稱' ) comment '部門表'; INSERT INTO dept (id, deptName) VALUES (1,'研發(fā)部'), (2,'市場部'), (3,'財務(wù)部'), (4,'銷售部'), (5,'總經(jīng)辦');DROP TABLE IF EXISTS emp; CREATE TABLE emp(id int auto_increment primary key comment'編號,唯一標(biāo)識符',name varchar(50) not null comment '姓名',age int comment '年齡',job varchar(50) comment '職位',salary int comment '薪資',entrydate date comment '入職時間',managerid int comment '直系領(lǐng)導(dǎo)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,'項目經(jīng)理',15200,'2005-01-01',1,1),(3,'楊瀟',33,'開發(fā)',8400,'2011-01-01',2,1),(4,'韋一笑',48,'開發(fā)',11000,'2006-01-01',2,1),(5,'常遇春',43,'開發(fā)',10500,'2002-01-01',2,1),(6,'小昭',19,'開發(fā)實習(xí)生',3200,'2018-01-01',2,1);部門表和員工表在在數(shù)據(jù)庫層面沒有創(chuàng)建外鍵管理,不能保證數(shù)據(jù)的一致性和完整性。
添加外鍵的語法:
CREATE TABLE 表名(字段名 數(shù)據(jù)類型.....[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;總結(jié):
五、多表查詢
? 01:多表關(guān)系
? 在實際項目開發(fā)過程中,會根據(jù)業(yè)務(wù)需求及業(yè)務(wù)模塊之間的關(guān)系,分析并設(shè)計表結(jié)構(gòu),基于業(yè)務(wù)之間相互關(guān)聯(lián),所以各個表之間也存在相互關(guān)聯(lián)關(guān)系,具體分為三種,如:
? 一對一:
? 案例: 用戶與用戶詳情的關(guān)系
? 關(guān)系: 一對一關(guān)系,多用于單表拆分,將一張表的基礎(chǔ)子彈放在一張表中其他詳情字段放在另一張表中,用以提升效率。
?
? 一對多(多對一):
? 案例: 一個部門對應(yīng)多個員工,一個員工對應(yīng)一個部門。
? 實現(xiàn)方式:在多的一方創(chuàng)建外鍵,指向一的一方。
示例:
? 多對多:
? 案例: 學(xué)生和課表的關(guān)系 ,一個學(xué)生可以對應(yīng)多門課,一個課程對應(yīng)有多個學(xué)生學(xué)習(xí)
? 實現(xiàn)方式:建立第三張表作為中間表,中間表至少包含兩個外鍵,分別外鍵關(guān)聯(lián)學(xué)生表和課程表
示例:
圖示:
? 02:多表查詢概述: 指從多張表中查詢數(shù)據(jù)
? 多表查詢的笛卡爾積現(xiàn)象: 笛卡爾積是指在數(shù)據(jù)學(xué)中,兩個集合的所有組合情況,(在多表查詢時,我們需要消除無效的笛卡爾積)。
? 03:內(nèi)連接 —> 相當(dāng)于查詢A集合和B集合的部分?jǐn)?shù)據(jù)
? 隱式內(nèi)聯(lián):
? 語法:SELECT 字段列表 FROM 表1,表2 WHERE 條件…;
? 顯式內(nèi)聯(lián):
? 語法:SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 連接條件…;
實例:
-- --------內(nèi)聯(lián)演示----------- # 查詢每一個員工的姓名,及關(guān)聯(lián)部門的名稱(使用隱式內(nèi)聯(lián)實現(xiàn)) SELECT e.name , d.deptName from emp e,dept d where e.dept_id = d.id;# 查詢每一個員工的姓名,及關(guān)聯(lián)部門的名稱(使用顯示內(nèi)聯(lián)實現(xiàn)) SELECT e.name , d.deptName from emp e inner join dept d on e.dept_id = d.id;? 04:外連接
? 左外連接: 查詢坐標(biāo)所有數(shù)據(jù),以及兩張表交集部分?jǐn)?shù)據(jù)
? 右外連接: 查詢右表所有數(shù)據(jù),以及兩張表交集部分?jǐn)?shù)據(jù)
演示:
# 查詢emp表的所有數(shù)據(jù),和對應(yīng)的部門信息(左外連接) SELECT * FROM emp e left join dept d on d.id = e.dept_id;# 查詢dept表的所有數(shù)據(jù),和對應(yīng)的員工信息(右外連接)SELECT * FROM emp e right join dept d on d.id = e.dept_id;? 05:
? a:自查詢 —> 當(dāng)前表與自身的連接查詢,自連接必須使用別名
? 自連接語法:
? SELECT 字段列表 FROM 表A,別名A JOIN 表A 別名B ON 條件…
? 自連接查詢可以是外連接查詢,也可以是內(nèi)連接查詢。
? 示例:
# 查詢員工及其領(lǐng)導(dǎo)的名字 SELECT a.name as '員工姓名',b.name as '領(lǐng)導(dǎo)姓名' FROM emp a join emp b on a.managerid = b.id; # 查詢所有員工及其領(lǐng)導(dǎo)的名字 ,如果員工沒有領(lǐng)導(dǎo)也要查詢出來 SELECT a.name as '員工姓名',b.name as '領(lǐng)導(dǎo)姓名' FROM emp a left join emp b on a.managerid= b.id;? b:聯(lián)合查詢 --> union ,union all
? 對于union查詢,就是把多次查詢的結(jié)果合并起來,形成一個新的查詢結(jié)果集
? 語法: SELECT 字段列表 FROM 表A …
? UNION [ ALL ]
? SELECT 字段列表 FROM 表B…;
? 注意:對于聯(lián)合查詢的多張表的列 數(shù)據(jù)必須保持一致,字段類型也需要保持一致。
實例:
-- 連接查詢 使用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 語句中的一個。
? 根據(jù)子查詢的查詢結(jié)果分為:
? 標(biāo)量子查詢: 子查詢結(jié)果為單個值(數(shù)字、字符串、日期等),這種是最簡單的形式。
? 常見的操作符為:= <> > < <= >=
? 列子查詢: 子查詢的結(jié)果為一列(可以是多行)
? 常見的操作符: IN 、NOT IN 、ANY 、SOME、 ALL
? IN :在指定的集合范圍之內(nèi),多選一
? NOT IN :不在指定的集合范圍內(nèi)
? ANY :子查詢返回列表中,有任意一個滿足即可
? SOME : 與ANY等同,使用SOME的地方都可以使用ANY
? ALL :子查詢返回列表的所有值都必須滿足
示例:
-- --------列子查詢--------# 1. 查詢'銷售部'和'市場部'的所有員工信息 SELECT * FROM emp WHERE dept_id in (select id from dept WHERE deptName in ('市場部','銷售部'));# 2. 查詢比財務(wù)部所有人工資都高的員工信息 SELECT * FROM emp WHERE salary > (select max(salary) From emp group by dept_id having dept_id = (select id from dept where deptName= '財務(wù)部'));SELECT * FROM emp WHERE salary > all (select salary from emp where dept_id = (select id from dept where deptName='財務(wù)部'));# 3. 查詢比研發(fā)部其中任意一人工資高的員工信息SELECT * FROM emp WHERE salary > any (select salary FROM emp WHERE dept_id = (SELECT id from dept where deptName='研發(fā)部'));? 行子查詢: 子查詢的結(jié)果為一行(也可以是多行),這種子查詢稱為行子查詢
? 常用操作符: = 、<> 、IN 、NOT IN
? 注意:條件中的多個字段順序應(yīng)當(dāng)和子查詢的字段順序一致,否則會沒有數(shù)據(jù)
# 查詢和張無忌工資相同、直屬領(lǐng)導(dǎo)相同的的員工信息 SELECT * FROM emp where (managerid,salary) = (SELECT salary,managerid from emp where name ='張無忌');?
? 表子查詢: 子查詢結(jié)果為多行多列
? 常用操作符:IN
? 示例:
# 查詢 楊瀟 張無忌 工資相同、直系領(lǐng)導(dǎo)相同的員工信息SELECT * FROM emp where (salary,managerid) in (select salary,managerid from emp where name in ('張無忌','楊瀟'));# 查詢?nèi)肼毴掌谑?#39;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:多表查詢案例
六、事務(wù)
? 1: 事務(wù)簡介:是一組操作的集合,他是一個不可分割的工作單位,事務(wù)會把所有的操作作為一個整體一起向系統(tǒng)提交或者撤銷操作請求,即這些操作要么同時成功,要么同時失敗。
? 具體例子 參見 轉(zhuǎn)賬業(yè)務(wù)。
MySQL 默認(rèn)是事務(wù)自動提交,也就是說,當(dāng)執(zhí)行一條DML SQL語句,MySQL 會隱式的提交事務(wù)
? 2: 事務(wù)操作
– 方式一:設(shè)置手動事務(wù)
? 01:查看 / 設(shè)置 事務(wù)的提交方式
? SELECT @@autocommit;
? # 設(shè)置手動提交
? SET @@autocommit=0;
? 02:提交事務(wù)
? COMMIT;
? 03:回滾事務(wù)
? ROLLBACK;
– 方式二:開啟事務(wù)模式
? 01:開啟事務(wù)
? START TRANSACTION 或 BEGIN;
? 02:提交事務(wù)
? COMMIT;
? 03:回滾事務(wù)
? ROLLBACK;
? 3:事務(wù)四大特性
? a、原子行(ATOMICITY): 事務(wù)是不可分割的最小操作單元,那么全部成功,要么全部失敗
? b、一致性(CONSISITENCY):事務(wù)完成時,必須是所有的數(shù)據(jù)都保持一致狀態(tài)。
? c、隔離性(ISOLATION): 數(shù)據(jù)庫系統(tǒng)提供的隔離機制,保證事務(wù)在不收外部并發(fā)操作影響 的獨立環(huán)境下運行
? d、持久性(DURABILITY):事務(wù)一旦提交或者回滾,他對數(shù)據(jù)庫的修改是永久的。
? 4:并發(fā)事務(wù)問題
| 臟讀 | 一個事務(wù)讀到另外一個事務(wù)還沒有提交的數(shù)據(jù) |
| 不可重復(fù)讀 | 一個事務(wù)先后讀取同一條記錄,但兩次讀取的數(shù)據(jù)不同,稱之為不可重復(fù)讀。 |
| 幻讀 | 一個事務(wù)按照條件查詢數(shù)據(jù)時,沒有對應(yīng)的數(shù)據(jù)行,但是在插入數(shù)據(jù)時,又發(fā)現(xiàn)數(shù)據(jù)已經(jīng)存在,好像出現(xiàn)了“幻影” |
? 5:事務(wù)的隔離級別
| READ UNCOMMITTED | √ | √ | √ |
| READ COMMITTED | × | √ | √ |
| REPEATABLE READ(默認(rèn)) | × | × | √ |
| SERIALIZABLE | × | × | × |
查看事務(wù)隔離級別
? SELECT @@TRANSACTION_ISOLATION;
設(shè)置事務(wù)隔離級別
? SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ;
事務(wù)的隔離級別也高,數(shù)據(jù)越安全,但是性能越低。
事務(wù)總結(jié):
希望對您有幫助。求點贊+關(guān)注。
總結(jié)
以上是生活随笔為你收集整理的mysql基础入门(参照b站黑马程序员整理)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工作375-input readonly
- 下一篇: 黑马程序员MySQL-视图SQL笔记