MySOL
SQL語法
本節用到的架構:
特點:
- SQL語句可以單行或多行書寫,以;結尾
- 可以使用空格和縮進增強語句的可讀性
- MySQL的SQL語句不區分大小,關鍵字建議大寫
3種註釋
單行:
-- 註釋內容
#註釋內容 (MySQL特有)
多行:
/*註釋內容*/
SQL按功能分類
- DDL:操作數據庫、表
- DML:增刪改表中的數據
- DQL:查詢表中的數據
- DCL:管理用戶,授予權限
DDL
作用:操作數據庫、表
操作數據庫:CRUD
- C(create):創建數據庫
create database 數據庫名稱
改進後:
create database if not exists 數據庫名稱;(防止重複)
create database 數據庫名稱 character set 字符集名稱(更改默認字符集:utf-8)
綜合:
create database if not exists 數據庫名稱 character set 字符集名稱
實例代碼
CREATE DATABASE IF NOT EXISTS Student;-- 創建Student數據庫
- R(Retrieve):查詢數據庫
查詢所有數據庫名稱
show databases;
查詢某個數據庫
show create database 數據庫名稱;
實例代碼
SHOW CREATE DATABASE Student; -- 查詢Student數據庫
- U(update):修改數據庫
修改數據庫的字符集
alter database 數據庫名稱 character set 字符集名稱;
實例代碼
ALTER DATABASE Student CHARACTER SET utf-8; -- 將字符集改爲utf-8
- D(delete):刪除數據庫
drop database 數據庫名稱;
改進後:
drop database if exists 數據庫名稱;(判斷數據庫存在,存在再刪除)
實例代碼
drop database if exists Student; -- 刪除Student數據庫
- 使用:數據庫
查詢當前正在使用的數據庫名稱
select database();
使用數據庫
use 數據庫名稱;
實例代碼
USE Student; -- 使用Student數據庫
操作表:CRUD
數據庫的數據類型
數據類型 | 含義 | 例子 |
---|---|---|
int | 整數類型 | age int; |
double | 小數類型 | score double(5,2); 一共5位,小數點後保留2位 |
date | 日期,只包含年月日,yyyy-MM-dd | birthday date |
datetime | 日期,包含年月日時分秒,yyyy-MM-dd HH:mm:ss | time datetime |
timestamp | 時間錯類型,如果是null,默認複製系統當前時間 | time timestamp; |
varchar | 字符串 | name varchar(10); |
- C(create):創建表
create table 表名(
列名1 數據類型1,
列名2 數據類型2,
...
列名n 數據類型n); //注意:最後一行沒有逗號
複製表
create table 表名 like 被複制的表名稱
實例代碼
CREATE TABLE class_01( -- 創建班級表
NAME VARCHAR(10), -- 姓名
age INT, -- 年齡
class VARCHAR(20), -- 班級
English DOUBLE(3,1), -- 英語
Chinese DOUBLE(3,1), -- 語文
Math DOUBLE(3,1), -- 數學
recordtime TIMESTAMP) -- 錄檔日期
- R(Retrieve):查詢表
查詢某個數據庫中所有的表名稱
show tables;
查詢表結構
desc 表名;
實例代碼
DESC class_01; -- 查詢表結構
- U(update):修改表
修改表名
alter table 表名 rename to 新表名;
修改表的字符集
alter table 表名 character set 新字符集;
添加一列
alter table 表名 add 列名 數據類型;
修改列名稱、數據類型
alter table 表名 change 列名 新列名 (新)數據類型;
alter table 表名 modify 列名 新數據類型;
刪除列
alter table 表名 drop 列名;
實例代碼
ALTER TABLE class_01 RENAME TO class_1; -- 將表名class_01改爲class_1
ALTER TABLE class_1 ADD temp INT; -- 添加一列temp列
ALTER TABLE class_1 CHANGE temp newtemp VARCHAR(6); -- 將int類型temp列改爲varchar(6)類型 newtemp列
ALTER TABLE class_1 MODIFY newtemp INT; -- 將varchar(6)類型newtemp列改爲int類型
ALTER TABLE class_1 DROP newtemp; -- 刪除newtemp列
- D(delete):刪除表
drop table 表名;
改進:
drop table if exists 表名;
實例代碼
drop table if exits class_1; -- 刪除class_1表
DML
作用:增刪改表中的數據
- 添加數據:
insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
實例代碼
INSERT INTO class_1 VALUES("Tom",18,"一班",80,91.5,78,NULL); -- 添加一條學生記錄
注意:
-
列名與值要一一對應
-
如果表名後不定義列名,則默認所有列添加值
insert into 表名 values (值1,值2,...值n);
-
除了數字類型,其他類型的值需要引號(單雙都可以)引起來
- 刪除數據:
如果沒有條件,刪除表中所有記錄
delete from 表名[where 條件];
刪除表,再創建一個一模一樣的空表
truncate table 表名;
- 修改數據
update 表名 set 列名1 = 值1,列名2 = 值2,...[where 條件]
實例代碼
UPDATE class_1 SET English = 78 WHERE age = 18; -- 將age = 18的學生English改爲78
DQL
作用:查詢表中的記錄
查詢表中所有記錄
select * from 表名
語法
select 字段列表
from 表名列表
where 條件列表
group by 分組字段
having 分組之後的條件
order by 排序
limit 分頁限定
基礎查詢
去除重複的結果集
select distinct 列名 from 表名;
計算幾列之和
select 列名1,列名2,列名1+列名2 from 表名;
改進:如果有null參與運算,計算結果都爲null
select 列名1,列名2 列名1+ifnull(列名2,0)from 表名;
改進:起別名as(as 可替換成 空格)
select 列名1,列名2 列名1+ifnull(列名2,0) as 別名 from 表名;
select 列名1 新列名1,列名2 新列名2 from 表名;
實例代碼
SELECT English,Math,Chinese,(Math+Chinese+English) 總分 FROM class_1; -- 計算總分
條件查詢
語法:where 字句後跟條件
條件運算符
- 比較運算符
- 等於=
- 大於>
- 大於或等於>=
- 小於<
- 小於或等於<=
- 不等於!=或<>
- 邏輯運算符
- and或&&
- or或||
- not或!
- 模糊查詢 like
- 佔位符:_(下劃線)表示單個任意字符
- 佔位符:% 表示任意多個字符
- 範圍查詢
- in表示在一個非連續的範圍內 eg:in(1,4,8)
- between…and…表示在一個連續的範圍內 eg:between 1 and 8
- 空判斷
- 判空 is null 或 is not null
實例代碼
-- 查詢一班name第二個字是a的記錄
SELECT * FROM class_1 WHERE class="一班" AND NAME LIKE "_a%";
-- 查詢English範圍在80到100的記錄
SELECT * FROM class_1 WHERE English BETWEEN 80 AND 100;
排序查詢
語法:order by 字句
order by 排序字段1 排序方式1,排序字段2 排序方式2
排序方式:
asc:升序(默認)
desc:降序
注意:如果有多個排序條件,則當前一個的條件值一樣時,纔會判斷第二條件
聚合函數:將一系列數據作爲整體,進行縱向的計算
- count:計算個數
- max:計算最大值
- min:計算最小值
- sum:計算和
- avg:計算平均值
計算有多少行
select count(列名) from 表名
注意:聚合函數的計算,會排除null值(null值不參與計算)
實例代碼
-- 將學生根據name升序
SELECT * FROM class_1 ORDER BY NAME ASC;
-- 計算學生人數
SELECT COUNT(NAME) FROM class_1;
-- 計算Math最大值
SELECT MAX(Math) FROM class_1;
-- 計算Math最小值
SELECT MIN(Math) FROM class_1;
分組查詢
語法:group by 分組字段
注意:分組之後查詢的字段是分組字段,聚合函數
where與having區別:
-
where在分組之前限定,如果不滿足條件,不參與分組
-
having在分組之後限定,如果不滿足條件,不會被查詢出來
-
where後不可以加聚合函數
-
having可以進行聚合函數的判斷
實例代碼
-- 按照年齡分組查詢人數
SELECT age,COUNT(NAME) FROM class_1 GROUP BY age;
分頁查詢
語法:limit 開始索引,每頁查詢的條數
公式:開始索引 = (當前頁碼 - 1)*每頁顯示的頁數
注意:limit是MySQL特有
實例代碼
-- 按照3個記錄爲一頁
SELECT * FROM class_1 LIMIT 0,3;
SELECT * FROM class_1 LIMIT 3,3;
約束
作用:對錶中的數據進行限定,保證數據的正確性、有效性和完整性。
分類:
- 主鍵約束:primary key
- 非空約束:not null
- 唯一約束:unique
- 外鍵約束:foreign key
非空約束
語法:not null
創建表時添加約束
create table 表名(...,列名 數據類型 not null);
刪除非空約束
alter table 表名 modify 列名 數據類型;
創建表後,添加非空約束
alter table 表名 modify 列名 數據類型;
唯一約束
語法:unique
創建表時添加約束
create table 表名(...,列名 數據類型 unique);
刪除唯一約束
alter table 表名 drop index 列名;
創建表後,添加唯一約束
alter table 表名 modify 列名 數據類型 unique;
注意:唯一約束可以有null值,但只能有一條null值記錄
主鍵約束
語法:primary key
注意:
- 含義:非空且唯一
- 一張表只能有一個字段爲主鍵
- 主鍵就是表中記錄的唯一標識
創建表時,添加主鍵
create table 表名 (...,列名 數據類型 primary key);
刪除主鍵
alter table 表名 drop primary key;
創建表後,添加主鍵
alter table 表名 modify 列名 數據類型 primary key;
自動增長
概念:如果某一列是數值類型的,使用auto-increment
可以來完成值自動增長
創建表時,添加主鍵並實現自動增長
create table 表名(列名 數值類型 primary key auto-increment);
刪除自動增長
alter table 表名 modify 列名 數據類型;
添加自動增長
alter table 表名 modify 列名 數值類型 auto-increment;
外鍵約束
語法:foreign key
作用:讓表與表之間產生關係,保證數據的正確性。
創建表時,添加外鍵
create table 從表名(...,constraint 外鍵名稱 foreign key(外鍵列名稱) references 主表名稱(主表列名稱));
刪除外鍵
alter table 從表名 drop foreign key 外鍵名稱;
創建表後,添加外鍵
alter table 從表名 add constraint 外鍵名稱 foreign key(外鍵字段名稱)references
主表名稱(主表列名稱);
注意:外鍵名稱可以隨便起,只是標記不會顯式出來,只要不重複就行。
級聯操作
分類:
- 級聯更新: on update cascade
- 級聯刪除:on delete cascade
添加級聯操作
alter table 從表名 add constraint 外鍵名稱 foreign key(外鍵字段名稱) references
主表名稱(主表列名稱)on update cascade on delete cascade;
DCL
作用:管理用戶,授予權限
管理用戶
添加用戶
create user '用戶名'@'主機名' identified by '密碼';
刪除用戶
drop user '用戶名'@'主機名';
修改用戶密碼
update user set password = password('新密碼')where user='用戶名';
或者
set password for '用戶名'@'主機名'=password("新密碼");
查詢用戶
1. 切換到mysql數據庫
use mysql;
2.查詢user表
select * from user;
mysql中忘記了root用戶的密碼怎麼辦?
- 管理員身份打開cmd – >
net stop mysql
停止mysql服務 - 使用無驗證方式啓動mysql:
mysqld --skip-grant-tables
- 打開新的cmd窗口,直接輸入mysql命令,enter,就可以登入成功
- use mysql;
- update user set password = password(‘新密碼’) where user = ‘root’;
- 關閉兩個cmd窗口
- 打開任務管理器,手動結束mysql.exe進程
- 啓動mysql服務,使用新密碼登入
通配符: 主機名寫% : 表示可以在任意主機使用用戶登錄數據庫
權限管理
查詢權限
show grants for '用戶名'@'主機名';
授予權限
grant 權限列表 on 數據庫.表名 to '用戶名'@'主機名';
撤銷權限
revoke 權限列表 on 數據庫.表名 from '用戶名'@'主機名';
數據庫的設計
- 一對一
實現方式:在任意一方添加外鍵指向另一方的主鍵,且外鍵唯一unique
- 一對多
實現方式:在多的一方建立外鍵,指向一的一方
- 多對多
實現方式:藉助第三張中間表
中間表至少包含兩個字段,這兩個字段作爲第三張表的外鍵,分別指向兩張表的主鍵
數據庫的三大範式
第一範式:每個列都不可以再拆分
第二範式:在第一範式基礎上,非主鍵列完全依賴主鍵
第三範式:在第二範式基礎上,非主鍵列直接依賴主鍵,而不依賴於其他鍵
**注意:**在設計數據庫結構時,儘量遵循三大範式,除非有性能顧慮。
數據庫的備份和還原
cmd命令行語法
備份:mysqldump -u用戶名 -p密碼 數據庫名稱 > 保存的路徑
還原:
- 登錄數據庫
- 創建數據庫
- 使用數據庫
- 執行文件: source 文件路徑
多表查詢
語法
select 列名列表
from 表名列表
where 條件
分類:
- 內連接查詢
- 外連接查詢
- 子查詢
笛卡爾積:有兩個集合A,B,取這兩個集合的所有組成情況。
要完成多表查詢,需要消除無用的數據
內連接查詢
-
隱式內連接:使用where條件消除無用數據
-
顯式內連接:
select 字段列表 from 表名1 [inner] join 表名2 on 條件;
內連接查詢:
- 從哪些表中查詢數據
- 條件是什麼
- 查詢那些字段
外連接查詢
- 左外連接
查詢左邊表中所有數據以及其交集部分
select 字段列表 from 表1 left[outer] join 表2 on 條件;
- 右外連接
查詢右邊表所有數據以及其交集部分
select 字段列表 from 表1 right[outer] join 表2 on 條件;
子查詢
概念:查詢中嵌套查詢,稱嵌套查詢爲子查詢
子查詢的3種不同情況:
- 子查詢的結果單行單列的
子查詢作爲條件,使用運算符去判斷
- 子查詢的結果是多行單列的
子查詢可以作爲條件,使用運算符in判斷
- 子查詢的結果是多行多列的
子查詢作爲一張虛擬表
事務
事務的基本介紹
概念:如果一個包含多個步驟的業務操作,被事務管理,那麼這些操作要麼同時成功,要麼同時失敗。
操作的關鍵字:
- 開啓事務:start transaction
- 回滾:rollback
- 提交:commit
MySQL數據庫中,事務默認自動提交
一條DML(增刪改)語句會自動提交一次事務
事務提交的兩種方式:
- 自動提交
- 手動提交
查看事務的默認提交方式
select @@autocommit;
修改事務的提交方式
-- 參數 1:自動提交 0:手動提交
set @@autocommit = 參數;
事務的四大特徵
- 原子性:是不可分割的最小操作單位,要麼同時成功,要麼同時失敗
- 持久性:當事務提交或回滾後,數據庫會持久化的保存數據
- 隔離性:多個事務之間相互獨立
- 一致性:事務操作前後,數據總量不變
事務的隔離級別
概念:多個事務之間隔離的,相互獨立的。但是如果多個事務操作同一批數據,則會引發一些問題,設置不同的隔離級別既可以解決這些問題。
存在問題:
- 髒讀:一個事務,讀取到另一個事務沒有提交的數據
- 不可重複讀(虛讀):同一事務,兩次讀到的數據不一樣
- 幻讀:一個事務操作數據表中的所有數據,另一事務添加了一條數據,則第一個事務查詢不到添加的數據
隔離級別:
- read uncommitted : 讀未提交
產生的問題:髒讀、不可重複讀、幻讀
- read committed:讀已提交(Oracle默認)
產生的問題:不可重複讀、幻讀
- read repeaded:可重複度(MySQL默認)
產生的問題:幻讀
- serializable:串行化
可以解決所有問題
注意:隔離級別從小到大安全性越來越高,但是效率越來越低
查詢數據庫隔離級別
select @@ts_isolation;
設置數據庫隔離級別
set global transaction isolation level 級別字符串;