一 mysql 內(nèi)容介紹
1mysql1.數(shù)據(jù)庫,是當(dāng)前應(yīng)用非常廣泛的一款關(guān)系型數(shù)據(jù)庫
2 目前mysql在數(shù)據(jù)庫中的排名是第二,也是第一oracle(甲骨文)公司的產(chǎn)品。
3主要知識點包括:
a)數(shù)據(jù)庫與表的操作
b)數(shù)據(jù)的增加、修改、刪除
c)數(shù)據(jù)的查詢(重點)
d)與python交互
二 創(chuàng)建庫和表
1.主要知識點包括:能夠與mysql建立連接,創(chuàng)建數(shù)據(jù)庫、表,分別從圖形界面與腳本界面兩個方面講解
2.相關(guān)的知識點包括:E-R關(guān)系模型,數(shù)據(jù)庫的3范式,mysql中數(shù)據(jù)字段的類型,字段約束
3.數(shù)據(jù)庫的操作,包括創(chuàng)建、刪除
4.表的操作,包括創(chuàng)建、修改、刪除
5.數(shù)據(jù)的操作,包括增加、修改、刪除、查詢,簡稱crud
6.學(xué)生表結(jié)構(gòu):
a)id
b)名稱
c)性別
d)地址
e)生日
8.科目表結(jié)構(gòu):
a)id
名稱
1?數(shù)據(jù)庫簡介
人類在進化的過程中,創(chuàng)造了數(shù)字、文字、符號等來進行數(shù)據(jù)的記錄,但是承受著認知能力和創(chuàng)造能力的提升,數(shù)據(jù)量越來越大,對于數(shù)據(jù)的記錄和準確查找,成為了一個重大難題。
計算機誕生后,數(shù)據(jù)開始在計算機中存儲并計算,并設(shè)計出了數(shù)據(jù)庫系統(tǒng)數(shù)據(jù)庫系統(tǒng)解決的問題:持久化存儲,優(yōu)化讀寫,保證數(shù)據(jù)的有效性
當(dāng)前使用的數(shù)據(jù)庫,主要分為兩類
1.文檔型,如sqlite,就是一個文件,通過對文件的復(fù)制完成數(shù)據(jù)庫的復(fù)制
2.服務(wù)型,如mysql、oracle、postgre,數(shù)據(jù)存儲在一個物理文件中,但是需要使用終端以tcp/ip協(xié)議連接,進行數(shù)據(jù)庫的讀寫操作
E-R模型
當(dāng)前物理的數(shù)據(jù)庫都是按照E-R模型進行設(shè)計的
E(entry ) 實體
R( relationship) ?關(guān)系
一個實體轉(zhuǎn)換為數(shù)據(jù)庫中的一個表
關(guān)系描述兩個實體之間的對應(yīng)規(guī)則,包括
1一對一
現(xiàn)代的婚姻:一個男人娶一個女人,且一個女人只能價一個男人
2一對多
古代的婚姻,一個男人娶多個老婆,一個女人只能嫁一個男人
3多對多
不同教室可以被多個同學(xué)使用,同學(xué)可以使用多個教室
關(guān)系轉(zhuǎn)換為數(shù)據(jù)庫表中的一個列在關(guān)系型數(shù)據(jù)庫中一行就是一個對象
三范式
經(jīng)過研究和對使用中問題的總結(jié),對于設(shè)計數(shù)據(jù)庫提出了一些規(guī)范,這些規(guī)范被稱為范式
1.第一范式(1NF):列不可拆分
2.第二范式(2NF):唯一標識
3.第三范式(3NF):引用主鍵
說明:后一個范式,都是在前一個范式的基礎(chǔ)上建立的
2 數(shù)據(jù)完整性
一個數(shù)據(jù)庫就是一個完整的業(yè)務(wù)單元,可以包含多張表,數(shù)據(jù)被存儲在表中
在表中為了更加準確的存儲數(shù)據(jù),保證數(shù)據(jù)的正確有效,可以在創(chuàng)建表的時候,為表添加一些強制性的驗證,包括數(shù)據(jù)字段的類型、約束
字段類型
在mysql中包含的數(shù)據(jù)類型很多,這里主要列出來常用的幾種
1.數(shù)字:int,decimal
decimal(5,2)整數(shù)3位,小數(shù)2位
2.字符串:char,varchar,text
char:不根據(jù)內(nèi)容改變字符串長度
varchar:根據(jù)內(nèi)容改變字符串長度
字符=字節(jié)+編碼
char因為是定長,所以查詢效率高,浪費空間
varchar因為是邊長,所以節(jié)省空間,查詢效率相對低
3.日期:datetime
date:年月日
time:時分秒
datetime:年月日時分秒
4.布爾:bit
0或1
約束
1.主鍵primary key
2.非空not null
3.惟一unique
4.默認default
5.外鍵foreign key
三?使用圖形窗口連接
·windows下的navicat點擊“連接”彈出窗口,按照提示填寫連接信息,如下圖
·連接成功后,會在連接名稱下面顯示出當(dāng)前的數(shù)據(jù)庫
·雙擊選中數(shù)據(jù)庫,就可以編輯此數(shù)據(jù)庫
·下次再進入此軟件時,通過雙擊完成連接、編輯操作
數(shù)據(jù)庫操作
·在連接的名稱上右擊,選擇“新建數(shù)據(jù)庫”,彈出窗口,并按提示填寫
在數(shù)據(jù)庫上右擊,選擇“刪除數(shù)據(jù)庫”可以完成刪除操作
表操作
·當(dāng)數(shù)據(jù)庫顯示為高亮?xí)r,表示當(dāng)前操作此數(shù)據(jù)庫,可以在數(shù)據(jù)中創(chuàng)建表
·一個實體對應(yīng)一張表,用于存儲特定結(jié)構(gòu)的數(shù)據(jù)
·點擊“新建表”,彈出窗口,按提示填寫信息
·主鍵的名稱一般為id,設(shè)置為int型,無符號數(shù),自動增長,非空
·自動增長表示由mysql系統(tǒng)負責(zé)維護這個字段的值,不需要手動維護,所以不用關(guān)心這個字段的具體值
·字符串varchar類型需要設(shè)置長度,即最多包含多少個字符
·點擊“添加欄位”,可以添加一個新的字段
·點擊“保存”,為表定義名稱
數(shù)據(jù)操作
·表創(chuàng)建成功后,可以在右側(cè)看到,雙擊表打開新窗口,如下圖
·在此窗口中可以增加、修改、刪除數(shù)據(jù)
邏輯刪除
·對于重要數(shù)據(jù),并不希望物理刪除,一旦刪除,數(shù)據(jù)無法找回
·一般對于重要數(shù)據(jù),會設(shè)置一個isDelete的列,類型為bit,表示邏輯刪除
·大于大量增長的非重要數(shù)據(jù),可以進行物理刪除
·數(shù)據(jù)的重要性,要根據(jù)實際開發(fā)決定
四 腳本命令操作
sql語句分為兩大類:
1、dml對表的數(shù)據(jù)內(nèi)容進行增刪改查
2、ddl除了dml之外
·命令操作方式,在工作中使用的更多一些,所以要達到熟練的程度
·打開終端,運行命令
>mysql -uroot -p
·退出登錄
quit或exit
·登錄成功后,輸入如下命令查看效果
·注意:在語句結(jié)尾要使用分號;
遠程連接
·一般在公司開發(fā)中,可能會將數(shù)據(jù)庫統(tǒng)一搭建在一臺服務(wù)器上,所有開發(fā)人員共用一個數(shù)據(jù)庫,而不是在自己的電腦中配置一個數(shù)據(jù)庫
·運行命令
mysql -hip地址-uroot -p
·-h后面寫要連接的主機ip地址
·-u后面寫連接的用戶名
·-p回車后寫密碼
數(shù)據(jù)庫操作
·創(chuàng)建數(shù)據(jù)庫
create database數(shù)據(jù)庫名charset=utf8;
·刪除數(shù)據(jù)庫
drop database數(shù)據(jù)庫名;
·切換數(shù)據(jù)庫
use數(shù)據(jù)庫名;
·查看當(dāng)前選擇的數(shù)據(jù)庫
select database();
表操作
·查看當(dāng)前數(shù)據(jù)庫中所有表
show tables;
·創(chuàng)建表
auto_increment表示自動增長,只能是數(shù)字類型
主鍵本身是用來唯一標識這一行,沒有業(yè)務(wù)邏輯意義,所以是什么值不重要,只要唯一就行,所以如果是主鍵不需要修改
create table表名(列及類型);
如:
create table students(
id int auto_increment primary key,
sname varchar(10) not null
);
·修改表
alter table表名add|modify|drop列名類型;
如:
alter table students add birthday datetime;
·刪除表
drop table表名;
·查看表結(jié)構(gòu)
desc表名;
·更改表名稱
rename table原表名to新表名;
·查看表的創(chuàng)建語句
show create table '表名';
數(shù)據(jù)操作
·查詢
select * from表名
·增加
全列插入:insert into表名values(...)
缺省插入:insert into表名(列1,...) values(值1,...)
同時插入多條數(shù)據(jù):insert into表名values(...),(...)...;
或insert into表名(列1,...) values(值1,...),(值1,...)...;
·主鍵列是自動增長,但是在全列插入時需要占位,通常使用0,插入成功后以實際數(shù)據(jù)為準
·修改
update表名set列1=值1,... where條件
·刪除
delete from表名where條件
·邏輯刪除,本質(zhì)就是修改操作update
alter table students add isdelete bit default 0;
如果需要刪除則
update students isdelete=1 where ...;
五 查詢
內(nèi)容簡介
查詢的基本方法
select * from 表名;
·from關(guān)鍵字后面寫表名,表示數(shù)據(jù)來源于是這張表
·select后面寫表中的列名,如果是*表示在結(jié)果中顯示表中所有列
·在select后面的列名部分,可以使用as為列起別名,這個別名出現(xiàn)在結(jié)果集中
·如果要查詢多個列,之間使用逗號分隔
消除重復(fù)行
1 條件
使用where子句對表中的數(shù)據(jù)篩選,結(jié)果為true的行會出現(xiàn)在結(jié)果集中
語法如下
select * from 表名 where 條件;
1比較運算符
·等于=
·大于>
·大于等于>=
·小于<
·小于等于<=
·不等于!=或<>
·查詢編號大于3的學(xué)生
例子:
2 邏輯運算符
and,or,not
例1:選擇id小于10且isdelete=1的項
例2:選擇id<10或isdelete=0
3 模糊查找
·like
·%表示任意多個任意字符
·_表示一個任意字符
select * t_student2 where name like 'l%';
例:
4 范圍查詢
·in表示在一個非連續(xù)的范圍內(nèi)
例:查詢編號是1或3或8的學(xué)生
·between ... and ...表示在一個連續(xù)的范圍內(nèi)
·例:查詢學(xué)生是3至8的學(xué)生
5 空判斷
·注意:null與''是不同的
·判空is null·
查詢沒有填寫地址的學(xué)生
6 優(yōu)先級
·小括號,not,比較運算符,邏輯運算符
and比or先運算,如果同時出現(xiàn)并希望先算or,需要結(jié)合()使用
7 聚合
·為了快速得到統(tǒng)計數(shù)據(jù),提供了5個聚合函數(shù)
·1)count(*)表示計算總行數(shù),括號中寫星與列名,結(jié)果是相同的
如果所在列有null那么count(列名)比總行數(shù)小
2)max(列)表示求此列的最大值
3)·min(列)表示求此列的最小值
4)·sum(列)表示求此列的和
5)·avg(列)表示求此列的平均值
8 分組
select
from
where
group by
having
limit
·按照字段分組,表示此字段相同的數(shù)據(jù)會被放到一個組中
·分組后,只能查詢出相同的數(shù)據(jù)列,對于有差異的數(shù)據(jù)列無法出現(xiàn)在結(jié)果集中
·可以對分組后的數(shù)據(jù)進行統(tǒng)計,做聚合運算
1)·語法:
select列1,列2,聚合... from表名group by列1,列2,列3...
2)分組后的數(shù)據(jù)篩選
·語法:
select列1,列2,聚合... from表名
group by列1,列2,列3...
having列1,...聚合...
·having后面的條件運算符與where的相同
查詢男生總?cè)藬?shù)
對比where與having
·where是對from后面指定的表進行數(shù)據(jù)篩選,屬于對原始數(shù)據(jù)的篩選
·having是對group by的結(jié)果進行篩選
9 排序
·為了方便查看數(shù)據(jù),可以對數(shù)據(jù)進行排序
·語法:
select * from表名
order by列1 asc|desc,列2 asc|desc,...
選擇為被刪除的男生,按倒敘排列
10 分頁
·當(dāng)數(shù)據(jù)量過大時,在一頁中查看數(shù)據(jù)是一件非常麻煩的事情
·語法
select * from表名
limit?start,count
·從start開始,獲取count條數(shù)據(jù)
·start索引從0開始
示例:分頁
·已知:每頁顯示m條數(shù)據(jù),當(dāng)前顯示第n頁
·求總頁數(shù):此段邏輯后面會在python中實現(xiàn)
o查詢總條數(shù)p1
o使用p1除以m得到p2
o如果整除則p2為總數(shù)頁
o如果不整除則p2+1為總頁數(shù)
·求第n頁的數(shù)據(jù)
select * from students
where isdelete=0
limit (n-1)*m,m
例如:如果要求第5頁的數(shù)據(jù),每頁數(shù)據(jù)為10
則 limit 4*10,10
六 高級
1 關(guān)系
創(chuàng)建成績表scores,結(jié)構(gòu)如下
id
學(xué)生
科目
成績
思考:學(xué)生列應(yīng)該存什么信息呢?
答:學(xué)生列的數(shù)據(jù)不是在這里新建的,而應(yīng)該從學(xué)生表引用過來,關(guān)系也是一條數(shù)據(jù);根據(jù)范式要求應(yīng)該存儲學(xué)生的編號,而不是學(xué)生的姓名等其它信息,同理,科目表也是關(guān)系列,引用科目表中的數(shù)據(jù)。
外鍵
·思考:怎么保證關(guān)系列數(shù)據(jù)的有效性呢?任何整數(shù)都可以嗎?
·答:必須是學(xué)生表中id列存在的數(shù)據(jù),可以通過外鍵約束進行數(shù)據(jù)的有效性驗證
·為stuid添加外鍵約束
alter table scores add constraint stu_sco foreign key(stuid) references students(id);
·此時插入或者修改數(shù)據(jù)時,如果stuid的值在students表中不存在則會報錯
·在創(chuàng)建表時可以直接創(chuàng)建約束
create table scores(
id int primary key auto_increment,
stuid int,
subid int,
score decimal(5,2),
foreign key(stuid) references students(id),
foreign key(subid) references subjects(id)
);
外鍵的級聯(lián)操作
·在刪除students表的數(shù)據(jù)時,如果這個id值在scores中已經(jīng)存在,則會拋異常
·推薦使用邏輯刪除,還可以解決這個問題
·可以創(chuàng)建表時指定級聯(lián)操作,也可以在創(chuàng)建表后再修改外鍵的級聯(lián)操作
·語法
alter table scores add constraint stu_sco foreign key(stuid) references students(id) on delete cascade;
·級聯(lián)操作的類型包括:
?restrict(限制):默認值,拋異常
?cascade(級聯(lián)):如果主表的記錄刪掉,則從表中相關(guān)聯(lián)的記錄都將被刪除
?set null:將外鍵設(shè)置為空
?no action:什么都不做
2 連接查詢
·問:查詢每個學(xué)生每個科目的分數(shù)
·分析:學(xué)生姓名來源于students表,科目名稱來源于subjects,分數(shù)來源于scores表,怎么將3個表放到一起查詢,并將結(jié)果顯示在同一個結(jié)果集中呢?
·答:當(dāng)查詢結(jié)果來源于多張表時,需要使用連接查詢
·關(guān)鍵:找到表間的關(guān)系,當(dāng)前的關(guān)系是
?students表的id---scores表的stuid
?subjects表的id---scores表的subid
·則上面問題的答案是:
select students.sname,subjects.stitle,scores.score
from scores
inner join students on scores.stuid=students.id
inner join subjects on scores.subid=subjects.id;
·結(jié)論:當(dāng)需要對有關(guān)系的多張表進行查詢時,需要使用連接join
·連接查詢分類如下:
?表A inner join表B:表A與表B匹配的行會出現(xiàn)在結(jié)果中
?表A left join表B:表A與表B匹配的行會出現(xiàn)在結(jié)果中,外加表A中獨有的數(shù)據(jù),未對應(yīng)的數(shù)據(jù)使用null填充
?表A right join表B:表A與表B匹配的行會出現(xiàn)在結(jié)果中,外加表B中獨有的數(shù)據(jù),未對應(yīng)的數(shù)據(jù)使用null填充
·在查詢或條件中推薦使用“表名.列名”的語法
·如果多個表中列名不重復(fù)可以省略“表名.”部分
·如果表的名稱太長,可以在表名后面使用' as簡寫名'或'簡寫名',為表起個臨時的簡寫名稱
3 自關(guān)聯(lián)
·設(shè)計省信息的表結(jié)構(gòu)provinces
?id
?ptitle
·設(shè)計市信息的表結(jié)構(gòu)citys
?id
?ctitle
?proid
·citys表的proid表示城市所屬的省,對應(yīng)著provinces表的id值
·問題:能不能將兩個表合成一張表呢?
·思考:觀察兩張表發(fā)現(xiàn),citys表比provinces表多一個列proid,其它列的類型都是一樣的
·意義:存儲的都是地區(qū)信息,而且每種信息的數(shù)據(jù)量有限,沒必要增加一個新表,或者將來還要存儲區(qū)、鄉(xiāng)鎮(zhèn)信息,都增加新表的開銷太大
·答案:定義表areas,結(jié)構(gòu)如下
?id
?atitle
?pid
·因為省沒有所屬的省份,所以可以填寫為null
·城市所屬的省份pid,填寫省所對應(yīng)的編號id
·這就是自關(guān)聯(lián),表中的某一列,關(guān)聯(lián)了這個表中的另外一列,但是它們的業(yè)務(wù)邏輯含義是不一樣的,城市信息的pid引用的是省信息的id
·在這個表中,結(jié)構(gòu)不變,可以添加區(qū)縣、鄉(xiāng)鎮(zhèn)街道、村社區(qū)等信息
·創(chuàng)建areas表的語句如下:
create table areas(
id int primary key,
atitle varchar(20),
pid int,
foreign key(pid) references areas(id)
);
·從sql文件中導(dǎo)入數(shù)據(jù)
source areas.sql;
·查詢一共有多少個省
·查詢省的名稱為“山西省”的所有城市
select city.* from areas as city
inner join areas as province on city.pid=province.id
where province.atitle='山西省';
·查詢市的名稱為“廣州市”的所有區(qū)縣
select dis.*,dis2.* from areas as dis
inner join areas as city on city.id=dis.pid
left join areas as dis2 on dis.id=dis2.pid
where city.atitle='廣州市';
4 子查詢
·查詢支持嵌套使用
·查詢各學(xué)生的語文、數(shù)學(xué)、英語的成績
select sname,
(select sco.score from scores sco inner join subjects sub on sco.subid=sub.id where sub.stitle='語文' and stuid=stu.id) as語文,
(select sco.score from ?scores sco inner join subjects sub on sco.subid=sub.id where sub.stitle='數(shù)學(xué)' and stuid=stu.id) as數(shù)學(xué),
(select sco.score from ?scores sco inner join subjects sub on sco.subid=sub.id where sub.stitle='英語' and stuid=stu.id) as英語
from students stu;
2 內(nèi)置函數(shù)
1 字符串函數(shù)
·查看字符的ascii碼值ascii(str),str是空串時返回0
查看ascii碼值對應(yīng)的字符char(數(shù)字)
·拼接字符串concat(str1,str2...)
select concat(12,34,'ab');
·包含字符個數(shù)length(str)
select length('abc');
·截取字符串
?left(str,len)返回字符串str的左端len個字符
?right(str,len)返回字符串str的右端len個字符
?substring(str,pos,len)返回字符串str的位置pos起len個字符
select substring('abc123',2,3);
·去除空格
?ltrim(str)返回刪除了左空格的字符串str
?rtrim(str)返回刪除了右空格的字符串str
?trim([方向remstr from str)返回從某側(cè)刪除remstr后的字符串str,方向詞包括both、leading、trailing,表示兩側(cè)、左、右
select trim(' ?bar ??');
select trim(leading 'x' FROM 'xxxbarxxx');
select trim(both 'x' FROM 'xxxbarxxx');
select trim(trailing 'x' FROM 'xxxbarxxx');
·返回由n個空格字符組成的一個字符串space(n)
select space(10);
·替換字符串replace(str,from_str,to_str)
select replace('abc123','123','def');
·大小寫轉(zhuǎn)換,函數(shù)如下
?lower(str)
?upper(str)
select lower('aBcD');
select upper('aBcD');
2數(shù)學(xué)函數(shù)
·求絕對值abs(n)
select abs(-32);
·求m除以n的余數(shù)mod(m,n),同運算符%
select mod(10,3);
select 10%3;
·地板floor(n),表示不大于n的最大整數(shù)
select floor(2.3);
·天花板ceiling(n),表示不小于n的最大整數(shù)
select ceiling(2.3);
·求四舍五入值round(n,d),n表示原數(shù),d表示小數(shù)位置,默認為0
select round(1.6);
·求x的y次冪pow(x,y)
select pow(2,3);
·獲取圓周率PI()
select PI();
·隨機數(shù)rand(),值為0-1.0的浮點數(shù)
select rand();
·還有其它很多三角函數(shù),使用時可以查詢文檔