MySQL客戶端連接,系統自帶的命令列工具執行指令: mysql [-h 127.0.0.1] [-P 3306] -u root -p
SQL
SQL通用語法
- SQL陳述句可以單行或多行書寫,以分號結尾
- SQL陳述句可以使用空格/縮進來增強陳述句的可讀性
- MySQL資料庫的SQL陳述句不區分大小寫,關鍵字建議使用大寫
- 注釋:
- 單行注釋:-- 注釋內容 或 # 注釋內容(MySQL特有)
- 多行注釋: /* 注釋內容 */
DDL
| DDL-資料庫操作 | 具體內容 | SQL陳述句 |
|---|---|---|
| 查詢 | 查詢所有資料庫 | show databases; |
| 查詢當前資料庫 | select database(); | |
| 創建 | 創建資料庫 | create database [if not exists] 資料庫名 [default charset 字符集] [collate 排序規則]; |
| 洗掉 | 洗掉資料庫 | drop database [if exists] 資料庫名; |
| 使用 | 使用/切換資料庫 | use 資料庫名; |
| DDL-表操作 | 具體內容 | SQL陳述句 |
|---|---|---|
| 查詢 | 查詢當前資料庫所有表 | |
| 查詢表結構 | desc 表名; | |
| 查詢指定表的建表陳述句 | show create table 表名; | |
| 創建 | 創建表 | create table 表名(欄位名 欄位型別,欄位名 欄位型別); |
| 修改 | 添加欄位 | alter table 表名 add 欄位名 資料型別(長度) [COMMENT 注釋] [約束]; |
| 修改指定欄位的資料型別 | alter table 表名 modify 欄位名 新資料型別(長度); | |
| 修改欄位名和欄位型別 | alter table 表名 change 舊欄位名 新欄位名 新資料型別(長度) [COMMENT 注釋] [約束]; | |
| 洗掉指定欄位 | alter table 表名 drop 欄位名; | |
| 重命名 | 修改表名 | alter table 表名 rename to 新表名; |
| 洗掉 | 洗掉指定表 | drop table [if exists] 表名; |
| 洗掉指定表,并重新創建該表 | truncate table 表名; |
create table 表名(
欄位名1 欄位1型別[COMMENT 欄位1注釋],
欄位名2 欄位2型別[COMMENT 欄位2注釋],
……
欄位名n 欄位n型別[COMMENT 欄位n注釋]
)[COMMENT 表注釋];
MySQL中的資料型別有很多,主要分為三類:數值型別、字串型別、日期時間型別
數值型別
| 型別 | 大小/位元組 | 描述 | 有符號范圍(SIGNED) | 無符號范圍(UNSIGNED) |
|---|---|---|---|---|
| tinyint | 1 | 小整數值 | (-128 , 127) | (0 , 255) |
| smallint | 2 | 大整數值 | (-32768 , 32767) | (0 , 65535) |
| mediumint | 3 | 大整數值 | (-8388608 , 8388607) | (0 , 16777215) |
| int或integer | 4 | 大整數值 | (-2147483648 , 2147483647) | (0 , 4294967295) |
| bigint | 8 | 極大整數值 | (-2^63 , 2^63 -1) | (0 , 2^64 -1) |
| float | 4 | 單精度浮點數 | (-3.402823466 E+38 , 3.402823466351 E+38) | 0和(1.175494351 E-38,3.402823466 E+38) |
| double | 8 | 雙精度浮點數 | (-1.7976931348623157 E+308 , 1.7976931348623157 E+308) | 0和(2.2250738585072014 E-308 , 1.7976931348623157 E+308) |
| decimal | 小數值(精確定點數) | 依賴于M(精度)和D(標度)的值 | 依賴于M(精度)和D(標度)的值 |
字串型別
| 型別 | 大小/位元組 | 描述 |
|---|---|---|
| char | 0-255 | 定長字串 |
| varchar | 0-65535 | 變長字串 |
| tinyblob | 0-255 | 不超過255個字符的二進制資料 |
| tinytext | 0-255 | 短文本字串 |
| blob | 0-65535 | 二進制形式的長文本資料 |
| text | 0-255 | 長文本資料 |
| mediumblob | 0-65535 | 二進制形式的中等長度文本資料 |
| mediumtext | 0-16777215 | 中等長度文本資料 |
| longblob | 0-16777215 | 二進制形式的極大文本資料 |
| longtext | 0-4294967295 | 極大文本資料 |
日期型別
| 型別 | 大小/位元組 | 范圍 | 格式 | 描述 |
|---|---|---|---|---|
| date | 3 | 1000-01-01 至 9999-12-31 | YYYY-MM-DD | 日期值 |
| time | 3 | -838:59:59 至 838:59:59 | HH:MM:SS | 時間值或持續時間 |
| year | 1 | 1901 至 2155 | YYYY | 年份值 |
| datetime | 8 | 1000-01-01 00:00:00 至 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和時間值 |
| timestamp | 4 | 1970-01-01 00:00:01 至 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和時間值,時間戳 |
DML
DML英文全稱是Data Manipulation Language(資料操作語言),用來對資料庫中表的資料記錄進行增刪改操作
- 添加資料(INSERT)
- 修改資料(UPDATE)
- 洗掉資料(DELETE)
| DML操作分類 | 具體內容 | SQL陳述句 |
|---|---|---|
| 添加資料 | 給指定欄位添加資料 | insert into 表名(欄位名1,欄位名2,…) values (值1,值2,…); |
| 給全部欄位添加資料 | insert into 表名 values (值1,值2,…); | |
| 批量添加資料 | insert into 表名(欄位名1,欄位名2,…) values (值1,值2,…),(值1,值2,…),(值1,值2,…); | |
| 批量添加資料 | insert into 表名 values (值1,值2,…),(值1,值2,…),(值1,值2,…); | |
| 修改資料 | 修改指定欄位的資料 | update 表名 set 欄位名1=值1,欄位名2=值2 [where 條件]; |
| 修改整張表的資料 | update 表名 set 欄位名1=值1,欄位名2=值2; | |
| 洗掉某個欄位的值 | update 表名 set 欄位名=null; | |
| 洗掉資料 | 洗掉指定欄位的資料 | delete from 表名 [where 條件]; |
| 洗掉整張表所有資料 | delete from 表名; |
DQL
DQL英文全稱是Data Query Language(資料查詢語言),資料查詢語言,用來查詢資料庫中表的記錄
語法:select 欄位串列 from 表名 where 條件串列;
select 欄位串列
from 表名串列
where 條件串列
group by 分組欄位串列
having 分組后條件串列
order by 排序欄位串列
limit 分頁引數
DQL執行順序:from → where → group by → select → order by → limit
| DQL基本查詢 | SQL陳述句 |
|---|---|
| 查詢多個欄位的資料 | select 欄位1,欄位2 from 表名; |
| 查詢全部欄位的資料 | select * from 表名; |
| 設定別名 | select 欄位1 [as] 別名1,欄位2 [as] 別名2 from 表名; |
| 去除重復記錄 | select distinct 欄位名 from 表名; |
條件查詢的運算子
| 條件串列 | 說明 |
|---|---|
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
| = | 等于 |
| <> 或 != | 不等于 |
| between…and… | 在某個范圍之內(含最小,最大值) |
| in(…) | 在in之后的串列中的值,多選一 |
| like 占位符 | 模糊匹配(_匹配單個字符,%匹配任意個字符) |
| is null 或 is not null | 是空值null / 不是空值 |
| and 或 && | 并且(多個條件同時成立) |
| or 或 || | 或者(多個條件任意一個成立) |
| not 或 ! | 非,不是 |
DQL聚合查詢:將一列資料作為一個整體,進行縱向計算.語法:select 聚合函式(欄位串列) from 表名;
注意:null值不參與所有聚合函式運算
| 具體操作 | 語法 |
|---|---|
| 統計指定表的記錄總量 | select count(*) from 表名; |
| 統計指定表的指定欄位記錄的總數量 | select count(指定欄位) from 表名; |
| 統計指定表的指定欄位的最大值 | select max(指定欄位) from 表名; |
| 統計指定表的指定欄位的最小值 | select min(指定欄位) from 表名; |
| 統計指定表的指定欄位的求和 | select sum(指定欄位) from 表名; |
| 統計指定表的指定欄位的平均值 | select avg(指定欄位) from 表名; |
分組查詢: select 欄位串列 表名 [where 條件] group by 分組欄位名 [having 分組后的過濾條件];
執行順序:
- where是分組之前進行過濾,不滿足where條件,不參與分組
- 執行聚合函式
- having是分組之后對結果進行過濾
注意:where不能對聚合函式進行判斷,而having可以;分組之后查詢的欄位一般為聚合函式和分組欄位,查詢其他欄位無任何意義
-- 查詢年齡小于45的員工,并根據作業地址分組,獲取員工數量大于等于3的作業地址
select workaddress,count(*) from emp where age<45 group by workaddress having count(*)>=3;
select workaddress,count(*) address from emp where age<45 group by workaddress having address>=3;
排序查詢: select 欄位串列 from 表名 order by 欄位名1 排序方式,欄位名2 排序方式;
排序方式有兩種:升序ASC(默認值);降序desc
注意:如果是多欄位排序,當第一個欄位值相同時,才會根據第二個欄位進行排序
分頁查詢: select 欄位串列 from 表名 limit 起始索引,查詢記錄數;
-- 查詢第一頁的員工資料,每頁展示10條記錄
select * from emp limit 0,10;
select * from emp limit 10;
-- 查詢第二頁的員工資料,每頁展示10條記錄
select * from emp limit 10,10;
注意
- 起始索引從0開始,起始索引 = (查詢頁碼 - 1)* 每頁顯示記錄數
- 如果查詢的是第一頁資料,起始索引可以省略,直接簡寫為 limit 10
- 分頁查詢是資料庫的方言,不同的資料庫有不同的實作,MySQL中是LIMIT
DCL
DCL英文全稱是Data ControlLanguage(資料控制語言),用來管理資料庫用戶,控制資料庫的訪問權限
| DCL-管理用戶 | SQL語法 |
|---|---|
| 查詢用戶 | use mysql; select * from user; |
| 創建用戶 | create user '用戶名'@'主機名' identified by '密碼'; |
| 修改用戶密碼 | alter user '用戶名'@'主機名' identified with mysql_native_password by '新密碼'; |
| 洗掉用戶 | drop user '用戶名'@'主機名'; |
主機名可以使用 % 通配
-- 創建用戶zhangsan,只能在當前主機localhost訪問,密碼為123456
create user 'zhangsan'@'localhost' identified by '123456';
-- 創建用戶lisi,可以在任意主機訪問該資料庫,密碼為123456
create user 'lisi'@'%' identified by '123456';
-- 修改用戶lisi的訪問密碼為1234
alter user 'lisi'@'%' identified with mysql_native_password by '123456';
-- 洗掉zhangsan@localhost用戶
drop user 'zhangsan'@'localhost';
MySQL中定義了很多種權限,但是常用的就以下幾種:
| 權限 | 說明 |
|---|---|
| ALL, ALL PRIVILEGES | 所有權限 |
| SELECT | 查詢資料 |
| INSERT | 插入資料 |
| UPDATE | 修改資料 |
| DELETE | 洗掉資料 |
| ALTER | 修改表 |
| DROP | 洗掉資料庫/表/視圖 |
| CREATE | 創建資料庫/表 |
注意:
- 多個權限之間,使用逗號分隔
- 授權時,資料庫名和表名可以使用 * 進行通配,代表所有
| DCL-權限控制 | SQL語法 |
|---|---|
| 查詢權限 | show grants for '用戶名'@'主機名'; |
| 授予權限 | grant 權限串列 on 資料庫名.表名 to '用戶名'@'主機名'; |
| 撤銷權限 | revoke 權限串列 on 資料庫名.表名 from '用戶名'@'主機名'; |
-- 查詢權限
show grants for 'lisi'@'%';
-- 授予權限
grant all on *.* to 'lisi'@'%';
-- 撤銷權限
revoke all on test.* from 'lisi'@'%';
函式
函式是指一段可以直接被另一段程式呼叫的程式或代碼
使用函式: select 函式(引數);
字串函式
| 函式 | 說明 |
|---|---|
| concat(str1,str2,…) | 字串拼接,將str1/str2等拼接成一個字串 |
| lower(str) | 將字串str全部轉為小寫 |
| upper(str) | 將字串str全部轉為大寫 |
| lpad(str,n,pad) | 左填充;用字串pad對str的左邊進行填充,達到n個字串長度 |
| rpad(str,n,pad) | 右填充;用字串pad對str的右邊進行填充,達到n個字串長度 |
| trim(str) | 去掉字串頭部和尾部的空格 |
| substring(str,start,len) | 回傳從字串str自start位置起的len個長度的字串 |
數值函式
| 函式 | 說明 |
|---|---|
| ceil(x) | 向上取整 |
| floor(x) | 向下取整 |
| mod(x,y) | 回傳x/y的模 |
| rand() | 回傳0-1內的亂數 |
| round(x,y) | 求引數x的四舍五入的值,保留y位小數 |
日期函式
| 函式 | 說明 |
|---|---|
| curdate() | 回傳當前日期 |
| curtime() | 回傳當前時間 |
| now() | 回傳當前日期和時間 |
| year(date) | 獲取指定date的年份 |
| month(date) | 獲取指定date的月份 |
| day(date) | 獲取指定date的日期 |
| datediff(date1,date2) | 回傳起始時間date1和結束時間date2之間的天數(date1-date2) |
| date_add(date,interval expr type) | 回傳一個日期值加上一個時間間隔expr后的時間值 |
流程函式
| 函式 | 說明 |
|---|---|
| if(value,t,f) | 如果value為true,則回傳t,否則回傳f |
| ifnull(value1,value2) | 如果value1不為空,回傳value1,否則回傳value2 |
| case when [val1] then [res1] … else [default] end | 如果val1為true,回傳res1,…否則回傳default默認值 |
| case [expr] when [val1] then [res1] … else [default] end | 如果expr的值等于val1,回傳res1,…否則回傳default默認值 |
點擊查看代碼
-- 生成一個六位數的隨機驗證碼
select lpad(round(rand()*1000000,0),6,'0');
select curdate();
select curtime();
select now();
select year(now());
select month(now());
select day(now());
select date_add(now(),interval 70 day);
select datediff('2022-12-01','2022-11-20');
select if(true,'success','error'); -- success
select if(false,'success','error'); -- error
select ifnull('str','default'); -- str
select ifnull('','default'); -- 空
select ifnull(null,'default'); -- default
-- case when then else end
-- 需求:查詢emp表的員工姓名和作業地址(北京/上海——一線城市,其他——二線城市)
select
name,
( case workaddress when '北京' then '一線城市' when '上海' then '一線城市' else '二線城市' end) as '作業地址'
from emp;
select
id,
name,
(case when math >= 85 then '優秀' when math >= 60 then '及格' else '不及格' end) '數學',
(case when chinese >= 85 then '優秀' when chinese >= 60 then '及格' else '不及格' end) '語文',
(case when english >= 85 then '優秀' when english >= 60 then '及格' else '不及格' end) '英語'
from score;
約束
約束是作用于表中欄位上的規則,用于限制存盤在表中的資料;從而保證資料庫中資料的正確、有效性和完整性
| 約束 | 說明 | 關鍵字 |
|---|---|---|
| 主鍵約束 | 主鍵是一行資料的唯一標識,要求非空且唯一 | primary key |
| 外鍵約束 | 用來讓兩張表的資料之間建立連接,保證資料的一致性和完整性 | foreign key |
| 非空約束 | 限制該欄位的資料不能為null | not null |
| 唯一約束 | 保證該欄位的所有資料都是唯一/不重復的 | unique |
| 默認約束 | 保存資料時,如果未指定該欄位的值,則采用默認值 | default |
| 檢查約束 | 保證欄位值滿足一個條件 | check |
create table user(
id int primary key auto_increment comment '主鍵且自動增長',
name varchar(10) not null unique comment '姓名',
age int check ( age > 0 && age <= 120 ) comment '年齡',
status char(1) default '1' comment '狀態',
gender char(1) comment '性別'
) comment '用戶表';
外鍵約束語法
-- 添加外鍵:創建表的同時添加外鍵
create table 表名(
欄位名 資料型別,
…
[constraint] [外鍵名稱] foreign key (外鍵欄位名) references 主表(主表列名)
);
-- 添加外鍵
alter table 表名 add constraint 外鍵名稱 foreign key (外鍵欄位名) references 主表(主表列名);
-- 添加外鍵的同時指定洗掉或更新的行為
alter table 表名 add constraint 外鍵名稱 foreign key(外鍵欄位) references 主表名(主表欄位名) on update cascade on delete cascade;
-- 洗掉外鍵
alter table 表名 drop foreign key 外鍵名稱;
| 洗掉/更新行為 | 說明 |
|---|---|
| no action | 當在父表中洗掉/更新對應記錄時,首先檢查該記錄是否有對應外鍵,如果有則不允許洗掉/更新(與restrict一致) |
| restrict | 當在父表中洗掉/更新對應記錄時,首先檢查該記錄是否有對應外鍵,如果有則不允許洗掉/更新(與no action一致) |
| cascade | 當在父表中洗掉/更新對應記錄時,首先檢查該記錄是否有對應外鍵,如果有,則也洗掉/更新外鍵在子表中的記錄 |
| set null | 當在父表中洗掉對應記錄時,首先檢查該記錄是否有對應外鍵,如果有則設定子表中該外鍵值為null(這就要求該外鍵允許取null) |
| set default | 父表有變更時,子表將外鍵列設定成一個默認的值(Innodb不支持) |
多表查詢
多表關系
- 一對多(多對一)
- 案例: 部門與員工的關系;一個部門對應多個員工,一個員工對應一個部門
- 實作: 在多的一方建立外鍵,指向一的一方的主鍵
- 多對多
- 案例: 學生與課程的關系;一個學生可以選修多門課程,一門課程也可以供多個學生選擇
- 實作: 建立第三張中間表,中間表至少包含兩個外鍵,分別關聯兩方主鍵
- 一對一
- 案例: 用戶與用戶詳情的關系;一對一關系,多用于單表拆分,將一張表的基礎欄位放在一張表中,其他詳情欄位放在另一張表中,以提升操作效率
- 實作: 在任意一方加入外鍵,關聯另外一方的主鍵,并且設定外鍵為唯一的(UNIQUE)
笛卡爾積:笛卡爾乘積是指在數學中,兩個集合A集合和B集合的所有組合情況,(在多表查詢時,需要消除無效的笛卡爾積)
連接分類:
- 內連接:相當于查詢A、B交集部分資料
- 外連接
- 左外連接:查詢左表所有資料,以及兩張表交集部分資料
- 右外連接:查詢右表所有資料,以及兩張表交集部分資料
- 自連接:當前表與自身的連接查詢,自連接必須使用表別名
- 自連接查詢,可以是基本連接,還可以是內連接查詢或者外連接查詢
- 聯合查詢:就是把多次查詢的結果合并起來,形成一個新的查詢結果集
- union all會將全部的資料直接合并在一起;union會對合并之后的資料去重
- 對于聯合查詢的多張表的列數必須保持一致,欄位型別也需要保持一致
- 子查詢/嵌套查詢:SQL陳述句中嵌套SELECT陳述句,稱為嵌套查詢,又稱子查詢
- 子查詢外部的陳述句可以是INSERT / UPDATE / DELETE / SELECT 的任何一個
- 根據子查詢結果不同,分為
- 標量子查詢(子查詢結果為單個值):常用的運算子有 = <> > >= < <=
- 列子查詢(子查詢結果為一列):常用的運算子有 IN、NOT IN、ANY、SOME、ALL
- 行子查詢(子查詢結果為一行):常用的運算子有 = 、<> 、IN 、NOT IN
- 表子查詢(子查詢結果為多行多列):常用的運算子有 IN
- 根據子查詢位置,分為:WHERE之后、FROM之后、SELECT之后
| 多表連接分類 | 具體分類 | SQL語法 |
|---|---|---|
| 內連接(兩張表交集部分) | 隱式內連接 | select 欄位串列 from 表1,表2 where 條件; |
| 顯式內連接 | select 欄位串列 from 表1 [inner] join 表2 on 連接條件; | |
| 外連接 | 左外連接 | select 欄位串列 from 表1 left [outer] join 表2 on 條件; |
| 右外連接 | select 欄位串列 from 表1 right [outer] join 表2 on 條件; | |
| 自連接 | select 欄位串列 from 表A 別名A join 表A 別名B on 條件; | |
| 聯合查詢 | select 欄位串列 from 表A union [all] select 欄位串列 from 表B; |
|
| 子查詢/嵌套查詢 | select * from t1 where column1 = (select column1 from t2); |
子查詢的代碼案例
-- 標量子查詢
-- 需求1:查詢"銷售部"的所有員工資訊
select * from emp where dept_id = (select id from dept where name = '銷售部');
-- 需求2:查詢指定入職日期之后入職的員工資訊
select * from emp where entrydate > (select entrydate from emp where name='張三');
-- 列子查詢
-- 需求1:查詢銷售部和市場部的部門所有員工資訊
select * from emp where dept_id in (select id from dept where name='銷售部' or name='市場部');
-- 需求2:查詢比財務部所有人工資都高的員工資訊
select * from emp where salary > all (select salary from emp where dept_id = (select id from dept where name = '財務部'));
-- 需求3:查詢比研發部其中任意一人工資高的員工資訊
select * from emp where salary > any (select salary from emp where dept_id = (select id from dept where name = '研發部'));
select * from emp where salary > some (select salary from emp where dept_id = (select id from dept where name = '研發部'));
-- 行子查詢
-- 需求:查詢與'張三'的薪資及直屬領導相同的員工資訊
select * from emp where (salary,managerid) = (select salary,managerid from emp where name = '張三');
-- 表子查詢
-- 需求1:查詢與'張三','李四'的職位和薪資相同的員工資訊
select * from emp where (job,salary) in (select job,salary from emp where name = '張三' or name = '李四');
-- 需求2:查詢入職日期'2022-01-01' 之后的員工資訊及其部門資訊
select e.*,d.* from (select * from emp where entrydata > '2022-01-01' e left join dept d on e.dept_id = d.id);
事務
事務是一組操作的集合,它是一個不可分割的作業單位,事務會把所有的操作作為一個整體一起向系統提交或撤銷操作請求,即這些操作要么同時成功,要么同時失敗
默認MySQL的事務是自動提交的,也就是說,當執行一條DML陳述句,MySQL會立即隱式的提交事務
| 事務操作 | SQL語法 |
|---|---|
| 查看事務提交方式(1為自動提交;0為手動提交) | select @@autocommit; |
| 設定事務提交方式 | set @@autocommit=0; |
| 提交事務 | commit; |
| 回滾事務 | rollback; |
| 開啟事務 | start transaction; 或 begin; |
事務四大特性
事務四大特性
- 原子性(Atomicity):事務是不可分割的最小操作單元,要么全部成功,要么全部失敗
- 一致性(Consistency):事務完成時,必須使所有的資料都保持一致狀態
- 隔離性(Isolation):資料庫系統提供的隔離機制,保證事務在不受外部并發操作影響的獨立環境下運行
- 持久性(Durability):事務一旦提交或回滾,它對資料庫中的資料的改變就是永久的
| 并發事務問題 | 描述 |
|---|---|
| 臟讀 | 一個事務讀到另外一個事務還沒有提交的資料 |
| 不可重復讀 | 一個事務先后讀取同一條記錄,但兩次讀取的資料不同,稱之為不可重復讀 |
| 幻讀 | 一個事務按照條件查詢資料時,沒有對應的資料行,但是在插入資料時,又發現這行資料已經存在,好像出現了幻影 |
| 事務隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
|---|---|---|---|
| read uncommitted | 存在 | 存在 | 存在 |
| read committed(oracle默認) | 解決了 | 存在 | 存在 |
| repeatable read(MySQL默認) | 解決了 | 解決了 | 存在 |
| serializable | 解決了 | 解決了 | 解決了 |
注意:事務隔離級別越高,資料越安全,但是性能越低
-- 查看事務隔離級別
select @@transaction_isolation;
-- 設定事務隔離級別(session是當前會話有效;global是全部會話都有效)
set [session|global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable};
本文來自博客園,作者:不二橘子醬,轉載請注明原文鏈接:https://www.cnblogs.com/marmaladeHY/p/15824658.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/421373.html
標籤:其他
上一篇:MySQL-基礎語法
