01基礎(chǔ)

啟動數(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ù)類型

  1. 數(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] 大小不確定 (最常用)
  2. 文本類型(字符串類型)
    char 0- 255 一個字節(jié) (最常用)
    varchar 0-65535 兩個字節(jié) (最常用)
    text 0- 216 - 1 兩個字節(jié) (最常用)
    longtext 0- 232 - 1 四個字節(jié)
  3. 二進(jìn)制數(shù)據(jù)(使用不多)
    blob 0 - 216 - 1
    longblob 0 - 232 - 1
  4. 日期類型
    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不可以操作

  • 多表查詢

  1. 多表查詢是指基于兩個和兩個以上的表查詢,在實際應(yīng)用中,查詢單個表可能不能滿足需求。
  2. 如果直接查詢多個表,會出現(xiàn)笛卡爾集,集表的每一行都會和其他表的每一行匹配。
  3. 想要顯示想要的結(jié)果,需要使用條件來過濾或限制行。
  4. 多表查詢的條件不能少于表的個數(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)
  1. 把同一張表當(dāng)做兩張表使用 --
  2. 需要給表取別名 表名 表別名 --
  3. 列名不明確,可以指定列的別名 列名 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語句,也叫嵌套查詢

  1. 單行子查詢
    單行子查詢是指只返回一行數(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' )
  1. 多行子查詢
    是指返回多行數(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;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容