SQL基本语句及用法
目錄
一.基本SQL語句用法及概述
1.常用MySQL命令
2.語法規范
3.SQL語句分類
二.數據查詢語言
1.基礎查詢
1)查詢的字段列表可以是字段、常量、表達式、函數等
2)使用別名,字段名和別名之間可以用空格或關鍵字AS與as指定別名
3)去重??? distinct
4)使用concat函數進行字符串拼接
2.條件查詢
1)件運算符
2)邏輯運算符
3.模糊查詢
4.排序??? order by
三.數據查詢語言之函數應用
1.常用函數分類
1)按使用方式分為:
2)按用途分為
2.函數應用
1)字符函數實例:
2)日期和時間函數實例
3)分組函數
四.數據查詢語言之分組查詢
1.分組查詢的概述
五.數據查詢語言之連接查詢
1.連接查詢的概述
2.連接分類
3.SQL99標準多表查詢
1)內連接
2)等值連接
3)非等值連接 between
4)自連接
5)外連接的概述
6)左外連接
7)右外連接
8)交叉連接 cross join
六.數據查詢語言之子查詢
1.子查詢的概述
2.子查詢實例
1)單行單列
2)多行單列
3)單行多列
4)多行多列
5)分頁查詢
6)聯合查詢UNION
七.插入語句DDL
1.不指定列名的插入
2.指定列名的插入
3.使用set語句
4.修改語句
5.刪除記錄
6.刪除多表記錄
7.清空表
八.數據庫管理
1.創建數據庫
2.修改數據庫
3.刪除數據庫
九.表管理
1.關系數據庫的規范化
2.表管理語句
3.常用數據類型
4.示例:
1)修改表
2)修改列的類型或約束
3)添加新列
4)刪除列
5)修改表名
6)刪除表
7)表復制
8)復制表結構及數據
十.約束
1.約束分類
2.約束應用
1)列級應用
2)表級約束
3)刪除約束
十一.事務控制語言DCL
1.事務
2.事務必須滿足的4個條件
3.事務控制語句
4.MySQL事物處理的方法
5.事務的創建
1)隱式事務
7.事務示例
十二.事務隔離
1.事務隔離要解決的問題
2.事務隔離級別
3.設置事務隔離級別
1)查看當前事務隔離級別
2)設置隔離事務級別
3)測試
4.SAVEPOINT應用
1)基本用法
2)SAVEPOINT示例
一.基本SQL語句用法及概述
1.常用MySQL命令
# 查看所有數據庫 SHOW DATABASES; # 切換指定數據庫 USE nsd2021; # 查看當前庫中所有的表 SHOW TABLES; # 查看表結構 DESC departments; # 查看當前所處的數據庫 SELECT DATABASE(); # 查看當前登陸用戶 SELECT USER(); # 查看版本 SELECT VERSION(); [root@mysql1 ~]# mysql --version #不進庫查看 [root@mysql1 ~]# mysql -V2.語法規范
關鍵字不區分大小寫,但建議關鍵字大寫
表名、列名建議小寫
每條命令最好用分號結尾,當然,你用`\G結尾也可以
每條命令根據需要,可以進行縮進或換行(最好是關鍵字單獨占一行),如:
mysql> SELECT-> name, email-> FROM-> employees;注釋
????????單行注釋
mysql> # select * from departments mysql> -- select * from departments????????多行注釋
mysql> /*/*> SELECT/*> */*> FROM/*> departments;/*> */3.SQL語句分類
數據查詢語言(Data Query Language, )DQL
負責進行數據查詢而不會對數據本身進行修改的語句,這是最基本的SQL語句。
數據定義語言 (Data Definition Language,)DDL
負責數據結構定義與數據庫對象定義的語言,由CREATE、ALTER與DROP三個語法所組成
數據操縱語言(Data Manipulation Language,)DML
負責對數據庫對象運行數據訪問工作的指令集,以INSERT、UPDATE、DELETE三種指令為核心,分別代表插入、更新與刪除。
數據控制語言 (Data Control Language)
它可以控制特定用戶賬戶對數據表、查看表、預存程序、用戶自定義函數等數據庫對象的控制權。由 GRANT 和 REVOKE 兩個指令組成。
二.數據查詢語言
1.基礎查詢
SELECT 查詢的字段列表 FROM 表;
1)查詢的字段列表可以是字段、常量、表達式、函數等
# 查單個字段 select dept_name from departments; # 查多個字段 select name, email from employees; # 查所有字段 select * from departments; # 使用表達式 select date, employee_id, basic+bonus from salary; # 查詢常量 select 100; # 查詢表達式 select 10+5; # 查詢函數 select version(); # 查詢函數,統計salary共有多少行記錄 select count(*) from salary;2)使用別名,字段名和別名之間可以用空格或關鍵字AS與as指定別名
mysql> select dept_id 部門編號, dept_name AS 部門名 from departments;3)去重??? distinct
select dept_id from employees; select distinct dept_id from employees;4)使用concat函數進行字符串拼接
select concat(name, '-', phone_number) from employees;2.條件查詢
SELECT 查詢的字段列表 FROM 表 WHERE 條件;
1)件運算符
>: 大于
<: 小于
=: 等于
>=: 大于等于
<=: 小于等于
!=: 不等于
select * from departments where dept_id>3; select * from departments where dept_id<3; select * from departments where dept_id=3; select * from departments where dept_id!=3; select * from departments where dept_id>=3; select * from departments where dept_id<=3;2)邏輯運算符
and(&&)、or(||)、not(!)
select * from departments where dept_id>1 and dept_id<5;
select * from departments where dept_id<3 or dept_id>6;
select * from departments where not dept_id<=6;
3.模糊查詢
- like: 包含
- between xxx and yyy :??????? 在xxx和yyy之間的
- in:在列表中的
- is null:為空,相當于python的None
- is not null:非空
%匹配0到多個任意字符
?_匹配一個字符
# %匹配0到多個任意字符 select name, email from employees where name like '張%'; # _匹配一個字符 select name, email from employees where name like '張_'; select * from departments where dept_id between 3 and 5; select * from departments where dept_id in (1, 3, 5, 8); # 匹配部門名為空的記錄 select * from departments where dept_name is null; # 查詢部門名不為空的記錄 select * from departments where dept_name is not null;4.排序??? order by
SELECT 查詢的字段列表 FROM 表 ORDER BY 排序列表 [asc|desc];
排序:默認升序
select name, birth_date from employees where birth_date>'19980101'; # 默認升序排列 select name, birth_date from employees where birth_date>'19980101' order by birth_date; # 降序排列 select name, birth_date from employees where birth_date>'19980101' order by birth_date desc;三.數據查詢語言之函數應用
1.常用函數分類
1)按使用方式分為:
-
單行函數
-
分組函數
2)按用途分為
-
字符函數
-
數學函數
-
日期函數
-
流程控制函數
SELECT 函數(參數) FROM 表;
2.函數應用
1)字符函數實例:
-
LENGTH(str):返字符串長度,以(字節)為單位
-
CHAR_LENGTH(str): 返回字符串長度,以(字符)為單位
-
CONCAT(s1,s2,...): 返回連接參數產生的字符串,一個或多個待拼接的內容,任意一個為NULL則返回值為NULL
-
UPPER(str)和UCASE(str): 將字符串中的字母全部轉換成大寫
-
LOWER(str)和LCASE(str):將str中的字母全部轉換成小寫
-
SUBSTR(s, start, length): 從子符串s的start位置開始,取出length長度的子串,位置(從1)開始計算
-
INSTR(str,str1):返回str1參數,在str參數內的位置
-
TRIM(s): 返回字符串(s刪除了兩邊空格之后的字符串)
數學函數實例
-
ABS(x):返回x的絕對值
-
PI(): 返回圓周率π,默認顯示6位小數
-
MOD(x,y): 返回x被y除后的余數
-
CEIL(x)、CEILING(x): 返回不小于x的最小整數
-
FLOOR(x): 返回不大于x的最大整數
-
ROUND(x)、ROUND(x,y): 前者返回最接近于x的整數,即對x進行四舍五入;后者返回最接近x的數,其值保留到小數點后面y位,若y為負值,則將保留到x到小數點左邊y位
2)日期和時間函數實例
-
CURDATE()、CURRENT_DATE(): 將當前日期按照"YYYY-MM-DD"或者"YYYYMMDD"格式的值返回,具體格式根據函數用在字符串或是數字語境中而定
-
NOW(): 返回當前日期和時間值,格式為"YYYY_MM-DD HH:MM:SS"或"YYYYMMDDHHMMSS",具體格式根據函數用在字符串或數字語境中而定
-
UNIX_TIMESTAMP()、UNIX_TIMESTAMP(date): 前者返回一個格林尼治標準時間1970-01-01 00:00:00到現在的秒數,后者返回一個格林尼治標準時間1970-01-01 00:00:00到指定時間的秒數
-
FROM_UNIXTIME(date): 和UNIX_TIMESTAMP互為反函數,把UNIX時間戳轉換為普通格式的時間
-
MONTH(date)和MONTHNAME(date):前者返回指定日期中的月份,后者返回指定日期中的月份的名稱
-
DAYNAME(d)、DAYOFWEEK(d)、WEEKDAY(d): DAYNAME(d)返回d對應的工作日的英文名稱,如Sunday、Monday等;DAYOFWEEK(d)返回的對應一周中的索引,1表示周日、2表示周一;WEEKDAY(d)表示d對應的工作日索引,0表示周一,1表示周二
-
WEEK(d): 計算日期d是一年中的第幾周
-
DAYOFYEAR(d)、DAYOFMONTH(d): 前者返回d是一年中的第幾天,后者返回d是一月中的第幾天
-
YEAR(date)、QUARTER(date)、MINUTE(time)、SECOND(time): YEAR(date)返回指定日期對應的年份,范圍是1970到2069;QUARTER(date)返回date對應一年中的季度,范圍是1到4;MINUTE(time)返回time對應的分鐘數,范圍是0~59;SECOND(time)返回制定時間的秒值
流程控制函數實例
-
IF(expr,v1,v2): 如果expr是TRUE則返回v1,否則返回v2
-
IFNULL(v1,v2): 如果v1不為NULL,則返回v1,否則返回v2
-
CASE expr (WHEN v1)( THEN r1) [WHEN v2 THEN v2] [ELSE rn] END: 如果expr等于某個vn,則返回對應位置THEN后面的結果,如果與所有值都不想等,則返回ELSE后面的rn
3)分組函數
用于統計,又稱為聚合函數或統計函數
-
sum() :求和
-
avg() :求平均值
-
max() :求最大值
-
min() :求最小值
-
count() :計算個數
四.數據查詢語言之分組查詢
1.分組查詢的概述
-
在對數據表中數據進行統計時,可能需要按照一定的類別分別進行統計。比如查詢每個部門的員工數。
-
使用GROUP BY按某個字段,或者多個字段中的值,進行分組,字段中值相同的為一組
語法格式
-
查詢列表必須是分組函數和出現在(GROUP BY)后面的字段
-
通常而言,分組前的數據篩選放在where子句中,分組后的數據篩選放在having子句中
應用實例
-
查詢每個部門的人數
-
查詢每個部門中年齡最大的員工
-
查詢每個部門入職最晚員工的入職時間
-
統計各部門使用tedu.cn郵箱的員工人數
-
查看員工2018年工資總收入,按總收入進行降序排列
-
查詢部門人數少于10人
五.數據查詢語言之連接查詢
1.連接查詢的概述
-
也叫多表查詢。常用于查詢字段來自于多張表
-
如果直接查詢兩張表,將會得到笛卡爾積
-
通過添加有效的條件可以進行查詢結果的限定
2.連接分類
按功能分類
-
內連接(重要)
-
等值連接
-
非等值連接
-
自連接
-
-
外連接
-
左外連接(重要)
-
右外連接(重要)
-
全外連接(mysql不支持,可以使用UNION實現相同的效果)
-
-
交叉連接
按年代分類
-
SQL92標準:僅支持內連接
-
SQL99標準:支持所有功能的連接
3.SQL99標準多表查詢
-
語法格式
1)內連接
-
語法格式
2)等值連接
-
查詢每個員工所在的部門名
-
查詢每個員工所在的部門名,使用別名
-
查詢每個員工所在的部門名,使用別名。兩個表中的同名字段,必須指定表名
-
查詢11號員工的名字及2018年每個月工資
-
查詢2018年每個員工的總工資
-
查詢2018年每個員工的總工資,按工資升序排列
-
查詢2018年總工資大于30萬的員工,按工資降序排列
3)非等值連接 between
附:創建工資級別表
創建表語法:
CREATE TABLE 表名稱 ( 列名稱1 數據類型, 列名稱2 數據類型, 列名稱3 數據類型, .... )創建工資級別表:
-
id:主鍵。僅作為表的行號
-
grade:工資級別,共ABCDE五類
-
low:該級別最低工資
-
high:該級別最高工資
向表中插入數據:
-
語法:
-
向wage_grade表中插入五行數據:
-
查詢2018年12月員工基本工資級別
-
查詢2018年12月員工各基本工資級別的人數
-
查詢2018年12月員工基本工資級別,員工需要顯示姓名
4)自連接
-
要點:
-
將一張表作為兩張使用
-
每張表起一個別名
-
-
查看哪些員的生日月份與入職月份相同
5)外連接的概述
-
常用于查詢一個表中有,另一個表中沒有的記錄
-
如果從表中有和它匹配的,則顯示匹配的值
-
如要從表中沒有和它匹配的,則顯示NULL
-
外連接查詢結果=內連接查詢結果+主表中有而從表中沒有的記錄
-
左外連接中,left join左邊的是主表left outer join
-
右外連接中,right join右邊的是主表right outer join
-
左外連接和右外連接可互換,實現相同的目標
6)左外連接
-
語法
-
查詢所有部門的人員以及沒有員工的部門
7)右外連接
-
語法
-
查詢所有部門的人員以及沒有員工的部門
8)交叉連接 cross join
-
返回笛卡爾積
-
語法:
-
查詢員工表和部門表的笛卡爾積
附:授予管理員root可以通過任意地址訪問數據庫,密碼是NSD2021@tedu.cn。默認情況下,root只允許在本機訪問
grant all on *.* to root@'%' identified by 'NSD2021@tedu.cn';向部門表中插入數據:
insert into departments(dept_name) values('采購部');
六.數據查詢語言之子查詢
1.子查詢的概述
子查詢就是指的在一個完整的查詢語句之中,嵌套若干個不同功能的小查詢,從而一起完成復雜查詢的一種編寫形式
子查詢返回的數據分類
????????單行單列:返回的是一個具體列的內容,可以理解為一個單值數據
????????單行多列:返回一行數據中多個列的內容
????????多行單列:返回多行記錄之中同一列的內容,相當于給出了一個操作范圍
????????多行多列:查詢返回的結果是一張臨時表
子查詢常出現的位置
????????select之后:僅支持單行單列????????
????????from之后:支持多行多列
????????where或having之后:支持單行單列、單行多列、多行單列
2.子查詢實例
1)單行單列
查詢運維部所有員工信息
分析:
????????首先從departments表中查出運維部的編號
查詢2018年12月所有比100號員工基本工資高的工資信息
分析:
首先查到2018年12月100號員工的基本工資
mysql> select basic from salary-> where year(date)=2018 and month(date)=12 and employee_id=100; +-------+ | basic | +-------+ | 14585 | +-------+ 1 row in set (0.00 sec) 再查詢2018年12月所有比100號員工基本工資高的工資信息mysql> select * from salary-> where year(date)=2018 and month(date)=12 and basic>(-> select basic from salary-> where year(date)=2018 and month(date)=12 and employee_id=100-> );查詢部門員工人數比開發部人數少的部門
分析:
查詢開發部部門編號
mysql> select dept_id from departments where dept_name='開發部'; +---------+ | dept_id | +---------+ | 4 | +---------+ 1 row in set (0.00 sec) 查詢開發部人數mysql> select count(*) from employees-> where dept_id=(-> select dept_id from departments where dept_name='開發部'-> ); +----------+ | count(*) | +----------+ | 55 | +----------+ 1 row in set (0.00 sec)分組查詢各部門人數
mysql> select count(*), dept_id from employees group by dept_id; +----------+---------+ | count(*) | dept_id | +----------+---------+ | 8 | 1 | | 5 | 2 | | 6 | 3 | | 55 | 4 | | 12 | 5 | | 9 | 6 | | 35 | 7 | | 3 | 8 | +----------+---------+ 8 rows in set (0.01 sec)?查詢部門員工人數比開發部人數少的部門
mysql> select count(*), dept_id from employees group by dept_id-> having count(*)<(-> select count(*) from employees-> where dept_id=(-> select dept_id from departments where dept_name='開發部'-> )-> ); +----------+---------+ | count(*) | dept_id | +----------+---------+ | 8 | 1 | | 5 | 2 | | 6 | 3 | | 12 | 5 | | 9 | 6 | | 35 | 7 | | 3 | 8 | +----------+---------+ 7 rows in set (0.00 sec)查詢每個部門的人數
分析:
查詢所有部門的信息
mysql> select d.* from departments as d; +---------+-----------+ | dept_id | dept_name | +---------+-----------+ | 1 | 人事部 | | 2 | 財務部 | | 3 | 運維部 | | 4 | 開發部 | | 5 | 測試部 | | 6 | 市場部 | | 7 | 銷售部 | | 8 | 法務部 | | 9 | NULL | +---------+-----------+ 9 rows in set (0.00 sec)查詢每個部門的人數
mysql> select d.*, (-> select count(*) from employees as e-> where d.dept_id=e.dept_id-> ) as amount-> from departments as d; +---------+-----------+--------+ | dept_id | dept_name | amount | +---------+-----------+--------+ | 1 | 人事部 | 8 | | 2 | 財務部 | 5 | | 3 | 運維部 | 6 | | 4 | 開發部 | 55 | | 5 | 測試部 | 12 | | 6 | 市場部 | 9 | | 7 | 銷售部 | 35 | | 8 | 法務部 | 3 | | 9 | NULL | 0 | +---------+-----------+--------+ 9 rows in set (0.00 sec)2)多行單列
查詢人事部和財務部員工信息
分析:
查詢人事部和財務部編號
mysql> select dept_id from departments-> where dept_name in ('人事部', '財務部'); +---------+ | dept_id | +---------+ | 1 | | 2 | +---------+ 2 rows in set (0.00 sec) 查詢部門編號是兩個部門編號的員工信息mysql> select * from employees-> where dept_id in (-> select dept_id from departments-> where dept_name in ('人事部', '財務部')-> );查詢人事部2018年12月所有員工工資
分析:
查詢人事部部門編號
mysql> select dept_id from departments where dept_name='人事部'; +---------+ | dept_id | +---------+ | 1 | +---------+ 1 row in set (0.00 sec) 查詢人事部員的編號mysql> select employee_id from employees-> where dept_id=(-> select dept_id from departments where dept_name='人事部'-> ); +-------------+ | employee_id | +-------------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | +-------------+ 8 rows in set (0.00 sec)查詢2018年12月人事部所有員工工資
mysql> select * from salary-> where year(date)=2018 and month(date)=12 and employee_id in (-> select employee_id from employees-> where dept_id=(-> select dept_id from departments where dept_name='人事部'-> )-> ); +------+------------+-------------+-------+-------+ | id | date | employee_id | basic | bonus | +------+------------+-------------+-------+-------+ | 6252 | 2018-12-10 | 1 | 17016 | 7000 | | 6253 | 2018-12-10 | 2 | 20662 | 9000 | | 6254 | 2018-12-10 | 3 | 9724 | 8000 | | 6255 | 2018-12-10 | 4 | 17016 | 2000 | | 6256 | 2018-12-10 | 5 | 17016 | 3000 | | 6257 | 2018-12-10 | 6 | 17016 | 1000 | | 6258 | 2018-12-10 | 7 | 23093 | 4000 | | 6259 | 2018-12-10 | 8 | 23093 | 2000 | +------+------------+-------------+-------+-------+ 8 rows in set (0.00 sec)3)單行多列
查找2018年12月基本工資和獎金都是最高的工資信息
分析:
查詢2018年12月最高的基本工資
mysql> select max(basic) from salary-> where year(date)=2018 and month(date)=12; +------------+ | max(basic) | +------------+ | 25524 | +------------+ 1 row in set (0.00 sec) 查詢2018年12月最高的獎金mysql> select max(bonus) from salary-> where year(date)=2018 and month(date)=12; +------------+ | max(bonus) | +------------+ | 11000 | +------------+ 1 row in set (0.00 sec) 查詢mysql> select * from salary-> where year(date)=2018 and month(date)=12 and basic=(-> select max(basic) from salary-> where year(date)=2018 and month(date)=12-> ) and bonus=(-> select max(bonus) from salary-> where year(date)=2018 and month(date)=12-> ); +------+------------+-------------+-------+-------+ | id | date | employee_id | basic | bonus | +------+------------+-------------+-------+-------+ | 6368 | 2018-12-10 | 117 | 25524 | 11000 | +------+------------+-------------+-------+-------+ 1 row in set (0.01 sec)4)多行多列
查詢3號部門及其部門內員工的編號、名字和email
分析
查詢3號部門和員工的所有信息
mysql> select d.dept_name, e.*-> from departments as d-> inner join employees as e-> on d.dept_id=e.dept_id; 將上述結果當成一張臨時表,必須為其起別名。再從該臨時表中查詢mysql> select dept_id, dept_name, employee_id, name, email-> from (-> select d.dept_name, e.*-> from departments as d-> inner join employees as e-> on d.dept_id=e.dept_id-> ) as tmp_table-> where dept_id=3; +---------+-----------+-------------+-----------+--------------------+ | dept_id | dept_name | employee_id | name | email | +---------+-----------+-------------+-----------+--------------------+ | 3 | 運維部 | 14 | 廖娜 | liaona@tarena.com | | 3 | 運維部 | 15 | 竇紅梅 | douhongmei@tedu.cn | | 3 | 運維部 | 16 | 聶想 | niexiang@tedu.cn | | 3 | 運維部 | 17 | 陳陽 | chenyang@tedu.cn | | 3 | 運維部 | 18 | 戴璐 | dailu@tedu.cn | | 3 | 運維部 | 19 | 陳斌 | chenbin@tarena.com | +---------+-----------+-------------+-----------+--------------------+ 6 rows in set (0.00 sec)5)分頁查詢
使用SELECT查詢時,如果結果集數據量很大,比如幾萬行數據,放在一個頁面顯示的話數據量太大,不如分頁顯示,每次顯示100條
要實現分頁功能,實際上就是從結果集中顯示第1至100條記錄作為第1頁,顯示第101至200條記錄作為第2頁,以此類推
分頁實際上就是從結果集中“截取”出從M開始,偏移到N的記錄。這個查詢可以通過LIMIT <M>, <N>子句實現
起始索引從0開始
每頁顯示內容速算:LIMIT (PAGE-1)*SIZE, SIZE
示例:
# 按employee_id排序,取出前5位員姓名
?
# 按employee_id排序,取出前15至20號員姓名
6)聯合查詢UNION
作用:將多條select語句的結果,合并到一起,稱之為聯合操作。
語法:( ) UNION ( )
要求查詢時,多個select語句的檢索到的字段數量必須一致
每一條記錄的各字段類型和順序最好是一致的
UNION關鍵字默認去重,可以使用UNION ALL包含重復項
mysql> (select 'yes') union (select 'yes'); +-----+ | yes | +-----+ | yes | +-----+ 1 row in set (0.00 sec)mysql> (select 'yes') union all (select 'yes'); +-----+ | yes | +-----+ | yes | | yes | +-----+ 2 rows in set (0.00 sec)
例,某生產商有一張原材料表和一張商品表,需要把原材料價格和商品價格一起輸出
查詢1972年前或2000年后出生的員工
# 普通方法
?
# 聯合查詢的方法
?
七.插入語句DDL
1.不指定列名的插入
語法格式:
????????INSERT INTO 表名稱 VALUES (值1, 值2,....)
需要為所有列指定值
值的順序必須與表中列的順序一致
示例:# 如果表中已有1號部門,則出錯。因為dept_id是主鍵,不允許重復
mysql> insert into departments values(1, '行政部'); ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'# mysql> insert into departments values(10, '行政部'); Query OK, 1 row affected (0.01 sec)?支持多行插入
mysql> insert into employees values-> (134, '張三', '2019-5-10', '2000-10-12', 'zhangsan@tedu.cn', '15088772354', 9),-> (135, '李四', '2020-8-20', '1999-6-23', 'lisi@tedu.cn', '13323458734', 9); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 02.指定列名的插入
語法格式:
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
列和值的順序要一致
列名先后順序不重要
示例 :
mysql> insert into departments (dept_name, dept_id) values ('售后部', 11); Query OK, 1 row affected (0.00 sec) 主鍵由于是自動增長的,也可以不指定主鍵的值mysql> insert into departments (dept_name) values ('咨詢部'); Query OK, 1 row affected (0.00 sec)
支持子查詢
3.使用set語句
語法格式:
INSERT INTO 表名 SET 列名1=列值1, 列名2=列值2, ...
示例:
4.修改語句
修改單表記錄
語法:
UPDATE 表名稱 SET 列名稱=新值, 列名稱=新值, ... WHERE 篩選條件
示例:
# 修改人事部的名稱為人力資源部
mysql> update departments set dept_name='人力資源部'-> where dept_name='人事部'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0修改多表記錄
語法:
示例:
# 修改李四所在部門為企劃部
mysql> update departments as d-> inner join employees as e-> on d.dept_id=e.dept_id-> set d.dept_name='企劃部'-> where e.name='李四';5.刪除記錄
刪除單表記錄
語法:
刪除的是滿足條件的整行記錄,而不是某個字段
示例:
# 刪除重復的員工張三,只保留一個張三的信息
# 查詢張三信息
# 根據員工編號刪除重復的張三
mysql> delete from employees where employee_id=136; Query OK, 1 row affected (0.00 sec)6.刪除多表記錄
語法:
DELETE 表1別名, 表2別名 FROM 表1 AS 表1別名 INNER | LEFT | RIGHT JOIN 表2 AS 表2別名 ON 連接條件 WHERE 篩選條件示例:
# 刪除9號部門中所有的員工
mysql> delete e-> from employees as e-> inner join departments as d-> on e.dept_id=d.dept_id-> where d.dept_id=9; Query OK, 2 rows affected (0.00 sec)7.清空表
語法:
TRUNCATE TABLE 表名 TRUNCATE不支持WHERE條件自增長列,TRUNCATE后從1開始;DELETE繼續編號
TRUNCATE不能回滾,DELETE可以
效率略高于DELETE
示例:
# 清空wage_grade表 mysql> truncate table wage_grade; Query OK, 0 rows affected (0.01 sec)八.數據庫管理
1.創建數據庫
-
語法:
-
[ ]中的內容是可選的
-
<數據庫名>:創建數據庫的名稱。MySQL 的數據存儲區將以目錄方式表示 MySQL 數據庫,因此數據庫名稱必須符合操作系統的文件夾命名規則,不能以數字開頭,盡量要有實際意義。
-
IF NOT EXISTS:在創建數據庫之前進行判斷,只有該數據庫目前尚不存在時才能執行操作。此選項可以用來避免數據庫已經存在而重復創建的錯誤。
-
[DEFAULT] CHARACTER SET:指定數據庫的字符集。指定字符集的目的是為了避免在數據庫中存儲的數據出現亂碼的情況。如果在創建數據庫時不指定字符集,那么就使用系統的默認字符集。
-
[DEFAULT] COLLATE:指定字符集的默認校對規則。
-
MySQL 的字符集(CHARACTER)和校對規則(COLLATION)是兩個不同的概念。字符集是用來定義 MySQL 存儲字符串的方式,校對規則定義了比較字符串的方式。
2.修改數據庫
-
語法:
-
ALTER DATABASE 用于更改數據庫的全局特性。
-
使用 ALTER DATABASE 需要獲得數據庫 ALTER 權限。
-
數據庫名稱可以忽略,此時語句對應于默認數據庫。
-
CHARACTER SET 子句用于更改默認的數據庫字符集。
3.刪除數據庫
-
語法:
-
<數據庫名>:指定要刪除的數據庫名。
-
IF EXISTS:用于防止當數據庫不存在時發生錯誤。
-
DROP DATABASE:刪除數據庫中的所有表格并同時刪除數據庫。
-
如果要使用 DROP DATABASE,需要獲得數據庫 DROP 權限。
九.表管理
1.關系數據庫的規范化
良好的數據庫設計表現在以下幾方面:
-
訪問效率高
-
減少數據冗余,節省存儲空間,便于進一步擴展
-
可以使應用程序的開發變得更容易
關系數據庫的規范化理論為:關系數據庫中的每一個關系都要滿足一定的規范。根據滿足規范的條件不同,可以分為6個等級:第一范式(1NF)、第二范式(2NF)……第五范式(5NF)。其中,NF是Normal Form的縮寫。一般情況下,只要把數據規范到第三范式標準就可以滿足需要了。
第一范式(1NF)
-
在一個關系中,消除重復字段,且各字段都是最小的邏輯存儲單位。即,要滿足原子性。
-
第一范式是第二和第三范式的基礎,是最基本的范式。第一范式包括下列指導原則。 (1)數據組的每個屬性只可以包含一個值。 (2)關系中的每個數組必須包含相同數量的值。 (3)關系中的每個數組一定不能相同。
-
在任何一個關系數據庫中,第一范式是對關系模式的基本要求,不滿足第一范式的數據庫就不是關系型數據庫。
第二范式(2NF)
-
第二范式是在第一范式的基礎上建立起來的,即滿足第二范式必先滿足第一范式(1NF)。
-
第二范式要求數據庫表中的每個實體(即各個記錄行)必須可以被唯一地區分。
-
為實現區分各行記錄通常需要為表設置一個“區分列”,用以存儲各個實體的唯一標識。這個唯一屬性列被稱為主關鍵字或主鍵。
-
第二范式要求實體的屬性完完全依賴于主關鍵字,即不能存在僅依賴主關鍵字一部分的屬性,如果存在,那么這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關系。
第三范式(3NF)
-
第三范式是在第二范式的基礎上建立起來的,即滿足第三范式必先滿足第二范式。
-
第三范式要求關系表不存在非關鍵字列對任意候選關鍵字列的傳遞函數依賴,也就是說,第三范式要求一個關系表中不包含已在其他表中包含的非主關鍵字信息。
-
除主鍵外,其他字段必須依賴主鍵。
2.表管理語句
創建表
-
語法:
3.常用數據類型
| tinyint(m) | 1個字節 范圍(-128~127) |
| smallint(m) | 2個字節 范圍(-32768~32767) |
| mediumint(m) | 3個字節 范圍(-8388608~8388607) |
| int(m) | 4個字節 范圍(-2147483648~2147483647) |
| bigint(m) | 8個字節 范圍(+-9.22*10的18次方) |
| float(m,d) | 單精度浮點型 8位精度(4字節) m總個數,d小數位 |
| double(m,d) | 雙精度浮點型 16位精度(8字節) m總個數,d小數位 |
| decimal(m,d) | m表示十進制數字總的個數,d表示小數點后面數字的位數。常用于貨幣 |
| char(n) | 固定長度,最多255個字符 |
| varchar(n) | 不固定長度,最多65535個字符 |
| tinytext | 可變長度,最多255個字符 |
| text | 可變長度,最多65535個字符 |
| mediumtext | 可變長度,最多2的24次方-1個字符 |
| longtext | 可變長度,最多2的32次方-1個字符 |
| date | 日期 '2008-12-2' |
| time | 時間 '12:25:36' |
| datetime | 日期時間 '2008-12-2 22:06:44' |
| timestamp | 自動存儲記錄修改時間 |
| enum(選項1, 選項2, ...) | 單選字符串數據類型,適合存儲表單界面中的“單選值” |
| set(選項1,選項2, ...) | 多選字符串數據類型,適合存儲表單界面的“多選值”。 |
4.示例:
# 創建數據庫mydb mysql> create database mydb default charset utf8mb4; Query OK, 1 row affected (0.00 sec) ? mysql> use mydb; Database changed # 創建部門表 mysql> create table departments (-> id int,-> dept_name varchar(20)-> ); Query OK, 0 rows affected (0.01 sec)1)修改表
修改列名
-
語法:
-
示例:
2)修改列的類型或約束
-
語法:
-
示例:
3)添加新列
-
語法:
-
示例:
4)刪除列
-
語法:
-
示例:
5)修改表名
-
語法:
-
示例:
6)刪除表
-
語法:
-
示例:
7)表復制
僅復制表結構
-
語法:
-
示例:
8)復制表結構及數據
-
語法:
-
示例:
十.約束
-
約束是一種限制,用于限制表中的數據,為了保證表中數據的準確性和可靠性。
-
創建表時可以添加約束
-
修改表時可以添加約束
1.約束分類
-
PRIMARY KEY:主鍵,用于保證該字段的值具有唯一性并且非空。
-
NOT NULL :非空,用于保證該字段的值不能為空。
-
DEFAULT:默認值,用于保證該字段有默認值。
-
UNIQUE:唯一,用于保證該字段的值具有唯一性,可以為空。
-
FOREIGN KEY:外鍵,用于限制兩個表的關系,用于保證該字段的值必須來自于主表的關聯列的值,在從表添加外鍵約束,用于引用主表中某些的值。
約束可應用在列級或表級。列表所有約束均支持,但外鍵約束沒有效果;表級約束可以支持主鍵、唯一、外鍵約束。
2.約束應用
1)列級應用
-
創建表時使用約束
2)表級約束
-
創建表時使用約束
-
自定義約束名稱
3)刪除約束
-
語法:
-
示例:
例:創建員工數據庫的三張表
# 創建部門表 create table departments(dept_id int AUTO_INCREMENT PRIMARY KEY,dept_name VARCHAR(10) UNIQUE ); # 創建員工表 create table employees(employee_id INT auto_increment primary key,name VARCHAR(10) not null,hire_date DATE,birth_date DATE,email varchar(25) UNIQUE,phone_number varchar(11),dept_id int,FOREIGN KEY(dept_id) references departments(dept_id) ); # 創建工資表 create table salary(id int AUTO_INCREMENT PRIMARY KEY,date DATE,employee_id int,basic int,bonus int,FOREIGN KEY(employee_id) references employees(employee_id) );十一.事務控制語言DCL
1.事務
-
數據庫事務指的是一組數據操作。
-
主要用于處理操作量大,復雜度高的數據。
-
在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。
-
事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要么全部執行,要么全部不執行。
-
事務用來管理 insert,update,delete 語句
2.事務必須滿足的4個條件
-
原子性(Atomicity):一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
-
一致性(Consistency):在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及后續數據庫可以自發性地完成預定的工作。
-
隔離性(Isolation):數據庫允許多個并發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
-
持久性(Durability):事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失。
3.事務控制語句
-
BEGIN 或 START TRANSACTION 顯式地開啟一個事務;
-
COMMIT 也可以使用 COMMIT WORK,不過二者是等價的。COMMIT 會提交事務,并使已對數據庫進行的所有修改成為永久性的;
-
ROLLBACK 也可以使用 ROLLBACK WORK,不過二者是等價的。回滾會結束用戶的事務,并撤銷正在進行的所有未提交的修改;
-
SAVEPOINT identifier,SAVEPOINT 允許在事務中創建一個保存點,一個事務中可以有多個 SAVEPOINT;
-
RELEASE SAVEPOINT identifier 刪除一個事務的保存點,當沒有指定的保存點時,執行該語句會拋出一個異常;
-
ROLLBACK TO identifier 把事務回滾到標記點;
-
SET TRANSACTION 用來設置事務的隔離級別。InnoDB 存儲引擎提供事務的隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。
4.MySQL事物處理的方法
-
用 BEGIN, ROLLBACK, COMMIT來實現
-
BEGIN開始一個事務
-
ROLLBACK事務回滾
-
COMMIT提交事務
-
-
直接用 SET 來改變 MySQL 的自動提交模式
-
SET AUTOCOMMIT=0 禁止自動提交
-
SET AUTOCOMMIT=1*開啟自動提交
-
5.事務的創建
1)隱式事務
-
事務沒有明顯的開啟和結束的標記。如INSERT、UPDATE、DELETE語句。
2)顯式事務
-
事務具有明顯的開啟和結束的標記
-
必須先設置自動提交功能為禁用
6.創建事務步驟
1)開啟事務
set aotocommit=0; start transaction; # 可選編寫事務語句:INSERT、UPDATE、DELETE語句
結束事務
7.事務示例
-
創建銀行表
-
插入數據
-
使用事務:正常提交
-
使用事務:回滾
十二.事務隔離
1.事務隔離要解決的問題
-
臟讀:臟讀指的是讀到了其他事務未提交的數據,未提交意味著這些數據可能會回滾,也就是可能最終不會存到數據庫中,也就是不存在的數據。讀到了并不一定最終存在的數據,這就是臟讀。
-
可重復讀:可重復讀指的是在一個事務內,最開始讀到的數據和事務結束前的任意時刻讀到的同一批數據都是一致的。通常針對數據更新(UPDATE)操作。
-
不可重復讀:對比可重復讀,不可重復讀指的是在同一事務內,不同的時刻讀到的同一批數據可能是不一樣的,可能會受到其他事務的影響,比如其他事務改了這批數據并提交了。通常針對數據更新(UPDATE)操作。
-
幻讀:幻讀是針對數據插入(INSERT)操作來說的。假設事務A對某些行的內容作了更改,但是還未提交,此時事務B插入了與事務A更改前的記錄相同的記錄行,并且在事務A提交之前先提交了,而這時,在事務A中查詢,會發現好像剛剛的更改對于某些數據未起作用,但其實是事務B剛插入進來的,讓用戶感覺很魔幻,感覺出現了幻覺,這就叫幻讀。
2.事務隔離級別
-
讀未提交(READ UNCOMMITTED)
-
讀提交 (READ COMMITTED)
-
可重復讀 (REPEATABLE READ)
-
串行化 (SERIALIZABLE)
從上往下,隔離強度逐漸增強,性能逐漸變差。采用哪種隔離級別要根據系統需求權衡決定,其中,可重復讀是 MySQL 的默認級別。
事務隔離其實就是為了解決上面提到的臟讀、不可重復讀、幻讀這幾個問題。只有串行化的隔離級別解決了全部這 3 個問題,其他的 3 個隔離級別都有缺陷。
| 讀未提交 | 可能 | 可能 | 可能 |
| 讀提交 | 不可能 | 可能 | 可能 |
| 可重復讀 | 不可能 | 不可能 | 可能 |
| 串行化 | 不可能 | 不可能 | 不可能 |
3.設置事務隔離級別
1)查看當前事務隔離級別
mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set (0.00 sec)2)設置隔離事務級別
mysql> set session transaction isolation level read uncommitted; Query OK, 0 rows affected (0.01 sec)mysql> select @@tx_isolation; +------------------+ | @@tx_isolation | +------------------+ | READ-UNCOMMITTED | +------------------+ 1 row in set (0.00 sec)3)測試
# 在第一個終端上執行以下2條語句 mysql> set autocommit=0; mysql> update bank set balance=balance+1000 where name='kali';# 以下3條語句在第二個終端上執行 mysql> set session transaction isolation level read uncommitted; mysql> set autocommit=0; mysql> select * from bank; # 此時kali賬戶上已經增加1000# 回到第一個終端回滾 mysql> rollback;# 在第2個終端上重新查詢 mysql> select * from bank; # 此時kali賬戶上又減少了10004.SAVEPOINT應用
1)基本用法
-
使用mysql中的savepoint保存點來實現事務的部分回滾
-
語法:
-
使用 SAVEPOINT identifier 來創建一個名為identifier的回滾點
-
ROLLBACK TO identifier,回滾到指定名稱的SAVEPOINT,這里是identifier
-
使用 RELEASE SAVEPOINT identifier 來釋放刪除保存點identifier
-
如果當前事務具有相同名稱的保存點,則將刪除舊的保存點并設置一個新的保存點。
-
如果執行START TRANSACTION,COMMIT和ROLLBACK語句,則將刪除當前事務的所有保存點。
2)SAVEPOINT示例
mysql> set autocommit=0; mysql> update bank set balance=balance+1000 where name='kali'; mysql> savepoint aaa; # 創建保存點 mysql> select * from bank; # kali老師賬號已增加1000 mysql> update bank set balance=balance-1000 where name='yao'; mysql> select * from bank; # yao賬號已減少1000 mysql> rollback to aaa; # 回滾到保存點aaa mysql> select * from bank; # kali老師賬號已增加1000,yao賬號未改變 mysql> exit; # 退出 # 再連入之后查詢 mysql> select * from bank; # 因為從未執行過commit。所以查到的結果與執行事務之前查到的結果一樣。總結
以上是生活随笔為你收集整理的SQL基本语句及用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql安装图形化管理界面phpMyA
- 下一篇: Mysql基础运用(视图,变量,存储,流