啟動數(shù)據(jù)庫服務(wù)指令:

連接到MySQL的指令:(登錄前,需要保證服務(wù)啟動)

數(shù)據(jù)庫三層結(jié)構(gòu)
可以理解為客戶端發(fā)送sql指令,數(shù)據(jù)庫管理系統(tǒng)通過端口3306監(jiān)聽到該條指令,翻譯后操作數(shù)據(jù)庫表。


數(shù)據(jù)在數(shù)據(jù)庫中的存儲方式:

SQL語句分類

創(chuàng)建數(shù)據(jù)庫

#使用指令創(chuàng)建數(shù)據(jù)庫
CREATE DATABASE hsp_db01;
#刪除數(shù)據(jù)庫指令
DROP DATABASE hsp_db01
#創(chuàng)建一個使用 utf8 字符集的 hsp_db02 數(shù)據(jù)庫
CREATE DATABASE hsp_db02 CHARACTER SET utf8
#創(chuàng)建一個使用 utf8 字符集,并帶校對規(guī)則的 hsp_db03 數(shù)據(jù)庫
CREATE DATABASE hsp_db03 CHARACTER SET utf8 COLLATE utf8_bin
#校對規(guī)則 utf8_bin 區(qū)分大小 默認(rèn) utf8_general_ci 不區(qū)分大小寫
查看刪除數(shù)據(jù)庫
老師說明 在創(chuàng)建數(shù)據(jù)庫,表的時候,為了規(guī)避關(guān)鍵字,可以使用反引號解決
#演示刪除和查詢數(shù)據(jù)庫
#查看當(dāng)前數(shù)據(jù)庫服務(wù)器中的所有數(shù)據(jù)庫
SHOW DATABASES
#查看前面創(chuàng)建的 hsp_db01 數(shù)據(jù)庫的定義信息 SHOW CREATE DATABASE `hsp_db01`
#刪除前面創(chuàng)建的 hsp_db01 數(shù)據(jù)庫
DROP DATABASE hsp_db01
備份恢復(fù)數(shù)據(jù)庫
備份數(shù)據(jù)庫,在管理員模式下運(yùn)行
恢復(fù)數(shù)據(jù)庫:在MySQL命令行執(zhí)行,進(jìn)入命令:
mysql -u root -p


#備份
mysqldump -u root -pliying -B liying_db02 liying_db03 > d:\\bak.sql
# 恢復(fù)
source d:\\bak.sql
數(shù)據(jù)庫的表
創(chuàng)建表
注意:用MySQL關(guān)鍵字如name作列名時,可以用``括住

CREATE TABLE `user`(
id INT,
`name` VARCHAR(255),
`password` VARCHAR(255),
`birthday` DATE)
CHARACTER SET utf8 COLLATE utf8_bin ENGINE INNODB;
列類型
MySQL的列類型即MySQL的數(shù)據(jù)類型
- 數(shù)值類型:
整型,
tinyint 一個字節(jié)
smallint 2個字節(jié)
mediumint 3個字節(jié)
int 4個字節(jié)(最常用)
bigint 8個字節(jié)
小數(shù)類型
float 單精度 4個字節(jié)
double 雙精度 8個字節(jié) (常用)
decimal[M, D] 大小不確定 (最常用) - 文本類型(字符串類型)
char 0- 255 一個字節(jié) (最常用)
varchar 0-65535 兩個字節(jié) (最常用)
text 0- 216 - 1 兩個字節(jié) (最常用)
longtext 0- 232 - 1 四個字節(jié) - 二進(jìn)制數(shù)據(jù)(使用不多)
blob 0 - 216 - 1
longblob 0 - 232 - 1 - 日期類型
data [日期 年月日]
time [時間 時分秒]
datatime [年月日時分秒 YYYY-MM-DD HH:MM:SS] (最常用)
timestamp: [時間戳] (最常用)
year [年]
數(shù)值型(整數(shù))的基本使用
1. 如果沒有指定 unsinged , 則 TINYINT 就是有符號
2. 如果指定 unsinged , 則 TINYINT 就是無符號 0-255
CREATE TABLE t3 (
id TINYINT);
CREATE TABLE t4 (
id TINYINT UNSIGNED);
INSERT INTO t3 VALUES(127);
#這是非常簡單的添加語句
SELECT * FROM t3 INSERT INTO t4 VALUES(255);
數(shù)值型(小數(shù))的基本使用

字符串的基本使用

-
注意:varchar的最大長度是65532字節(jié)(三個字節(jié)記錄大?。?,不同的編碼類型,可以容納的字符數(shù)不同,如utf-8的大小為三字節(jié),所以可以容納的字符數(shù)為21844字符
-
varchar占用的空間看編碼的類型,如utf-8單字符是三字節(jié),gbk是二字節(jié)。
- 所以char可能造成空間的浪費(fèi),
- varchar()相當(dāng)于規(guī)定最大長度
- varchar占用的空間看實際占用的空間,不一定
日期類型的使用
修改表

DESC employee -- 顯示表結(jié)構(gòu),可以查看表的所有列
ALTER TABLE employee
CHANGE `name` `user_name` VARCHAR(64) NOT NULL DEFAULT ''
操作表的內(nèi)容
數(shù)據(jù)庫 C[create]R[read]U[update]D[delete]語句
insert語句

說明 insert 語句的細(xì)節(jié)
-- 1.插入的數(shù)據(jù)應(yīng)與字段的數(shù)據(jù)類型相同,(如果要接收的類型是int,輸入'30',會添加成功,MySQL底層會嘗試將其轉(zhuǎn)換為int,會成功。)
-- 2. 數(shù)據(jù)的長度應(yīng)在列的規(guī)定范圍內(nèi),例如:不能將一個長度為 80 的字符串加入到長度為 40 的列中。
--3. 在 values 中列出的數(shù)據(jù)位置必須與被加入的列的排列位置相對應(yīng)。
-- 4. 字符和日期型數(shù)據(jù)應(yīng)包含在單引號中。
-- 5. 列可以插入空值[前提是該字段允許為空],insert into table value(null)
-- 6. insert into tab_name (列名..) values (),(),() 形式添加多條記錄
-- 7. 如果是給表中的所有字段添加數(shù)據(jù),可以不寫前面的字段名稱
-- 8. 默認(rèn)值的使用,當(dāng)不給某個字段值時,如果有默認(rèn)值就會添加默認(rèn)值,否則報錯 -- 如果某個列 沒有指定 not null ,那么當(dāng)添加數(shù)據(jù)時,沒有給定值,則會默認(rèn)給 null -- 如果我們希望指定某個列的默認(rèn)值,可以在創(chuàng)建表時指定。
update語句


delete語句


select 語句

- distinct 取消重復(fù), 只顯示一個

-
使用表達(dá)式對查詢的列進(jìn)行運(yùn)算 :
-
在 select 語句中可使用 as 語句
SELECT `name`, (chinese + english + math + 10) FROM student;
-- 使用別名表示學(xué)生分?jǐn)?shù)。 SELECT `name` AS '名字', (chinese + english + math + 10) AS total_score FROM student;

- order by 語句


-
統(tǒng)計/合計函數(shù)
count() 和 count(列) 的區(qū)別
-- 解釋 :count() 返回滿足條件的記錄的行數(shù)
-- count(列): 統(tǒng)計滿足條件的某列有多少個,但是會排除 為 null 的情況-
sum函數(shù)

-
avg函數(shù)
-
max/min函數(shù)
-
分組統(tǒng)計 group-by
having相當(dāng)于group by之后進(jìn)行過濾,相當(dāng)于where(個人理解)
-
字符串函數(shù)
SELECT CONCAT(LCASE(LEFT(ename, 1)), SUBSTRING(ename, 2)) AS `name` FROM emp;
SELECT REPLACE(ename, LEFT(ename, 1), LCASE(LEFT(ename, 1))) FROM emp;
-
數(shù)學(xué)函數(shù)
-- CONV(number2,from_base,to_base) 進(jìn)制轉(zhuǎn)換
-- 下面的含義是 8 是十進(jìn)制的 8, 轉(zhuǎn)成 2 進(jìn)制輸出
SELECT CONV(8, 10, 2) FROM DUAL;
-- RAND([seed]) RAND([seed]) 返回隨機(jī)數(shù) 其范圍為 0 ≤ v ≤ 1.0
-- 老韓說明
-- 1. 如果使用 rand() 每次返回不同的隨機(jī)數(shù) ,在 0 ≤ v ≤ 1.0
-- 2. 如果使用 rand(seed) 返回隨機(jī)數(shù), 范圍 0 ≤ v ≤ 1.0, 如果 seed 不變,該隨機(jī)數(shù)也不變了
SELECT RAND() FROM DUAL;
-
時間日期相關(guān)函數(shù)
-- 顯示所有新聞信息,發(fā)布日期只顯示 日期,不用顯示時間.
SELECT id, content, DATE(send_time) FROM mes;
-- 請查詢在 10 分鐘內(nèi)發(fā)布的新聞, 思路一定要梳理一下.
SELECT * FROM mes
WHERE DATE_ADD(send_time, INTERVAL 10 MINUTE) >= NOW()
SELECT * FROM mes
WHERE send_time >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)



unix時間戳就是指用unix_timestamp()生成的時間戳,可以用from_unixtime()函數(shù)按特定的格式還原
-- unix_timestamp() : 返回的是 1970-1-1 到現(xiàn)在的秒數(shù)
SELECT UNIX_TIMESTAMP() FROM DUAL;
-- FROM_UNIXTIME() : 可以把一個 unix_timestamp 秒數(shù)[時間戳],轉(zhuǎn)成指定格式的日期 -- %Y-%m-%d 格式是規(guī)定好的,表示年月日
-- 意義:在開發(fā)中,可以存放一個整數(shù),然后表示時間,通過 FROM_UNIXTIME 轉(zhuǎn)換
SELECT FROM_UNIXTIME(1618483484, '%Y-%m-%d') FROM DUAL;
SELECT FROM_UNIXTIME(1618483100, '%Y-%m-%d %H:%i:%s') FROM DUAL;
-
加密和系統(tǒng)函數(shù)
-- USER() 查詢用戶 -- 可以查看登錄到 mysql 的有哪些用戶,以及登錄的 IP
SELECT USER() FROM DUAL; -- 用戶@IP 地址
-- DATABASE()查詢當(dāng)前使用數(shù)據(jù)庫名稱 SELECT DATABASE();
-- MD5(str) 為字符串算出一個 MD5 32 的字符串,
-- PASSWORD(str) -- 加密函數(shù), MySQL 數(shù)據(jù)庫的用戶密碼就是 PASSWORD 函數(shù)加密
-
流程控制函數(shù)
單表查詢增強(qiáng)
■ 使用 where 子句 -- ?如何查找 1992.1.1 后入職的員工
-- 老師說明: 在 mysql 中,日期類型可以直接比較, 需要注意格式
SELECT * FROM emp WHERE hiredate > '1992-01-01'
-- ■ 如何使用 like 操作符(模糊)
-- %: 表示 0 到多個任意字符
_: 表示單個任意字符
-- ?如何顯示首字符為 S 的員工姓名和工資
SELECT ename, sal FROM emp
WHERE ename LIKE 'S%'
-- ■ 如何顯示沒有上級的雇員的情況
SELECT * FROM emp
WHERE mgr IS NULL;注意,查看值是否等于null,要用Is。 而不是=
-- ■ 查詢表結(jié)構(gòu)
DESC emp-
分頁查詢
group by 增強(qiáng)查詢
-- (1) 顯示每種崗位的雇員總數(shù)、平均工資。
SELECT COUNT(*), AVG(sal), job
FROM emp
GROUP BY job;
理解: group by排序字符時,將相同字符的放在一行,count和AVG 與 group by 合作,有奇效
-- (2) 顯示雇員總數(shù),以及獲得補(bǔ)助的雇員數(shù)。
-- 思路: 獲得補(bǔ)助的雇員數(shù) 就是 comm 列為非 null, 就是 count(列),如果該列的值為 null, 不會統(tǒng)計 , SQL 非常靈活,需要我們動腦筋.
SELECT COUNT(), COUNT(comm)
FROM emp
-- 老師的擴(kuò)展要求:統(tǒng)計沒有獲得補(bǔ)助的雇員數(shù)
SELECT COUNT(), COUNT(IF(comm IS NULL, 1, NULL))
FROM emp
SELECT COUNT(), COUNT() - COUNT(comm)
FROM emp
-- (3) 顯示管理者的總?cè)藬?shù)。小技巧:嘗試寫->修改->嘗試[正確的]
SELECT COUNT(DISTINCT mgr)
FROM emp;
-
注意:
having可以操作統(tǒng)計函數(shù)和普通過濾語句,而where不可以操作
多表查詢
- 多表查詢是指基于兩個和兩個以上的表查詢,在實際應(yīng)用中,查詢單個表可能不能滿足需求。
- 如果直接查詢多個表,會出現(xiàn)笛卡爾集,集表的每一行都會和其他表的每一行匹配。
- 想要顯示想要的結(jié)果,需要使用條件來過濾或限制行。
- 多表查詢的條件不能少于表的個數(shù) - 1,否則會出現(xiàn)笛卡爾集。
-- ?如何顯示部門號為 10 的部門名、員工名和工資 SELECT ename,sal,dname,emp.deptno
FROM emp, dept
WHERE emp.deptno = dept.deptno AND emp.deptno = 10
-- ?顯示各個員工的姓名,工資,及其工資的級別
-- 思路 姓名,工資 來自 emp 13
-- 工資級別 salgrade 5
-- 寫 sql , 先寫一個簡單,然后加入過濾條件...
select ename, sal, grade
from emp , salgrade
where sal between losal
- 自連接
自連接是指同一張表的連接查詢,把一張表看做是兩張表.
-- 這里老師小結(jié):
-- 自連接的特點(diǎn)
- 把同一張表當(dāng)做兩張表使用 --
- 需要給表取別名 表名 表別名 --
- 列名不明確,可以指定列的別名 列名 as 列的別名
-- 思考題: 顯示公司員工名字和他的上級的名字
-- 老韓分析: 員工名字 在 emp, 上級的名字的名字 emp
-- 員工和上級是通過 emp 表的 mgr 列關(guān)聯(lián)
SELECT worker.ename AS '職員名' , boss.ename AS '上級名'
FROM emp worker, emp boss
WHERE worker.mgr = boss.empno;
- 子查詢
什么是子查詢?
子查詢是指嵌入在其他sql語句中的select語句,也叫嵌套查詢
- 單行子查詢
單行子查詢是指只返回一行數(shù)據(jù)的子查詢語句
如何顯示與 SMITH 同一部門的所有員工?
/* 1. 先查詢到 SMITH 的部門號得到
2. 把上面的 select 語句當(dāng)做一個子查詢來使用 */
SELECT deptno
FROM emp
WHERE ename = 'SMITH'
-- 下面的答案.
SELECT *
FROM emp
WHERE deptno = (
SELECT deptno
FROM emp
WHERE ename = 'SMITH' )
- 多行子查詢
是指返回多行數(shù)據(jù)的子查詢,使用關(guān)鍵字In
/* 1. 查詢到 10 號部門有哪些工作
2. 把上面查詢的結(jié)果當(dāng)做子查詢使用 */
select distinct job
from emp
where deptno = 10;
-- 下面語句完整
select ename, job, sal, deptno
from emp
where job in (
SELECT DISTINCT job
FROM emp
WHERE deptno = 10 ) and deptno <> 10
- 子查詢當(dāng)做臨時表
-- 查詢ecshop中各個類別中,價格最高的商品
-- 查詢 商品表
-- 先得到 各個類別中,價格最高的商品 max + group by cat_id, 當(dāng)做臨時表
-- 把子查詢當(dāng)做一張臨時表可以解決很多很多復(fù)雜的查詢
select cat_id , max(shop_price)
from ecs_goods
group by cat_id
-- 這個最后答案
select goods_id, ecs_goods.cat_id, goods_name, shop_price
from (
SELECT cat_id , MAX(shop_price) as max_price
FROM ecs_goods
GROUP BY cat_id
) temp , ecs_goods
where temp.cat_id = ecs_goods.cat_id
and temp.max_price = ecs_goods.shop_price
- 子查詢中使用all any操作符
-- all 和 any 的使用
-- 請思考:顯示工資比部門 30 的所有員工的工資高的員工的姓名、工資和部門號
SELECT ename, sal, deptno
FROM emp
WHERE sal > ALL(
SELECT sal
FROM emp
WHERE deptno = 30 )
-- 可以這樣寫
SELECT ename, sal, deptno
FROM emp
WHERE sal > ( SELECT MAX(sal)
FROM emp
WHERE deptno = 30 )
-- 請思考:如何顯示工資比部門 30 的其中一個員工的工資高的員工的姓名、工資和部門號
SELECT ename, sal, deptno
FROM emp WHERE sal > any(
SELECT sal
FROM emp
WHERE deptno = 30 )
SELECT ename, sal, deptno
FROM emp
WHERE sal > (
SELECT min(sal)
FROM emp
WHERE deptno = 30 )
-
多列子查詢
多列子查詢是指查詢返回多個列數(shù)據(jù)的子查詢語句
-- 請思考如何查詢與 allen 的部門和崗位完全相同的所有雇員(并且不含 allen 本人)
-- (字段 1, 字段 2 ...) = (select 字段 1,字段 2 from 。。。。)
-- 分析: 1. 得到 smith 的部門和崗位
SELECT deptno , job
FROM emp
WHERE ename = 'ALLEN'
-- 分析: 2 把上面的查詢當(dāng)做子查詢來使用,并且使用多列子查詢的語法進(jìn)行匹配
SELECT *
FROM emp
WHERE (deptno , job) = ( SELECT deptno , job FROM emp
WHERE ename = 'ALLEN' ) AND ename != 'ALLEN
- 在from子句中使用子查詢
-- 查詢每個部門的信息(包括:部門名,編號,地址)和人員數(shù)量,我們一起完成。
-- 1. 部門名,編號,地址 來自 dept 表
-- 2. 各個部門的人員數(shù)量 -》 構(gòu)建一個臨時表
-- 還有一種寫法 表.* 表示將該表所有列都顯示出來, 可以簡化 sql 語句
-- 在多表查詢中,當(dāng)多個表的列不重復(fù)時,才可以直接寫列名
SELECT tmp.* , dname, loc
FROM dept, (
SELECT COUNT(*) AS per_num, deptno
FROM emp
GROUP BY deptno
) tmp
WHERE tmp.deptno = dept.deptno
- 表復(fù)制
-- 為了對某個 sql 語句進(jìn)行效率測試,我們需要海量數(shù)據(jù)時,可以使用此法為表創(chuàng)建海量數(shù)據(jù)
CREATE TABLE my_tab01
( id INT,
`name` VARCHAR(32),
sal DOUBLE,
job VARCHAR(32),
deptno INT);
-- 1. 先把 emp 表的記錄復(fù)制到 my_tab01
INSERT INTO my_tab01
(id, `name`, sal, job,deptno)
SELECT empno, ename, sal, job, deptno FROM emp;
-- 2. 自我復(fù)制
INSERT INTO my_tab01
SELECT * FROM my_tab01;
SELECT COUNT(*) FROM my_tab01;
- 如何刪除一個表的重復(fù)記錄
-- 1. 先創(chuàng)建一張表 my_tab02,
-- 2. 讓 my_tab02 有重復(fù)的記錄
CREATE TABLE my_tab02 LIKE emp;
-- 這個語句 把 emp 表的結(jié)構(gòu)(列),復(fù)制到 my_tab02
-- 3. 考慮去重 my_tab02 的記錄
/*
思路
(1) 先創(chuàng)建一張臨時表 my_tmp , 該表的結(jié)構(gòu)和 my_tab02 一樣
(2) 把 my_tmp 的記錄 通過 distinct 關(guān)鍵字 處理后 把記錄復(fù)制到 my_tmp
(3) 清除掉 my_tab02 記錄
(4) 把 my_tmp 表的記錄復(fù)制到 my_tab02
(5) drop 掉 臨時表 my_tmp
CREATE TABLE tmp LIKE my_tab02;
INSERT INTO tmp
SELECT DISTINCT * FROM my_tab02;
DELETE FROM my_tab02;
INSERT INTO my_tab02
SELECT * FROM tmp;
DROP TABLE tmp;






















