目錄
1.MySQL概述
1.1 安裝
1.1.1 版本
1.1.2 安裝
1.1.3 連接
1.2 數據模型
1.3 SQL簡介
1.3.1 分類
1.3.2 SQL通用語法
2.DDL
2.1 數據庫操作
2.2 圖形化工具
2.2.1 使用
2.3 表操作
2.3.1 創建表
2.3.1.1約束
2.3.1.2 數據類型
2.3.1.3 案例
2.3.2 DDL(表操作)
3.DML
3.1 增加(insert)
3.2 修改(update)
3.3 刪除(delete)
4.DQL
4.1 語法
4.2 基本查詢
4.4 條件查詢
4.5 聚合函數
4.6 分組查詢
4.7 排序查詢
4.8 分頁查詢
1.MySQL概述
1.1 安裝
1.1.1 版本
MySQL官方提供了兩個版本:
-
商業版本(MySQL Enterprise Edition)
-
該版本是收費的,我們可以使用30天。 官方會提供對應的技術支持。
-
-
社區版本(MySQL Community Server)
-
該版本是免費的,但是MySQL不會提供任何的技術支持。
-
本課程,采用的是MySQL的社區版本(8.0.34)
1.1.2 安裝
官網下載地址:https://downloads.mysql.com/archives/community/
1.1.3 連接
MySQL服務器啟動完畢后,然后再使用如下指令,來連接MySQL服務器:
mysql -u用戶名 -p密碼 [-h數據庫服務器的IP地址 -P端口號]
-h 參數不加,默認連接的是本地 127.0.0.1 的MySQL服務器
-P 參數不加,默認連接的端口號是 3306
上述指令,可以有兩種形式:
-
密碼直接在-p參數之后直接指定 (這種方式不安全,密碼直接以明文形式出現在命令行)
密碼在-p回車之后,在命令行中輸入密碼,然后回車
上述的MySQL服務器我們是安裝在本地的,這個僅僅是在我們學習階段,在真實的企業開發中,MySQL數據庫服務器是不會在我們本地安裝的,是在公司的服務器上安裝的,而服務器還需要放置在專門的IDC機房中的,IDC機房呢,就需要保證恒溫、恒濕、恒壓,而且還要保證網絡、電源的可靠性(備用電源及網絡)。
那我們要想使用服務器上的這臺MySQL服務器,就需要在我們的電腦上去遠程連接這臺MySQL 。 而服務器上安裝的MySQL數據庫呢,并不是你一個人在訪問,我們項目組的其他開發人員也是需要訪問這臺MySQL的。
接下來,就來演示一下,通過MySQL的客戶端命令行,如何來連接服務器上部署的MySQL :
mysql [-h數據庫服務器的IP地址 -P端口號] -u用戶名 -p密碼
1.2 數據模型
介紹完了Mysql數據庫的安裝配置之后,接下來我們再來聊一聊Mysql當中的數據模型。學完了這一小節之后,我們就能夠知道在Mysql數據庫當中到底是如何來存儲和管理數據的。
在介紹 Mysql的數據模型之前,需要先了解一個概念:關系型數據庫。
關系型數據庫(RDBMS)
概念:建立在關系模型基礎上,由多張相互連接的二維表組成的數據庫。
而所謂二維表,指的是由行和列組成的表,如下圖:
二維表的優點:
-
使用表存儲數據,格式統一,便于維護
-
使用SQL語言操作,標準統一,使用方便,可用于復雜查詢
我們之前提到的MySQL、Oracle、DB2、SQLServer這些都是屬于關系型數據庫,里面都是基于二維表存儲數據的。
結論:基于二維表存儲數據的數據庫就成為關系型數據庫,不是基于二維表存儲數據的數據庫,就是非關系型數據庫(比如大家后面要學習的Redis,就屬于非關系型數據庫)。
2). 數據模型
MySQL是關系型數據庫,是基于二維表進行數據存儲的,具體的結構圖下:
-
通過MySQL客戶端連接數據庫管理系統DBMS,然后通過DBMS操作數據庫
-
使用MySQL客戶端,向數據庫管理系統發送一條SQL語句,由數據庫管理系統根據SQL語句指令去操作數據庫中的表結構及數據
-
一個數據庫服務器中可以創建多個數據庫,一個數據庫中也可以包含多張表,而一張表中又可以包含多行記錄。
在Mysql數據庫服務器當中存儲數據,你需要:
先去創建數據庫(可以創建多個數據庫,之間是相互獨立的)
在數據庫下再去創建數據表(一個數據庫下可以創建多張表)
再將數據存放在數據表中(一張表可以存儲多行數據)
1.3 SQL簡介
1.3.1 分類
1.3.2 SQL通用語法
1.SQL語句可以單行或者多行書寫,以分號結尾。
2、SQL語句可以使用空格/縮進來增強語句的可讀性 。
3、MySQL數據庫的SQL語句不區分大小寫。
4、注釋:
-
單行注釋:-- 注釋內容 或 # 注釋內容(MySQL特有)
-
多行注釋: /* 注釋內容 */
2.DDL
2.1 數據庫操作
我們在進行數據庫設計,需要使用到剛才所介紹SQL分類中的DDL語句。
DDL英文全稱是Data Definition Language(數據定義語言),用來定義數據庫對象(數據庫、表)。
DDL中數據庫的常見操作:查詢、創建、使用、刪除。
查詢當前數據庫:
查詢當前數據庫:
創建數據庫
create database [ if not exists ] 數據庫名 [default charset utf8mb4];
創建數據庫時,可以不指定字符集。 因為在MySQL8版本之后,默認的字符集就是 utf8mb4。
注意:在同一個數據庫服務器中,不能創建兩個名稱相同的數據庫,否則將會報錯。
可以使用if not exists來避免這個問題
-- 數據庫不存在,則創建該數據庫;如果存在則不創建
create database if not extists itcast;
使用數據庫
刪除數據庫
如果刪除一個不存在的數據庫,將會報錯。
可以加上參數 if exists ,如果數據庫存在,再執行刪除,否則不執行刪除。
說明:上述語法中的database,也可以替換成 schema
如:create schema db01;
如:show schemas;
2.2 圖形化工具
2.2.1 使用
1、打開IDEA自帶的Database
2、配置MySQL
3、輸入相關信息
4、下載MySQL連接驅動
5、測試數據庫連接
6、保存配置
默認情況下,連接上了MySQL數據庫之后, 數據庫并沒有全部展示出來。 需要選擇要展示哪些數據庫。具體操作如下:
創建數據庫
有了圖形化界面工具后,就可以方便的使用圖形化工具:創建數據庫,創建表、修改表等DDL操作。
其實工具底層也是通過DDL語句操作的數據庫,只不過這些SQL語句是圖形化界面工具幫我們自動完成的。
2.3 表操作
關于表結構的操作也是包含四個部分:創建表、查詢表、修改表、刪除表。
2.3.1 創建表
注意: [ ] 中的內容為可選參數; 最后一個字段后面沒有逗號
案例:創建tb_user表
create table tb_user (id int comment 'ID,唯一標識', # id是一行數據的唯一標識(不能重復)username varchar(20) comment '用戶名',name varchar(10) comment '姓名',age int comment '年齡',gender char(1) comment '性別'
) comment '用戶表';
數據表創建完成,接下來我們還需要測試一下是否可以往這張表結構當中來存儲數據。
雙擊打開tb_user表結構,大家會發現里面沒有數據:
添加數據:
此時我們再插入一條數據:
可是我們之前在comment中提到id是唯一標識,不能有重復值,可是當id相同時能正常提交,該如何解決?
想要限制字段所存儲的數據,就需要用到數據庫中的約束。
2.3.1.1約束
概念:所謂約束就是作用在表中字段上的規則,用于限制存儲在表中的數據。
作用:就是來保證數據庫當中數據的正確性、有效性和完整性。
約束 | 描述 | 關鍵字 |
---|---|---|
非空約束 | 限制該字段值不能為null | not null |
唯一約束 | 保證字段的所有數據都是唯一、不重復的 | unique |
主鍵約束 | 主鍵是一行數據的唯一標識,要求非空且唯一 | primary key (auto_increment自增) |
默認約束 | 保存數據時,如果未指定該字段值,則采用默認值 | default |
外鍵約束 | 讓兩張表的數據建立連接,保證數據的一致性和完整性 | foreign key |
注意:約束是作用于表中字段上的,可以在創建表/修改表的時候添加約束。
create table tb_user (id int primary key comment 'ID,唯一標識', username varchar(20) not null unique comment '用戶名',name varchar(10) not null comment '姓名',age int comment '年齡',gender char(1) default '男' comment '性別'
) comment '用戶表';
我們會發現id字段下存儲的值,如果由我們自己來維護會比較麻煩(必須保證值的唯一性)。MySQL數據庫為了解決這個問題,給我們提供了一個關鍵字:auto_increment(自增)
主鍵自增:auto_increment
每次插入新的行記錄時,數據庫自動生成id字段(主鍵)下的值
具有auto_increment的數據列是一個正數序列開始增長(從1開始自增)
create table tb_user (id int primary key auto_increment comment 'ID,唯一標識', #主鍵自動增長username varchar(20) not null unique comment '用戶名',name varchar(10) not null comment '姓名',age int comment '年齡',gender char(1) default '男' comment '性別'
) comment '用戶表';
注意:自增刪除之后id會從下一個刪除后的下一個數字繼續開始,并不會按照現有id進行排序。
2.3.1.2 數據類型
MySQL中的數據類型有很多,主要分為三類:數值類型、字符串類型、日期時間類型。
1). 數值類型
類型 | 大小 | 有符號(SIGNED)范圍 | 無符號(UNSIGNED)范圍 | 描述 |
---|---|---|---|---|
TINYINT | 1byte | (-128,127) | (0,255) | 小整數值 |
SMALLINT | 2bytes | (-32768,32767) | (0,65535) | 大整數值 |
MEDIUMINT | 3bytes | (-8388608,8388607) | (0,16777215) | 大整數值 |
INT/INTEGER | 4bytes | (-2147483648,2147483647) | (0,4294967295) | 大整數值 |
BIGINT | 8bytes | (-2^63,2^63-1) | (0,2^64-1) | 極大整數值 |
FLOAT | 4bytes | (-3.402823466 E+38,3.402823466351 E+38) | 0 和 (1.175494351 E-38,3.402823466 E+38) | 單精度浮點數值 |
DOUBLE | 8bytes | (-1.7976931348623157 E+308,1.7976931348623157 E+308) | 0 和 (2.2250738585072014 E-308,1.7976931348623157 E+308) | 雙精度浮點數值 |
DECIMAL | 依賴于M(精度)和D(標度)的值 | 依賴于M(精度)和D(標度)的值 |
示例:?
? ? 年齡字段 ---不會出現負數, 而且人的年齡不會太大
?? ?age tinyint unsigned
?? ?
?? ?分數 ---總分100分, 最多出現一位小數
?? ?score decimal(4,1)
2). 字符串類型
類型 | 大小 | 描述 |
---|---|---|
CHAR | 0-255 bytes | 定長字符串(需要指定長度) |
VARCHAR | 0-65535 bytes | 變長字符串(需要指定長度) |
TINYBLOB | 0-255 bytes | 不超過255個字符的二進制數據 |
TINYTEXT | 0-255 bytes | 短文本字符串 |
BLOB | 0-65 535 bytes | 二進制形式的長文本數據 |
TEXT | 0-65 535 bytes | 長文本數據 |
MEDIUMBLOB | 0-16 777 215 bytes | 二進制形式的中等長度文本數據 |
MEDIUMTEXT | 0-16 777 215 bytes | 中等長度文本數據 |
LONGBLOB | 0-4 294 967 295 bytes | 二進制形式的極大文本數據 |
LONGTEXT | 0-4 294 967 295 bytes | 極大文本數據 |
char 與 varchar 都可以描述字符串,char是定長字符串,指定長度多長,就占用多少個字符,和字段值的長度無關 。而varchar是變長字符串,指定的長度為最大占用長度 。相對來說,char的性能會更高些,但是會更浪費空間。
示例:?
? ? 用戶名 username ---長度不定, 最長不會超過50
?? ?username varchar(50)
?? ?
?? ?手機號 phone ---固定長度為11
?? ?phone char(11)
3). 日期時間類型
類型 | 大小 | 范圍 | 格式 | 描述 |
---|---|---|---|---|
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 | 混合日期和時間值,時間戳 |
示例:?
?? ?生日字段 ?birthday ---生日只需要年月日 ?
?? ?birthday date
?? ?
?? ?創建時間 createtime --- 需要精確到時分秒
?? ?createtime ?datetime
2.3.1.3 案例
1). 列表展示
2). 需求說明及字段限制
步驟:
-
閱讀產品原型及需求文檔,看看里面涉及到哪些字段。
-
查看需求文檔說明,確認各個字段的類型以及字段存儲數據的長度限制。
-
在頁面原型中描述的基礎字段的基礎上,再增加額外的基礎字段。
使用SQL創建表:
-- 案例(創建員工表)
create table emp(id int unsigned primary key auto_increment comment '主鍵id',username varchar(20) not null unique comment '用戶名',name varchar(10) not null comment '姓名',gender char(1) not null comment '性別',phone char(11) not null unique comment '手機號',job tinyint comment '職位:1-班主任,2-講師,3-學工主管,4-教研主管,5-咨詢師',salary float(7,2) comment '薪資',image varchar(100) comment '頭像',entrydate date comment '入職時間',create_time datetime not null comment '創建時間',update_time datetime not null comment '更新時間'
)comment '員工表';
2.3.2 DDL(表操作)
3.DML
DML英文全稱是Data Manipulation Language(數據操作語言),用來對數據庫中表的數據記錄進行增、刪、改操作。
-
添加數據(INSERT)
-
修改數據(UPDATE)
-
刪除數據(DELETE)
3.1 增加(insert)
案例1:向emp表的username, name, gender, phone, create_time, update_time字段插入數據
-- 因為設計表時create_time, update_time兩個字段不能為NULL,所以也做為要插入的字段
insert into emp(username, name, gender, phone, create_time, update_time)
values ('wuji', '張無忌', 1, '13309091231', now(), now());
案例2:向temp表的所有字段插入數據
insert into emp2(id, username, password, name, gender, phone, job, salary, image, entry_date, create_time, update_time)
values (1,'shinaian','123456','施耐庵',1,'13309090001',4,15000,'1.jpg','2000-01-01',now(),now()),
案例3:批量向emp表的username、name、gender字段插入數據
insert into emp(username, name, gender, phone, create_time, update_time)
values ('Tom1', '湯姆1', 1, '13309091231', now(), now()),('Tom2', '湯姆2', 1, '13309091232', now(), now());
Insert操作的注意事項:
插入數據時,指定的字段順序需要與值的順序是一一對應的。
字符串和日期型數據應該包含在引號中。
插入的數據大小,應該在字段的規定范圍內。
3.2 修改(update)
update語法:
update 表名 set 字段名1 = 值1 , 字段名2 = 值2 , .... [where 條件] ;
案例1:將emp表中id為1的員工,姓名name字段更新為'張三'
update emp set name='張三', update_time=now() where id=1;
案例2:將emp表的所有員工入職日期更新為'2010-01-01'
update emp set entry_date='2010-01-01', update_time=now();
注意事項:
修改語句的條件可以有,也可以沒有,如果沒有條件,則會修改整張表的所有數據。
在修改數據時,一般需要同時修改公共字段update_time,將其修改為當前操作時間。
3.3 刪除(delete)
delete語法:
delete from 表名 [where 條件] ;
案例1:刪除emp表中id為1的員工
delete from emp where id = 1;
案例2:刪除emp表中所有員工
delete from emp;
注意事項:
? DELETE 語句的條件可以有,也可以沒有,如果沒有條件,則會刪除整張表的所有數據。
? DELETE 語句不能刪除某一個字段的值(可以使用uptate,將該字段值置為null即可)。
? 當進行刪除全部數據操作時,會提示詢問是否確認刪除所有數據,直接點擊Execute即可。
4.DQL
4.1 語法
4.2 基本查詢
查詢所有員工的 name, entry_date,并起別名(姓名、入職日期)
-- 方式1:
select name AS 姓名, entry_date AS 入職日期 from emp;-- 方式2: 別名中有特殊字符時,使用''或""包含
select name AS '姓 名', entry_date AS '入職日期' from emp;-- 方式3:
select name AS "姓名", entry_date AS "入職日期" from emp;
-- 方式4:
select name 姓名, entry_date 入職日期 from emp;
注意:字段后面的as可以省略。
查詢已有的員工關聯了哪幾種職位(不要重復)
select distinct job from emp;
4.4 條件查詢
語法:
select 字段列表 from 表名 where 條件列表 ; -- 條件列表:意味著可以有多個條件
-- =================== DQL: 基本查詢 ======================
-- 1. 查詢指定字段 name,entry_date 并返回
select name, entry_date
from emp-- 2. 查詢返回所有字段(通配符寫法,不推薦)
select *
from emp;-- 3. 查詢所有員工的 name,entry_date, 并起別名(姓名、入職日期)
select name as 姓名, entry_date as 入職日期
from emp;select name 姓名, entry_date 入職日期
from emp;-- 4. 查詢已有的員工關聯了哪幾種職位(不要重復)
select distinct job
from emp;-- =================== DQL: 條件查詢 ======================
-- 1. 查詢 姓名 為 柴進 的員工
select *
from emp
where name = '柴進';-- 2. 查詢 薪資小于等于5000 的員工信息
select *
from emp
where salary <= 5000;-- 3. 查詢 沒有分配職位 的員工信息
select *
from emp
where job is null;-- 4. 查詢 有職位 的員工信息
select *
from emp
where job is not null;-- 5. 查詢 密碼不等于 '123456' 的員工信息
select *
from emp
where password != '123456';select *
from emp
where password <> '123456';-- 6. 查詢 入職日期 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之間的員工信息
select *
from emp
where entry_date between '2000-01-01' and '2010-01-01';
select *
from emp
where entry_date >= '2000-01-01'and entry_date <= '2010-01-01';-- 7. 查詢 入職時間 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之間 且 性別為女 的員工信息
select *
from emp
where entry_date between '2000-01-01' and '2010-01-01'and gender = 2;-- 8. 查詢 職位是 2 (講師), 3 (學工主管), 4 (教研主管) 的員工信息
select * from emp where job = 2 || job = 3 || job = 4;select * from emp where job = 2 or job = 3 or job = 4;select * from emp where job in (2, 3, 4);
-- 9. 查詢 姓名 為兩個字的員工信息
-- 模糊匹配like
-- _代表任意一個字符
-- %代表任意n個字符
select * from emp where name like '__';-- 10. 查詢 姓 '李' 的員工信息
select * from emp where name like '李%';-- 11. 查詢 姓名中包含 '二' 的員工信息
select * from emp where name like '%二%';
4.5 聚合函數
之前我們做的查詢都是橫向查詢,就是根據條件一行一行的進行判斷,而使用聚合函數查詢就是縱向查詢,它是對一列的值進行計算,然后返回一個結果值。(將一列數據作為一個整體,進行縱向計算)
select 聚合函數(字段列表) from 表名 ;
-- 聚合函數-- 1. 統計該企業員工數量 count
-- 括號里可以寫字段名、常量、*
select count(id) from emp;
select count(job) from emp; -- 29,因為有一條數據為null
-- 空值null不會參與所有聚合函數的運算select count(1) from emp;
select count(*) from emp; -- 推薦使用count(*),性能最好-- 2. 統計該企業員工的平均薪資 avg
select avg(salary) from emp;-- 3. 統計該企業員工的最低薪資 min
select min(salary) from emp;-- 4. 統計該企業員工的最高薪資 max
select max(salary) from emp;-- 5. 統計該企業每月要給員工發放的薪資總額(薪資之和) sum
select sum(salary) from emp;
4.6 分組查詢
-- 分組 只支持查詢分組字段以及聚合函數,其他字段沒有意義
-- 1. 根據性別分組 , 統計男性和女性員工的數量
select gender,count(*) from emp group by gender;-- 2. 先查詢入職時間在 '2015-01-01' (包含) 以前的員工 , 并對結果根據職位分組 , 獲取員工數量大于等于2的職位
select job,count(*) as cnt from emp where entry_date <= '2015-01-01' group by job having cnt >= 2;
4.7 排序查詢
-- =================== 排序查詢 ======================
-- 1. 根據入職時間, 對員工進行升序排序 asc默認升序
select * from emp order by entry_date asc;
select * from emp order by entry_date;-- 2. 根據入職時間, 對員工進行降序排序 --desc降序
select * from emp order by entry_date desc;-- 3. 根據 入職時間 對公司的員工進行 升序排序 , 入職時間相同 , 再按照 更新時間 進行降序排序
select * from emp order by entry_date asc, update_time desc;
4.8 分頁查詢
分頁操作在業務系統開發時,也是非常常見的一個功能,日常我們在網站中看到的各種各樣的分頁條,后臺也都需要借助于數據庫的分頁操作。
-- =================== 分頁查詢 ======================
-- 1. 從起始索引0開始查詢員工數據, 每頁展示5條記錄
select * from emp limit 0, 5;-- 2. 查詢 第1頁 員工數據, 每頁展示5條記錄
select * from emp limit 0, 5;
select * from emp limit 5;-- 3. 查詢 第2頁 員工數據, 每頁展示5條記錄
select * from emp limit 5, 5;-- 4. 查詢 第3頁 員工數據, 每頁展示5條記錄
select * from emp limit 10, 5;
注意事項:
起始索引從0開始。 計算公式 : 起始索引 = (查詢頁碼 - 1)* 每頁顯示記錄數
分頁查詢是數據庫的方言,不同的數據庫有不同的實現,MySQL中是LIMIT
如果查詢的是第一頁數據,起始索引可以省略,直接簡寫為 limit 條數