日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL基本语句及用法

發(fā)布時間:2025/3/21 数据库 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL基本语句及用法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

一.基本SQL語句用法及概述

1.常用MySQL命令

2.語法規(guī)范

3.SQL語句分類

二.數(shù)據(jù)查詢語言

1.基礎(chǔ)查詢

1)查詢的字段列表可以是字段、常量、表達式、函數(shù)等

2)使用別名,字段名和別名之間可以用空格或關(guān)鍵字AS與as指定別名

3)去重??? distinct

4)使用concat函數(shù)進行字符串拼接

2.條件查詢

1)件運算符

2)邏輯運算符

3.模糊查詢

4.排序??? order by

三.數(shù)據(jù)查詢語言之函數(shù)應(yīng)用

1.常用函數(shù)分類

1)按使用方式分為:

2)按用途分為

2.函數(shù)應(yīng)用

1)字符函數(shù)實例:

2)日期和時間函數(shù)實例

3)分組函數(shù)

四.數(shù)據(jù)查詢語言之分組查詢

1.分組查詢的概述

五.數(shù)據(jù)查詢語言之連接查詢

1.連接查詢的概述

2.連接分類

3.SQL99標(biāo)準(zhǔn)多表查詢

1)內(nèi)連接

2)等值連接

3)非等值連接 between

4)自連接

5)外連接的概述

6)左外連接

7)右外連接

8)交叉連接 cross join

六.數(shù)據(jù)查詢語言之子查詢

1.子查詢的概述

2.子查詢實例

1)單行單列

2)多行單列

3)單行多列

4)多行多列

5)分頁查詢

6)聯(lián)合查詢UNION

七.插入語句DDL

1.不指定列名的插入

2.指定列名的插入

3.使用set語句

4.修改語句

5.刪除記錄

6.刪除多表記錄

7.清空表

八.數(shù)據(jù)庫管理

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

2.修改數(shù)據(jù)庫

3.刪除數(shù)據(jù)庫

九.表管理

1.關(guān)系數(shù)據(jù)庫的規(guī)范化

2.表管理語句

3.常用數(shù)據(jù)類型

4.示例:

1)修改表

2)修改列的類型或約束

3)添加新列

4)刪除列

5)修改表名

6)刪除表

7)表復(fù)制

8)復(fù)制表結(jié)構(gòu)及數(shù)據(jù)

十.約束

1.約束分類

2.約束應(yīng)用

1)列級應(yīng)用

2)表級約束

3)刪除約束

十一.事務(wù)控制語言DCL

1.事務(wù)

2.事務(wù)必須滿足的4個條件

3.事務(wù)控制語句

4.MySQL事物處理的方法

5.事務(wù)的創(chuàng)建

1)隱式事務(wù)

7.事務(wù)示例

十二.事務(wù)隔離

1.事務(wù)隔離要解決的問題

2.事務(wù)隔離級別

3.設(shè)置事務(wù)隔離級別

1)查看當(dāng)前事務(wù)隔離級別

2)設(shè)置隔離事務(wù)級別

3)測試

4.SAVEPOINT應(yīng)用

1)基本用法

2)SAVEPOINT示例


一.基本SQL語句用法及概述

1.常用MySQL命令

# 查看所有數(shù)據(jù)庫 SHOW DATABASES; # 切換指定數(shù)據(jù)庫 USE nsd2021; # 查看當(dāng)前庫中所有的表 SHOW TABLES; # 查看表結(jié)構(gòu) DESC departments; # 查看當(dāng)前所處的數(shù)據(jù)庫 SELECT DATABASE(); # 查看當(dāng)前登陸用戶 SELECT USER(); # 查看版本 SELECT VERSION(); [root@mysql1 ~]# mysql --version #不進庫查看 [root@mysql1 ~]# mysql -V

2.語法規(guī)范

關(guān)鍵字不區(qū)分大小寫,但建議關(guān)鍵字大寫

表名、列名建議小寫

每條命令最好用分號結(jié)尾,當(dāng)然,你用`\G結(jié)尾也可以

每條命令根據(jù)需要,可以進行縮進或換行(最好是關(guān)鍵字單獨占一行),如:

mysql> SELECT-> name, email-> FROM-> employees;

注釋

????????單行注釋

mysql> # select * from departments mysql> -- select * from departments

????????多行注釋

mysql> /*/*> SELECT/*> */*> FROM/*> departments;/*> */

3.SQL語句分類

數(shù)據(jù)查詢語言(Data Query Language, )DQL

負責(zé)進行數(shù)據(jù)查詢而不會對數(shù)據(jù)本身進行修改的語句,這是最基本的SQL語句。

數(shù)據(jù)定義語言 (Data Definition Language,)DDL

負責(zé)數(shù)據(jù)結(jié)構(gòu)定義與數(shù)據(jù)庫對象定義的語言,由CREATE、ALTER與DROP三個語法所組成

數(shù)據(jù)操縱語言(Data Manipulation Language,)DML

負責(zé)對數(shù)據(jù)庫對象運行數(shù)據(jù)訪問工作的指令集,以INSERT、UPDATE、DELETE三種指令為核心,分別代表插入、更新與刪除。

數(shù)據(jù)控制語言 (Data Control Language)

它可以控制特定用戶賬戶對數(shù)據(jù)表、查看表、預(yù)存程序、用戶自定義函數(shù)等數(shù)據(jù)庫對象的控制權(quán)。由 GRANT 和 REVOKE 兩個指令組成。

二.數(shù)據(jù)查詢語言

1.基礎(chǔ)查詢

SELECT 查詢的字段列表 FROM 表;

1)查詢的字段列表可以是字段、常量、表達式、函數(shù)等

# 查單個字段 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; # 查詢函數(shù) select version(); # 查詢函數(shù),統(tǒng)計salary共有多少行記錄 select count(*) from salary;

2)使用別名,字段名和別名之間可以用空格或關(guān)鍵字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函數(shù)進行字符串拼接

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:為空,相當(dāng)于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;

三.數(shù)據(jù)查詢語言之函數(shù)應(yīng)用

1.常用函數(shù)分類

1)按使用方式分為:

  • 單行函數(shù)

  • 分組函數(shù)

2)按用途分為

  • 字符函數(shù)

  • 數(shù)學(xué)函數(shù)

  • 日期函數(shù)

  • 流程控制函數(shù)

SELECT 函數(shù)(參數(shù)) FROM 表;

2.函數(shù)應(yīng)用

1)字符函數(shù)實例:

  • LENGTH(str):返字符串長度,以(字節(jié))為單位

select length('abc'); select length('你好'); select name, email, length(email) from employees where name='李平';
  • CHAR_LENGTH(str): 返回字符串長度,以(字符)為單位

select char_length('abc'); select char_length('你好');
  • CONCAT(s1,s2,...): 返回連接參數(shù)產(chǎn)生的字符串,一個或多個待拼接的內(nèi)容,任意一個為NULL則返回值為NULL

# 拼接字符串 mysql> select concat(dept_id, '-', dept_name) from departments;
  • UPPER(str)和UCASE(str): 將字符串中的字母全部轉(zhuǎn)換成大寫

select name, upper(email) from employees where name like '李%';
  • LOWER(str)和LCASE(str):將str中的字母全部轉(zhuǎn)換成小寫

# 轉(zhuǎn)小寫 select lower('HelloWorld');
  • SUBSTR(s, start, length): 從子符串s的start位置開始,取出length長度的子串,位置(從1)開始計算

select substr('hello world', 7); # 取子串,下標(biāo)從7開始取出3個 select substr('hello world', 7, 3);
  • INSTR(str,str1):返回str1參數(shù),在str參數(shù)內(nèi)的位置

# 子串在字符串中的位置 select instr('hello world', 'or'); select instr('hello world', 'ol');
  • TRIM(s): 返回字符串(s刪除了兩邊空格之后的字符串)

select trim(' hello world. ');

數(shù)學(xué)函數(shù)實例

  • ABS(x):返回x的絕對值

select abs(-10);(負—>正)
  • PI(): 返回圓周率π,默認顯示6位小數(shù)

select pi();
  • MOD(x,y): 返回x被y除后的余數(shù)

select mod(10, 3);
  • CEIL(x)、CEILING(x): 返回不小于x的最小整數(shù)

select ceil(10.1);
  • FLOOR(x): 返回不大于x的最大整數(shù)

select floor(10.9);
  • ROUND(x)、ROUND(x,y): 前者返回最接近于x的整數(shù),即對x進行四舍五入;后者返回最接近x的數(shù),其值保留到小數(shù)點后面y位,若y為負值,則將保留到x到小數(shù)點左邊y位

select round(10.6666);返回最接近于x的整數(shù),即對x進行四舍五入 select round(10.6666, 2);返回最接近x的數(shù),其值保留到小數(shù)點后面y位

2)日期和時間函數(shù)實例

  • CURDATE()、CURRENT_DATE(): 將當(dāng)前日期按照"YYYY-MM-DD"或者"YYYYMMDD"格式的值返回,具體格式根據(jù)函數(shù)用在字符串或是數(shù)字語境中而定

select curdate();當(dāng)前日期按照"YYYY-MM-DD" select curdate() + 0;格式根據(jù)函數(shù)用在字符串或是數(shù)字語境中而定
  • NOW(): 返回當(dāng)前日期和時間值,格式為"YYYY_MM-DD HH:MM:SS"或"YYYYMMDDHHMMSS",具體格式根據(jù)函數(shù)用在字符串或數(shù)字語境中而定

select now();式為"YYYY_MM-DD HH:MM:SS" select now() + 0;具體格式根據(jù)函數(shù)用在字符串或數(shù)字語境中而定
  • UNIX_TIMESTAMP()、UNIX_TIMESTAMP(date): 前者返回一個格林尼治標(biāo)準(zhǔn)時間1970-01-01 00:00:00到現(xiàn)在的秒數(shù),后者返回一個格林尼治標(biāo)準(zhǔn)時間1970-01-01 00:00:00到指定時間的秒數(shù)

select unix_timestamp();
  • FROM_UNIXTIME(date): 和UNIX_TIMESTAMP互為反函數(shù),把UNIX時間戳轉(zhuǎn)換為普通格式的時間

select from_unixtime(0);
  • MONTH(date)和MONTHNAME(date):前者返回指定日期中的月份,后者返回指定日期中的月份的名稱

select month('20211001120000');返回指定日期中的月份 select monthname('20211001120000');返回指定日期中的月份的名稱
  • DAYNAME(d)、DAYOFWEEK(d)、WEEKDAY(d): DAYNAME(d)返回d對應(yīng)的工作日的英文名稱,如Sunday、Monday等;DAYOFWEEK(d)返回的對應(yīng)一周中的索引,1表示周日、2表示周一;WEEKDAY(d)表示d對應(yīng)的工作日索引,0表示周一,1表示周二

select dayname('20211001120000');返回星期* select dayname('20211001');
  • WEEK(d): 計算日期d是一年中的第幾周

select week('20211001');
  • DAYOFYEAR(d)、DAYOFMONTH(d): 前者返回d是一年中的第幾天,后者返回d是一月中的第幾天

select dayofyear('20211001');
  • YEAR(date)、QUARTER(date)、MINUTE(time)、SECOND(time): YEAR(date)返回指定日期對應(yīng)的年份,范圍是1970到2069;QUARTER(date)返回date對應(yīng)一年中的季度,范圍是1到4;MINUTE(time)返回time對應(yīng)的分鐘數(shù),范圍是0~59;SECOND(time)返回制定時間的秒值

select year('20211001');返回指定日期對應(yīng)的年份 select quarter('20211001');回date對應(yīng)一年中的季度

流程控制函數(shù)實例

  • IF(expr,v1,v2): 如果expr是TRUE則返回v1,否則返回v2

select if(3>0, 'yes', 'no'); select name, dept_id, if(dept_id=1, '人事部', '非人事部') from employees where name='張亮';
  • IFNULL(v1,v2): 如果v1不為NULL,則返回v1,否則返回v2

select dept_id, dept_name, ifnull(dept_name, '未設(shè)置') from departments; insert into departments(dept_id) values(9); select dept_id, dept_name, ifnull(dept_name, '未設(shè)置') from departments;
  • CASE expr (WHEN v1)( THEN r1) [WHEN v2 THEN v2] [ELSE rn] END: 如果expr等于某個vn,則返回對應(yīng)位置THEN后面的結(jié)果,如果與所有值都不想等,則返回ELSE后面的rn

mysql> select dept_id, dept_name,-> case dept_nam-> when '運維部' then '技術(shù)部門'-> when '開發(fā)部' then '技術(shù)部門'-> when '測試部' then '技術(shù)部門'-> when null then '未設(shè)置'-> else '非技術(shù)部門'-> end as '部門類型'-> from departments; # 查看字段,名字。匹配 名字是 當(dāng)是v1就是r1 ,是v2 就是v2,否則就返回對應(yīng)位置THEN后面的結(jié)果,如果與所有值都不想等,則返回ELSE后面的值 select dept_id, dept_name,-> case -> when dept_name='運維部' then '技術(shù)部門'-> when dept_name='開發(fā)部' then '技術(shù)部門'-> when dept_name='測試部' then '技術(shù)部門'-> when dept_name is null then '未設(shè)置'-> else '非技術(shù)部門'-> end as '部門類型'-> from departments;

3)分組函數(shù)

用于統(tǒng)計,又稱為聚合函數(shù)或統(tǒng)計函數(shù)

  • sum() :求和

select employee_id, sum(basic+bonus) from salary where employee_id=10 and year(date)=2018;
  • avg() :求平均值

select employee_id, avg(basic+bonus) from salary where employee_id=10 and year(date)=2018;
  • max() :求最大值

select employee_id, max(basic+bonus) from salary where employee_id=10 and year(date)=2018;
  • min() :求最小值

select employee_id, min(basic+bonus) from salary where employee_id=10 and year(date)=2018;
  • count() :計算個數(shù)

select count(*) from departments;

四.數(shù)據(jù)查詢語言之分組查詢

1.分組查詢的概述

  • 在對數(shù)據(jù)表中數(shù)據(jù)進行統(tǒng)計時,可能需要按照一定的類別分別進行統(tǒng)計。比如查詢每個部門的員工數(shù)。

  • 使用GROUP BY按某個字段,或者多個字段中的值,進行分組,字段中值相同的為一組

語法格式

  • 查詢列表必須是分組函數(shù)和出現(xiàn)在(GROUP BY)后面的字段

  • 通常而言,分組前的數(shù)據(jù)篩選放在where子句中,分組后的數(shù)據(jù)篩選放在having子句中

SELECT 字段名1(要求出現(xiàn)在group by后面),分組函數(shù)(),…… FROM 表名 WHERE 條件 GROUP BY 字段名1,字段名2 HAVING 過濾條件 ORDER BY 字段;

應(yīng)用實例

  • 查詢每個部門的人數(shù)

select dept_id, count(*) from employees group by dept_id;
  • 查詢每個部門中年齡最大的員工

select dept_id, min(birth_date) from employees group by dept_id;
  • 查詢每個部門入職最晚員工的入職時間

select dept_id, max(hire_date) from employees group by dept_id;
  • 統(tǒng)計各部門使用tedu.cn郵箱的員工人數(shù)

mysql> select dept_id, count(*) from employees where email like '%@tedu.cn' group by dept_id; +---------+----------+ | dept_id | count(*) | +---------+----------+ | 1 | 5 | | 2 | 2 | | 3 | 4 | | 4 | 32 | | 5 | 7 | | 6 | 5 | | 7 | 15 | | 8 | 1 | +---------+----------+ 8 rows in set (0.00 sec)
  • 查看員工2018年工資總收入,按總收入進行降序排列

mysql> select employee_id, sum(basic+bonus) as total from salary where year(date)=2018 group by employee_id order by total desc;
  • 查詢部門人數(shù)少于10人

mysql> select dept_id, count(*) from employees where count(*)<10 group by dept_id; ERROR 1111 (HY000): Invalid use of group functionmysql> select dept_id, count(*) from employees group by dept_id having count(*)<10; +---------+----------+ | dept_id | count(*) | +---------+----------+ | 1 | 8 | | 2 | 5 | | 3 | 6 | | 6 | 9 | | 8 | 3 | +---------+----------+ 5 rows in set (0.00 sec)

五.數(shù)據(jù)查詢語言之連接查詢

1.連接查詢的概述

  • 也叫多表查詢。常用于查詢字段來自于多張表

  • 如果直接查詢兩張表,將會得到笛卡爾積

select name, dept_name from employees, departments;
  • 通過添加有效的條件可以進行查詢結(jié)果的限定

select name, dept_name from employees, departments where employees.dept_id=departments.dept_id;

2.連接分類

按功能分類

  • 內(nèi)連接(重要)

    • 等值連接

    • 非等值連接

    • 自連接

  • 外連接

    • 左外連接(重要)

    • 右外連接(重要)

    • 全外連接(mysql不支持,可以使用UNION實現(xiàn)相同的效果)

  • 交叉連接

按年代分類

  • SQL92標(biāo)準(zhǔn):僅支持內(nèi)連接

  • SQL99標(biāo)準(zhǔn):支持所有功能的連接

3.SQL99標(biāo)準(zhǔn)多表查詢

  • 語法格式

SELECT 字段... FROM 表1 [AS] 別名 [連接類型] JOIN 表2 [AS] 別名 ON 連接條件 WHERE 分組前篩選條件 GROUP BY 分組 HAVING 分組后篩選條件 ORDER BY 排序字段

1)內(nèi)連接

  • 語法格式

select 查詢列表 from 表1 別名 inner join 表2 別名 on 連接條件 inner join 表3 別名 on 連接條件 [where 篩選條件] [group by 分組] [having 分組后篩選] [order by 排序列表]

2)等值連接

  • 查詢每個員工所在的部門名

select name, dept_name-> from employees-> inner join departments-> on employees.dept_id=departments.dept_id;
  • 查詢每個員工所在的部門名,使用別名

select name, dept_name-> from employees as e-> inner join departments as d-> on e.dept_id=d.dept_id;
  • 查詢每個員工所在的部門名,使用別名。兩個表中的同名字段,必須指定表名

select name, d.dept_id, dept_name-> from employees as e-> inner join departments as d-> on e.dept_id=d.dept_id;
  • 查詢11號員工的名字及2018年每個月工資

select name, date, basic+bonus as total-> from employees as e-> inner join salary as s-> on e.employee_id=s.employee_id-> where year(s.date)=2018 and e.employee_id=11;
  • 查詢2018年每個員工的總工資

select name, sum(basic+bonus) from employees-> inner join salary-> on employees.employee_id=salary.employee_id-> where year(salary.date)=2018-> group by name;
  • 查詢2018年每個員工的總工資,按工資升序排列

select name, sum(basic+bonus) as total from employees as e-> inner join salary as s-> on e.employee_id=s.employee_id-> where year(s.date)=2018-> group by name-> order by total;
  • 查詢2018年總工資大于30萬的員工,按工資降序排列

select name, sum(basic+bonus) as total from employees as e-> inner join salary as s-> on e.employee_id=s.employee_id-> where year(s.date)=2018-> group by name-> having total>300000-> order by total desc;

3)非等值連接 between

附:創(chuàng)建工資級別表

創(chuàng)建表語法:

CREATE TABLE 表名稱 ( 列名稱1 數(shù)據(jù)類型, 列名稱2 數(shù)據(jù)類型, 列名稱3 數(shù)據(jù)類型, .... )

創(chuàng)建工資級別表:

  • id:主鍵。僅作為表的行號

  • grade:工資級別,共ABCDE五類

  • low:該級別最低工資

  • high:該級別最高工資

mysql> use nsd2021; mysql> create table wage_grade-> (-> id int,-> grade char(1),-> low int,-> high int,-> primary key (id));

向表中插入數(shù)據(jù):

  • 語法:

INSERT INTO 表名稱 VALUES (值1, 值2,....);
  • 向wage_grade表中插入五行數(shù)據(jù):

mysql> insert into wage_grade values-> (1, 'A', 5000, 8000),-> (2, 'B', 8001, 10000),-> (3, 'C', 10001, 15000),-> (4, 'D', 15001, 20000),-> (5, 'E', 20001, 1000000);
  • 查詢2018年12月員工基本工資級別

select employee_id, date, basic, grade-> from salary as s-> inner join wage_grade as g-> on s.basic between g.low and g.high-> where year(date)=2018 and month(date)=12;
  • 查詢2018年12月員工各基本工資級別的人數(shù)

select grade, count(*)-> from salary as s-> inner join wage_grade as g-> on s.basic between g.low and g.high-> where year(date)=2018 and month(date)=12-> group by grade;
  • 查詢2018年12月員工基本工資級別,員工需要顯示姓名

select name, date, basic, grade-> from salary as s-> inner join employees as e-> on s.employee_id=e.employee_id-> inner join wage_grade-> on basic between low and high-> where date='20181210'-> order by grade, basic;

4)自連接

  • 要點:

    • 將一張表作為兩張使用

    • 每張表起一個別名

  • 查看哪些員的生日月份與入職月份相同

select e.name, e.hire_date, em.birth_date-> from employees as e-> inner join employees as em-> on month(e.hire_date)=month(em.birth_date)-> and e.employee_id=em.employee_id;

5)外連接的概述

  • 常用于查詢一個表中有,另一個表中沒有的記錄

  • 如果從表中有和它匹配的,則顯示匹配的值

  • 如要從表中沒有和它匹配的,則顯示NULL

  • 外連接查詢結(jié)果=內(nèi)連接查詢結(jié)果+主表中有而從表中沒有的記錄

  • 左外連接中,left join左邊的是主表left outer join

  • 右外連接中,right join右邊的是主表right outer join

  • 左外連接和右外連接可互換,實現(xiàn)相同的目標(biāo)

6)左外連接

  • 語法

SELECT tb1.字段..., tb2.字段 FROM table1 AS tb1 LEFT OUTER JOIN table2 AS tb2 ON tb1.字段=tb2.字段
  • 查詢所有部門的人員以及沒有員工的部門

select d.*, e.name-> from departments as d-> left outer join employees as e-> on d.dept_id=e.dept_id;

7)右外連接

  • 語法

SELECT tb1.字段..., tb2.字段 FROM table1 AS tb1 RIGHT OUTER JOIN table2 AS tb2 ON tb1.字段=tb2.字段
  • 查詢所有部門的人員以及沒有員工的部門

select d.*, e.name-> from employees as e-> right outer join departments as d-> on d.dept_id=e.dept_id;

8)交叉連接 cross join

  • 返回笛卡爾積

  • 語法:

SELECT <字段名> FROM <表1> CROSS JOIN <表2> [WHERE子句]
  • 查詢員工表和部門表的笛卡爾積

select name, dept_name-> from employees-> cross join departments;

附:授予管理員root可以通過任意地址訪問數(shù)據(jù)庫,密碼是NSD2021@tedu.cn。默認情況下,root只允許在本機訪問

grant all on *.* to root@'%' identified by 'NSD2021@tedu.cn';

向部門表中插入數(shù)據(jù):

insert into departments(dept_name) values('采購部');


六.數(shù)據(jù)查詢語言之子查詢

1.子查詢的概述

子查詢就是指的在一個完整的查詢語句之中,嵌套若干個不同功能的小查詢,從而一起完成復(fù)雜查詢的一種編寫形式

子查詢返回的數(shù)據(jù)分類
????????單行單列:返回的是一個具體列的內(nèi)容,可以理解為一個單值數(shù)據(jù)

????????單行多列:返回一行數(shù)據(jù)中多個列的內(nèi)容

????????多行單列:返回多行記錄之中同一列的內(nèi)容,相當(dāng)于給出了一個操作范圍

????????多行多列:查詢返回的結(jié)果是一張臨時表

子查詢常出現(xiàn)的位置
????????select之后:僅支持單行單列????????

????????from之后:支持多行多列

????????where或having之后:支持單行單列、單行多列、多行單列

2.子查詢實例

1)單行單列

查詢運維部所有員工信息

分析:
????????首先從departments表中查出運維部的編號

mysql> select dept_id from departments where dept_name='運維部'; +---------+ | dept_id | +---------+ | 3 | +---------+ 1 row in set (0.00 sec) 再從employees表中查找該部門編號和運維部編號相同的員工 mysql> select *-> from employees-> where dept_id=(-> select dept_id from departments where dept_name='運維部'-> );

查詢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-> );

查詢部門員工人數(shù)比開發(fā)部人數(shù)少的部門

分析:

查詢開發(fā)部部門編號

mysql> select dept_id from departments where dept_name='開發(fā)部'; +---------+ | dept_id | +---------+ | 4 | +---------+ 1 row in set (0.00 sec) 查詢開發(fā)部人數(shù)mysql> select count(*) from employees-> where dept_id=(-> select dept_id from departments where dept_name='開發(fā)部'-> ); +----------+ | count(*) | +----------+ | 55 | +----------+ 1 row in set (0.00 sec)

分組查詢各部門人數(shù)

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)

?查詢部門員工人數(shù)比開發(fā)部人數(shù)少的部門

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='開發(fā)部'-> )-> ); +----------+---------+ | count(*) | dept_id | +----------+---------+ | 8 | 1 | | 5 | 2 | | 6 | 3 | | 12 | 5 | | 9 | 6 | | 35 | 7 | | 3 | 8 | +----------+---------+ 7 rows in set (0.00 sec)

查詢每個部門的人數(shù)

分析:

查詢所有部門的信息

mysql> select d.* from departments as d; +---------+-----------+ | dept_id | dept_name | +---------+-----------+ | 1 | 人事部 | | 2 | 財務(wù)部 | | 3 | 運維部 | | 4 | 開發(fā)部 | | 5 | 測試部 | | 6 | 市場部 | | 7 | 銷售部 | | 8 | 法務(wù)部 | | 9 | NULL | +---------+-----------+ 9 rows in set (0.00 sec)

查詢每個部門的人數(shù)

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 | 財務(wù)部 | 5 | | 3 | 運維部 | 6 | | 4 | 開發(fā)部 | 55 | | 5 | 測試部 | 12 | | 6 | 市場部 | 9 | | 7 | 銷售部 | 35 | | 8 | 法務(wù)部 | 3 | | 9 | NULL | 0 | +---------+-----------+--------+ 9 rows in set (0.00 sec)

2)多行單列


查詢?nèi)耸虏亢拓攧?wù)部員工信息

分析:

查詢?nèi)耸虏亢拓攧?wù)部編號

mysql> select dept_id from departments-> where dept_name in ('人事部', '財務(wù)部'); +---------+ | 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 ('人事部', '財務(wù)部')-> );

查詢?nèi)耸虏?018年12月所有員工工資

分析:

查詢?nèi)耸虏坎块T編號

mysql> select dept_id from departments where dept_name='人事部'; +---------+ | dept_id | +---------+ | 1 | +---------+ 1 row in set (0.00 sec) 查詢?nèi)耸虏繂T的編號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號部門及其部門內(nèi)員工的編號、名字和email

分析

查詢3號部門和員工的所有信息

mysql> select d.dept_name, e.*-> from departments as d-> inner join employees as e-> on d.dept_id=e.dept_id; 將上述結(jié)果當(dāng)成一張臨時表,必須為其起別名。再從該臨時表中查詢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查詢時,如果結(jié)果集數(shù)據(jù)量很大,比如幾萬行數(shù)據(jù),放在一個頁面顯示的話數(shù)據(jù)量太大,不如分頁顯示,每次顯示100條

要實現(xiàn)分頁功能,實際上就是從結(jié)果集中顯示第1至100條記錄作為第1頁,顯示第101至200條記錄作為第2頁,以此類推

分頁實際上就是從結(jié)果集中“截取”出從M開始,偏移到N的記錄。這個查詢可以通過LIMIT <M>, <N>子句實現(xiàn)

起始索引從0開始

每頁顯示內(nèi)容速算:LIMIT (PAGE-1)*SIZE, SIZE

示例:

# 按employee_id排序,取出前5位員姓名
?

mysql> select employee_id, name from employees-> order by employee_id-> limit 0, 5; +-------------+-----------+ | employee_id | name | +-------------+-----------+ | 1 | 梁偉 | | 2 | 郭巖 | | 3 | 李玉英 | | 4 | 張健 | | 5 | 鄭靜 | +-------------+-----------+ 5 rows in set (0.00 sec)


# 按employee_id排序,取出前15至20號員姓名

mysql> select employee_id, name from employees-> order by employee_id-> limit 15, 5; +-------------+--------+ | employee_id | name | +-------------+--------+ | 16 | 聶想 | | 17 | 陳陽 | | 18 | 戴璐 | | 19 | 陳斌 | | 20 | 蔣紅 | +-------------+--------+ 5 rows in set (0.00 sec)

6)聯(lián)合查詢UNION

作用:將多條select語句的結(jié)果,合并到一起,稱之為聯(lián)合操作。

語法:( ) UNION ( )

要求查詢時,多個select語句的檢索到的字段數(shù)量必須一致

每一條記錄的各字段類型和順序最好是一致的

UNION關(guān)鍵字默認去重,可以使用UNION ALL包含重復(fù)項

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)


例,某生產(chǎn)商有一張原材料表和一張商品表,需要把原材料價格和商品價格一起輸出

查詢1972年前或2000年后出生的員工

# 普通方法
?

mysql> select name, birth_date from employees-> where year(birth_date)<1972 or year(birth_date)>2000; +-----------+------------+ | name | birth_date | +-----------+------------+ | 梁偉 | 1971-08-19 | | 張建平 | 1971-11-02 | | 竇紅梅 | 1971-09-09 | | 溫蘭英 | 1971-08-14 | | 朱文 | 1971-08-15 | | 和林 | 1971-12-10 | +-----------+------------+ 6 rows in set (0.01 sec)

# 聯(lián)合查詢的方法
?

mysql> (-> select name, birth_date from employees-> where year(birth_date)<1972-> )-> union-> (-> select name, birth_date from employees-> where year(birth_date)>=2000-> ); +-----------+------------+ | name | birth_date | +-----------+------------+ | 梁偉 | 1971-08-19 | | 張建平 | 1971-11-02 | | 竇紅梅 | 1971-09-09 | | 溫蘭英 | 1971-08-14 | | 朱文 | 1971-08-15 | | 和林 | 1971-12-10 | +-----------+------------+ 6 rows in set (0.00 sec)

七.插入語句DDL

1.不指定列名的插入

語法格式:

????????INSERT INTO 表名稱 VALUES (值1, 值2,....)
需要為所有列指定值

值的順序必須與表中列的順序一致

示例:# 如果表中已有1號部門,則出錯。因為dept_id是主鍵,不允許重復(fù)

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: 0

2.指定列名的插入

語法格式:

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)


支持子查詢

mysql> insert into employees-> (name, hire_date, birth_date, email, phone_number, dept_id)-> (-> select name, hire_date, birth_date, email, phone_number, dept_id-> from employees-> where name='張三'-> ); Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0

3.使用set語句

語法格式:

INSERT INTO 表名 SET 列名1=列值1, 列名2=列值2, ...
示例:

mysql> insert into departments set dept_name='采購部'; Query OK, 1 row affected (0.00 sec)

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

修改多表記錄
語法:

UPDATE 表1 AS 表1別名 INNER | LEFT | RIGHT JOIN 表2 AS 表2別名 ON 連接條件 SET 列=值, 列=值, ... WHERE 連接條件


示例:

# 修改李四所在部門為企劃部

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.刪除記錄

刪除單表記錄
語法:

DELETE FROM 表名 WHERE 篩選條件;

刪除的是滿足條件的整行記錄,而不是某個字段

示例:

# 刪除重復(fù)的員工張三,只保留一個張三的信息
# 查詢張三信息

mysql> select * from employees where name='張三';

# 根據(jù)員工編號刪除重復(fù)的張三

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繼續(xù)編號

TRUNCATE不能回滾,DELETE可以

效率略高于DELETE

示例:

# 清空wage_grade表 mysql> truncate table wage_grade; Query OK, 0 rows affected (0.01 sec)

八.數(shù)據(jù)庫管理

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

  • 語法:

CREATE DATABASE [IF NOT EXISTS] <數(shù)據(jù)庫名> [[DEFAULT] CHARACTER SET <字符集名>] [[DEFAULT] COLLATE <校對規(guī)則名>];
  • [ ]中的內(nèi)容是可選的

  • <數(shù)據(jù)庫名>:創(chuàng)建數(shù)據(jù)庫的名稱。MySQL 的數(shù)據(jù)存儲區(qū)將以目錄方式表示 MySQL 數(shù)據(jù)庫,因此數(shù)據(jù)庫名稱必須符合操作系統(tǒng)的文件夾命名規(guī)則,不能以數(shù)字開頭,盡量要有實際意義。

  • IF NOT EXISTS:在創(chuàng)建數(shù)據(jù)庫之前進行判斷,只有該數(shù)據(jù)庫目前尚不存在時才能執(zhí)行操作。此選項可以用來避免數(shù)據(jù)庫已經(jīng)存在而重復(fù)創(chuàng)建的錯誤。

  • [DEFAULT] CHARACTER SET:指定數(shù)據(jù)庫的字符集。指定字符集的目的是為了避免在數(shù)據(jù)庫中存儲的數(shù)據(jù)出現(xiàn)亂碼的情況。如果在創(chuàng)建數(shù)據(jù)庫時不指定字符集,那么就使用系統(tǒng)的默認字符集。

  • [DEFAULT] COLLATE:指定字符集的默認校對規(guī)則。

  • MySQL 的字符集(CHARACTER)和校對規(guī)則(COLLATION)是兩個不同的概念。字符集是用來定義 MySQL 存儲字符串的方式,校對規(guī)則定義了比較字符串的方式。

2.修改數(shù)據(jù)庫

  • 語法:

ALTER DATABASE [數(shù)據(jù)庫名] { [ DEFAULT ] CHARACTER SET <字符集名> | [ DEFAULT ] COLLATE <校對規(guī)則名>}
  • ALTER DATABASE 用于更改數(shù)據(jù)庫的全局特性。

  • 使用 ALTER DATABASE 需要獲得數(shù)據(jù)庫 ALTER 權(quán)限。

  • 數(shù)據(jù)庫名稱可以忽略,此時語句對應(yīng)于默認數(shù)據(jù)庫。

  • CHARACTER SET 子句用于更改默認的數(shù)據(jù)庫字符集。

3.刪除數(shù)據(jù)庫

  • 語法:

DROP DATABASE [ IF EXISTS ] <數(shù)據(jù)庫名>
  • <數(shù)據(jù)庫名>:指定要刪除的數(shù)據(jù)庫名。

  • IF EXISTS:用于防止當(dāng)數(shù)據(jù)庫不存在時發(fā)生錯誤。

  • DROP DATABASE:刪除數(shù)據(jù)庫中的所有表格并同時刪除數(shù)據(jù)庫。

  • 如果要使用 DROP DATABASE,需要獲得數(shù)據(jù)庫 DROP 權(quán)限。

九.表管理

1.關(guān)系數(shù)據(jù)庫的規(guī)范化

良好的數(shù)據(jù)庫設(shè)計表現(xiàn)在以下幾方面:

  • 訪問效率高

  • 減少數(shù)據(jù)冗余,節(jié)省存儲空間,便于進一步擴展

  • 可以使應(yīng)用程序的開發(fā)變得更容易

關(guān)系數(shù)據(jù)庫的規(guī)范化理論為:關(guān)系數(shù)據(jù)庫中的每一個關(guān)系都要滿足一定的規(guī)范。根據(jù)滿足規(guī)范的條件不同,可以分為6個等級:第一范式(1NF)、第二范式(2NF)……第五范式(5NF)。其中,NF是Normal Form的縮寫。一般情況下,只要把數(shù)據(jù)規(guī)范到第三范式標(biāo)準(zhǔn)就可以滿足需要了。

第一范式(1NF)

  • 在一個關(guān)系中,消除重復(fù)字段,且各字段都是最小的邏輯存儲單位。即,要滿足原子性。

  • 第一范式是第二和第三范式的基礎(chǔ),是最基本的范式。第一范式包括下列指導(dǎo)原則。 (1)數(shù)據(jù)組的每個屬性只可以包含一個值。 (2)關(guān)系中的每個數(shù)組必須包含相同數(shù)量的值。 (3)關(guān)系中的每個數(shù)組一定不能相同。

  • 在任何一個關(guān)系數(shù)據(jù)庫中,第一范式是對關(guān)系模式的基本要求,不滿足第一范式的數(shù)據(jù)庫就不是關(guān)系型數(shù)據(jù)庫。

第二范式(2NF)

  • 第二范式是在第一范式的基礎(chǔ)上建立起來的,即滿足第二范式必先滿足第一范式(1NF)。

  • 第二范式要求數(shù)據(jù)庫表中的每個實體(即各個記錄行)必須可以被唯一地區(qū)分。

  • 為實現(xiàn)區(qū)分各行記錄通常需要為表設(shè)置一個“區(qū)分列”,用以存儲各個實體的唯一標(biāo)識。這個唯一屬性列被稱為主關(guān)鍵字或主鍵。

  • 第二范式要求實體的屬性完完全依賴于主關(guān)鍵字,即不能存在僅依賴主關(guān)鍵字一部分的屬性,如果存在,那么這個屬性和主關(guān)鍵字的這一部分應(yīng)該分離出來形成一個新的實體,新實體與原實體之間是一對多的關(guān)系。

第三范式(3NF)

  • 第三范式是在第二范式的基礎(chǔ)上建立起來的,即滿足第三范式必先滿足第二范式。

  • 第三范式要求關(guān)系表不存在非關(guān)鍵字列對任意候選關(guān)鍵字列的傳遞函數(shù)依賴,也就是說,第三范式要求一個關(guān)系表中不包含已在其他表中包含的非主關(guān)鍵字信息。

  • 除主鍵外,其他字段必須依賴主鍵。

2.表管理語句

創(chuàng)建表

  • 語法:

CREATE TABLE 表名稱 ( 列名稱1 數(shù)據(jù)類型 [(長度) 約束], 列名稱2 數(shù)據(jù)類型 [(長度) 約束], 列名稱3 數(shù)據(jù)類型 [(長度) 約束], .... )

3.常用數(shù)據(jù)類型

數(shù)據(jù)類型描述
tinyint(m)1個字節(jié) 范圍(-128~127)
smallint(m)2個字節(jié) 范圍(-32768~32767)
mediumint(m)3個字節(jié) 范圍(-8388608~8388607)
int(m)4個字節(jié) 范圍(-2147483648~2147483647)
bigint(m)8個字節(jié) 范圍(+-9.22*10的18次方)
float(m,d)單精度浮點型 8位精度(4字節(jié)) m總個數(shù),d小數(shù)位
double(m,d)雙精度浮點型 16位精度(8字節(jié)) m總個數(shù),d小數(shù)位
decimal(m,d)m表示十進制數(shù)字總的個數(shù),d表示小數(shù)點后面數(shù)字的位數(shù)。常用于貨幣
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, ...)單選字符串?dāng)?shù)據(jù)類型,適合存儲表單界面中的“單選值”
set(選項1,選項2, ...)多選字符串?dāng)?shù)據(jù)類型,適合存儲表單界面的“多選值”。

4.示例:

# 創(chuàng)建數(shù)據(jù)庫mydb mysql> create database mydb default charset utf8mb4; Query OK, 1 row affected (0.00 sec) ? mysql> use mydb; Database changed # 創(chuàng)建部門表 mysql> create table departments (-> id int,-> dept_name varchar(20)-> ); Query OK, 0 rows affected (0.01 sec)

1)修改表

修改列名

  • 語法:

ALTER TABLE 表 CHANGE [COLUMN] 列表 數(shù)據(jù)類型
  • 示例:

mysql> alter table departments-> change id dept_id int; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0

2)修改列的類型或約束

  • 語法:

ALTER TABLE 表 MODIFY [COLUMN] 列名 類型
  • 示例:

mysql> alter table departments-> modify dept_name varchar(10); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0

3)添加新列

  • 語法:

ALTER TABLE 表 ADD [COLUMN] 列名 類型
  • 示例:

mysql> alter table departments-> add manager_id int; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0

4)刪除列

  • 語法:

ALTER TABLE 表 DROP [COLUMN] 列名
  • 示例:

mysql> alter table departments-> drop manager_id; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0

5)修改表名

  • 語法:

ALTER TABLE 表名 RENAME TO 新表名
  • 示例:

mysql> alter table departments-> rename to depts; Query OK, 0 rows affected (0.00 sec)

6)刪除表

  • 語法:

DROP TABLE [IF EXISTS] 表名
  • 示例:

mysql> drop table depts; Query OK, 0 rows affected (0.01 sec)

7)表復(fù)制

僅復(fù)制表結(jié)構(gòu)

  • 語法:

CREATE TABLE 待創(chuàng)建的表名 LIKE 已有表名
  • 示例:

mysql> create table departments like nsd2021.departments; Query OK, 0 rows affected (0.01 sec)

8)復(fù)制表結(jié)構(gòu)及數(shù)據(jù)

  • 語法:

CREATE TABLE 待創(chuàng)建的表名 SELECT 字段, ... FROM 已有表名
  • 示例:

mysql> create table departments2-> select * from nsd2021.departments; Query OK, 13 rows affected (0.01 sec) Records: 13 Duplicates: 0 Warnings: 0

十.約束

  • 約束是一種限制,用于限制表中的數(shù)據(jù),為了保證表中數(shù)據(jù)的準(zhǔn)確性和可靠性。

  • 創(chuàng)建表時可以添加約束

  • 修改表時可以添加約束

1.約束分類

  • PRIMARY KEY:主鍵,用于保證該字段的值具有唯一性并且非空。

  • NOT NULL :非空,用于保證該字段的值不能為空。

  • DEFAULT:默認值,用于保證該字段有默認值。

  • UNIQUE:唯一,用于保證該字段的值具有唯一性,可以為空。

  • FOREIGN KEY:外鍵,用于限制兩個表的關(guān)系,用于保證該字段的值必須來自于主表的關(guān)聯(lián)列的值,在從表添加外鍵約束,用于引用主表中某些的值。

約束可應(yīng)用在列級或表級。列表所有約束均支持,但外鍵約束沒有效果;表級約束可以支持主鍵、唯一、外鍵約束。

2.約束應(yīng)用

1)列級應(yīng)用

  • 創(chuàng)建表時使用約束

mysql> create table employees(-> employee_id int primary key auto_increment, -- 主鍵約束-> name varchar(20) not null, -- 非空約束-> gender enum('男', '女'),-> email varchar(20) unique, -- 唯一約束-> nation varchar(10) default '漢族' -- 默認值約束-> ); Query OK, 0 rows affected (0.00 sec)

2)表級約束

  • 創(chuàng)建表時使用約束

mysql> create table employees2 (-> employee_id int auto_increment,-> name varchar(20),-> email varchar(20),-> dept_id int,-> primary key (employee_id), -- 主鍵-> unique (email), -- 唯一-> foreign key (dept_id) references departments(dept_id) -- 外鍵-> ); # 查看約束 mysql> select * from information_schema.table_constraints where table_name='employees2' \G
  • 自定義約束名稱

mysql> create table employees3 (-> employee_id int,-> name varchar(20),-> dept_id int,-> constraint pk primary key(employee_id), # 不報錯,不生效-> constraint fk_employees3_departments foreign key(dept_id) references departments(dept_id)-> );

3)刪除約束

  • 語法:

ALTER TABLE <表名> DROP FOREIGN KEY <外鍵約束名>
  • 示例:

mysql> alter table employees3-> drop foreign key fk_employees3_departments;

例:創(chuàng)建員工數(shù)據(jù)庫的三張表

# 創(chuàng)建部門表 create table departments(dept_id int AUTO_INCREMENT PRIMARY KEY,dept_name VARCHAR(10) UNIQUE ); # 創(chuàng)建員工表 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) ); # 創(chuàng)建工資表 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) );

十一.事務(wù)控制語言DCL

1.事務(wù)

  • 數(shù)據(jù)庫事務(wù)指的是一組數(shù)據(jù)操作。

  • 主要用于處理操作量大,復(fù)雜度高的數(shù)據(jù)。

  • 在 MySQL 中只有使用了 Innodb 數(shù)據(jù)庫引擎的數(shù)據(jù)庫或表才支持事務(wù)。

  • 事務(wù)處理可以用來維護數(shù)據(jù)庫的完整性,保證成批的 SQL 語句要么全部執(zhí)行,要么全部不執(zhí)行。

  • 事務(wù)用來管理 insert,update,delete 語句

2.事務(wù)必須滿足的4個條件

  • 原子性(Atomicity):一個事務(wù)(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結(jié)束在中間某個環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯誤,會被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣。

  • 一致性(Consistency):在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預(yù)設(shè)規(guī)則,這包含資料的精確度、串聯(lián)性以及后續(xù)數(shù)據(jù)庫可以自發(fā)性地完成預(yù)定的工作。

  • 隔離性(Isolation):數(shù)據(jù)庫允許多個并發(fā)事務(wù)同時對其數(shù)據(jù)進行讀寫和修改的能力,隔離性可以防止多個事務(wù)并發(fā)執(zhí)行時由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。事務(wù)隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復(fù)讀(repeatable read)和串行化(Serializable)。

  • 持久性(Durability):事務(wù)處理結(jié)束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會丟失。

3.事務(wù)控制語句

  • BEGIN 或 START TRANSACTION 顯式地開啟一個事務(wù);

  • COMMIT 也可以使用 COMMIT WORK,不過二者是等價的。COMMIT 會提交事務(wù),并使已對數(shù)據(jù)庫進行的所有修改成為永久性的;

  • ROLLBACK 也可以使用 ROLLBACK WORK,不過二者是等價的。回滾會結(jié)束用戶的事務(wù),并撤銷正在進行的所有未提交的修改;

  • SAVEPOINT identifier,SAVEPOINT 允許在事務(wù)中創(chuàng)建一個保存點,一個事務(wù)中可以有多個 SAVEPOINT;

  • RELEASE SAVEPOINT identifier 刪除一個事務(wù)的保存點,當(dāng)沒有指定的保存點時,執(zhí)行該語句會拋出一個異常;

  • ROLLBACK TO identifier 把事務(wù)回滾到標(biāo)記點;

  • SET TRANSACTION 用來設(shè)置事務(wù)的隔離級別。InnoDB 存儲引擎提供事務(wù)的隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

4.MySQL事物處理的方法

  • 用 BEGIN, ROLLBACK, COMMIT來實現(xiàn)

    • BEGIN開始一個事務(wù)

    • ROLLBACK事務(wù)回滾

    • COMMIT提交事務(wù)

  • 直接用 SET 來改變 MySQL 的自動提交模式

    • SET AUTOCOMMIT=0 禁止自動提交

    • SET AUTOCOMMIT=1*開啟自動提交

5.事務(wù)的創(chuàng)建

1)隱式事務(wù)

  • 事務(wù)沒有明顯的開啟和結(jié)束的標(biāo)記。如INSERT、UPDATE、DELETE語句。

mysql> show variables like '%autocommit%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 1 row in set (0.00 sec)

2)顯式事務(wù)

  • 事務(wù)具有明顯的開啟和結(jié)束的標(biāo)記

  • 必須先設(shè)置自動提交功能為禁用

mysql> set autocommit=0; # 只對當(dāng)前會話生效 Query OK, 0 rows affected (0.00 sec)mysql> show variables like '%autocommit%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | OFF | +---------------+-------+ 1 row in set (0.00 sec)

6.創(chuàng)建事務(wù)步驟

1)開啟事務(wù)

set aotocommit=0; start transaction; # 可選
  • 編寫事務(wù)語句:INSERT、UPDATE、DELETE語句

  • 結(jié)束事務(wù)

  • commit | rollback;

    7.事務(wù)示例

    • 創(chuàng)建銀行表

    mysql> use mydb; mysql> create table bank(-> id int primary key,-> name varchar(20),-> balance int-> ); Query OK, 0 rows affected (0.01 sec)
    • 插入數(shù)據(jù)

    mysql> insert into bank values-> (1, 'kali', 10000), (2, 'yao', 10000); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0
    • 使用事務(wù):正常提交

    mysql> set autocommit=0; mysql> update bank set balance=balance-1000 where name='kali'; mysql> update bank set balance=balance+1000 where name='yao'; # 此時在另一終端查看bank表,數(shù)據(jù)并未改變 mysql> commit;
    • 使用事務(wù):回滾

    mysql> set autocommit=0; mysql> update bank set balance=balance+1000 where name='kali'; mysql> update bank set balance=balance-1000 where name='yao'; # 此時在另一終端查看bank表,數(shù)據(jù)并未改變 mysql> rollback;

    十二.事務(wù)隔離

    1.事務(wù)隔離要解決的問題

    • 臟讀:臟讀指的是讀到了其他事務(wù)未提交的數(shù)據(jù),未提交意味著這些數(shù)據(jù)可能會回滾,也就是可能最終不會存到數(shù)據(jù)庫中,也就是不存在的數(shù)據(jù)。讀到了并不一定最終存在的數(shù)據(jù),這就是臟讀。

    • 可重復(fù)讀:可重復(fù)讀指的是在一個事務(wù)內(nèi),最開始讀到的數(shù)據(jù)和事務(wù)結(jié)束前的任意時刻讀到的同一批數(shù)據(jù)都是一致的。通常針對數(shù)據(jù)更新(UPDATE)操作。

    • 不可重復(fù)讀:對比可重復(fù)讀,不可重復(fù)讀指的是在同一事務(wù)內(nèi),不同的時刻讀到的同一批數(shù)據(jù)可能是不一樣的,可能會受到其他事務(wù)的影響,比如其他事務(wù)改了這批數(shù)據(jù)并提交了。通常針對數(shù)據(jù)更新(UPDATE)操作。

    • 幻讀:幻讀是針對數(shù)據(jù)插入(INSERT)操作來說的。假設(shè)事務(wù)A對某些行的內(nèi)容作了更改,但是還未提交,此時事務(wù)B插入了與事務(wù)A更改前的記錄相同的記錄行,并且在事務(wù)A提交之前先提交了,而這時,在事務(wù)A中查詢,會發(fā)現(xiàn)好像剛剛的更改對于某些數(shù)據(jù)未起作用,但其實是事務(wù)B剛插入進來的,讓用戶感覺很魔幻,感覺出現(xiàn)了幻覺,這就叫幻讀。

    2.事務(wù)隔離級別

    • 讀未提交(READ UNCOMMITTED)

    • 讀提交 (READ COMMITTED)

    • 可重復(fù)讀 (REPEATABLE READ)

    • 串行化 (SERIALIZABLE)

    從上往下,隔離強度逐漸增強,性能逐漸變差。采用哪種隔離級別要根據(jù)系統(tǒng)需求權(quán)衡決定,其中,可重復(fù)讀是 MySQL 的默認級別。

    事務(wù)隔離其實就是為了解決上面提到的臟讀、不可重復(fù)讀、幻讀這幾個問題。只有串行化的隔離級別解決了全部這 3 個問題,其他的 3 個隔離級別都有缺陷。

    隔離級別出現(xiàn)臟讀出現(xiàn)不可重讀出現(xiàn)幻讀
    讀未提交可能可能可能
    讀提交不可能可能可能
    可重復(fù)讀不可能不可能可能
    串行化不可能不可能不可能

    3.設(shè)置事務(wù)隔離級別

    1)查看當(dāng)前事務(wù)隔離級別

    mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set (0.00 sec)

    2)設(shè)置隔離事務(wù)級別

    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)測試

    # 在第一個終端上執(zhí)行以下2條語句 mysql> set autocommit=0; mysql> update bank set balance=balance+1000 where name='kali';# 以下3條語句在第二個終端上執(zhí)行 mysql> set session transaction isolation level read uncommitted; mysql> set autocommit=0; mysql> select * from bank; # 此時kali賬戶上已經(jīng)增加1000# 回到第一個終端回滾 mysql> rollback;# 在第2個終端上重新查詢 mysql> select * from bank; # 此時kali賬戶上又減少了1000

    4.SAVEPOINT應(yīng)用

    1)基本用法

    • 使用mysql中的savepoint保存點來實現(xiàn)事務(wù)的部分回滾

    • 語法:

    SAVEPOINT identifier ROLLBACK [WORK] TO [SAVEPOINT] identifier RELEASE SAVEPOINT identifier
    • 使用 SAVEPOINT identifier 來創(chuàng)建一個名為identifier的回滾點

    • ROLLBACK TO identifier,回滾到指定名稱的SAVEPOINT,這里是identifier

    • 使用 RELEASE SAVEPOINT identifier 來釋放刪除保存點identifier

    • 如果當(dāng)前事務(wù)具有相同名稱的保存點,則將刪除舊的保存點并設(shè)置一個新的保存點。

    • 如果執(zhí)行START TRANSACTION,COMMIT和ROLLBACK語句,則將刪除當(dāng)前事務(wù)的所有保存點。

    2)SAVEPOINT示例

    mysql> set autocommit=0; mysql> update bank set balance=balance+1000 where name='kali'; mysql> savepoint aaa; # 創(chuàng)建保存點 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; # 因為從未執(zhí)行過commit。所以查到的結(jié)果與執(zhí)行事務(wù)之前查到的結(jié)果一樣。

    總結(jié)

    以上是生活随笔為你收集整理的SQL基本语句及用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。