MySQL高級使用

  • 實體與實體之間有3種對應(yīng)關(guān)系孙援,這些關(guān)系也需要存儲下來
  • 在開發(fā)中需要對存儲的數(shù)據(jù)進行一些處理谱煤,用到內(nèi)置的一些函數(shù)
  • 視圖用于完成查詢語句的封裝
  • 事務(wù)可以保證復雜的增刪改操作有效

先看個問題

問:查詢每個學生每個科目的分數(shù)
分析:學生姓名來源于students表,科目名稱來源于subjects倦踢,分數(shù)來源于scores表,怎么將3個表放到一起查詢,并將結(jié)果顯示在同一個結(jié)果集中呢癌淮?
答:當查詢結(jié)果來源于多張表時,需要使用連接查詢
關(guān)鍵:找到表間的關(guān)系沦补,當前的關(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é)論:當需要對有關(guān)系的多張表進行查詢時乳蓄,需要使用連接join

關(guān)系

  • 創(chuàng)建成績表scores,結(jié)構(gòu)如下

    • id
    • 學生
    • 科目
    • 成績
  • 思考:學生列應(yīng)該存什么信息呢夕膀?

  • 答:學生列的數(shù)據(jù)不是在這里新建的虚倒,而應(yīng)該從學生表引用過來美侦,關(guān)系也是一條數(shù)據(jù);根據(jù)范式要求應(yīng)該存儲學生的編號魂奥,而不是學生的姓名等其它信息

  • 同理菠剩,科目表也是關(guān)系列,引用科目表中的數(shù)據(jù)

關(guān)系表
  • 創(chuàng)建表的語句如下
create table scores(
id int primary key auto_increment,
stuid int,
subid int,
score decimal(5,2)
);

外鍵

  • 思考:怎么保證關(guān)系列數(shù)據(jù)的有效性呢耻煤?任何整數(shù)都可以嗎具壮?
  • 答:必須是學生表中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:什么都不做

連接查詢

連接查詢分類如下:
表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填充
在查詢或條件中推薦使用“表名.列名”的語法
如果多個表中列名不重復可以省略“表名.”部分
如果表的名稱太長,可以在表名后面使用' as 簡寫名'或' 簡寫名'诵姜,為表起個臨時的簡寫名稱

練習

  • 查詢學生的姓名汽煮、平均分

select students.sname,avg(scores.score)
from scores
inner join students on scores.stuid=students.id
group by students.sname;

  • 查詢男生的姓名、總分

select students.sname,avg(scores.score)
from scores
inner join students on scores.stuid=students.id
where students.gender=1
group by students.sname;

  • 查詢科目的名稱棚唆、平均分

select subjects.stitle,avg(scores.score)
from scores
inner join subjects on scores.subid=subjects.id
group by subjects.stitle;

  • 查詢未刪除科目的名稱暇赤、最高分、平均分

select subjects.stitle,avg(scores.score),max(scores.score)
from scores
inner join subjects on scores.subid=subjects.id
where subjects.isdelete=0
group by subjects.stitle;

字符串函數(shù)

  • 查看字符的ascii碼值ascii(str)宵凌,str是空串時返回0

select ascii('a');

  • 查看ascii碼值對應(yīng)的字符char(數(shù)字)

select char(97);

  • 拼接字符串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');

  • 數(shù)學函數(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ù)始锚,使用時可以查詢文檔
  • 日期時間函數(shù)
  • 獲取子值,語法如下
    • year(date)返回date的年份(范圍在1000到9999)
    • month(date)返回date中的月份數(shù)值
    • day(date)返回date中的日期數(shù)值
    • hour(time)返回time的小時數(shù)(范圍是0到23)
    • minute(time)返回time的分鐘數(shù)(范圍是0到59)
    • second(time)返回time的秒數(shù)(范圍是0到59)
  • select year('2016-12-21');
  • 日期計算,使用+-運算符肌似,數(shù)字后面的關(guān)鍵字為year义黎、month、day姐呐、hour殿怜、minute、second
    select '2016-12-21'+interval 1 day;
  • 日期格式化date_format(date,format)曙砂,format參數(shù)可用的值如下
    • 獲取年%Y头谜,返回4位的整數(shù)
    • 獲取年%y,返回2位的整數(shù)
    • 獲取月%m鸠澈,值為1-12的整數(shù)
  • 獲取日%d柱告,返回整數(shù)
    • 獲取時%H,值為0-23的整數(shù)
    • 獲取時%h笑陈,值為1-12的整數(shù)
    • 獲取分%i际度,值為0-59的整數(shù)
    • 獲取秒%s,值為0-59的整數(shù)

select date_format('2016-12-21','%Y %m %d');

  • 當前日期current_date()

select current_date();

  • 當前時間current_time()

select current_time();

  • 當前日期時間now()

select now();

視圖

  • 對于復雜的查詢涵妥,在多次使用后乖菱,維護是一件非常麻煩的事情
  • 解決:定義視圖
  • 視圖本質(zhì)就是對查詢的一個封裝

定義視圖
create view stuscore as
select students.*,scores.score from scores
inner join students on scores.stuid=students.id;
視圖的用途就是查詢
select * from stuscore;

子查詢

  • 查詢支持嵌套使用
  • 查詢各學生的語文、數(shù)學蓬网、英語的成績

select sname,
(select score from scores
inner join subjects sub on sco.subid=sub.id
where sub.stitle='語文' and stuid=stu.id) as 語文,
(select score from scores
inner join subjects sub on sco.subid=sub.id
where sub.stitle='數(shù)學' and stuid=stu.id) as 數(shù)學,
(select score from scores
inner join subjects sub on sco.subid=sub.id
where sub.stitle='英語' and stuid=stu.id) as 英語
from students;

事務(wù)

  • 當一個業(yè)務(wù)邏輯需要多個sql完成時窒所,如果其中某條sql語句出錯,則希望整個操作都退回

  • 使用事務(wù)可以完成退回的功能帆锋,保證業(yè)務(wù)邏輯的正確性
    事務(wù)四大特性(簡稱ACID)

  • 原子性(Atomicity):事務(wù)中的全部操作在數(shù)據(jù)庫中是不可分割的吵取,要么全部完成,要么均不執(zhí)行

  • 一致性(Consistency):幾個并行執(zhí)行的事務(wù)窟坐,其執(zhí)行結(jié)果必須與按某一順序串行執(zhí)行的結(jié)果相一致

  • 隔離性(Isolation):事務(wù)的執(zhí)行不受其他事務(wù)的干擾海渊,事務(wù)執(zhí)行的中間結(jié)果對其他事務(wù)必須是透明的

  • 持久性(Durability):對于任意已提交事務(wù),系統(tǒng)必須保證該事務(wù)對數(shù)據(jù)庫的改變不被丟失哲鸳,即使數(shù)據(jù)庫出現(xiàn)故障

  • 要求:表的類型必須是innodb或bdb類型臣疑,才可以對此表使用事務(wù)

  • 查看表的創(chuàng)建語句

show create table students;

  • 修改表的類型

alter table '表名' engine=innodb;

事務(wù)語句

  • 開啟begin;
  • 提交commit;
  • 回滾rollback;

示例1

  • 步驟1:打開兩個終端,連接mysql徙菠,使用同一個數(shù)據(jù)庫讯沈,操作同一張表
    終端1:
    select * from students;

終端2:
begin;
insert into students(sname) values('張飛');

  • 步驟2
    終端1:
    select * from students;
  • 步驟3
    終端2:
    commit;

終端1:
select * from students;
示例2
步驟1:打開兩個終端,連接mysql,使用同一個數(shù)據(jù)庫缺狠,操作同一張表
終端1:
select * from students;


終端2:
begin;
insert into students(sname) values('張飛');
步驟2
終端1:
select * from students;

  • 步驟3
    終端2:
    rollback;

終端1:
select * from students;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末问慎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挤茄,更是在濱河造成了極大的恐慌如叼,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件穷劈,死亡現(xiàn)場離奇詭異笼恰,居然都是意外死亡,警方通過查閱死者的電腦和手機歇终,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門社证,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人评凝,你說我怎么就攤上這事追葡。” “怎么了奕短?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵宜肉,是天一觀的道長。 經(jīng)常有香客問我篡诽,道長崖飘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任杈女,我火速辦了婚禮朱浴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘达椰。我一直安慰自己翰蠢,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布啰劲。 她就那樣靜靜地躺著梁沧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蝇裤。 梳的紋絲不亂的頭發(fā)上廷支,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音栓辜,去河邊找鬼恋拍。 笑死,一個胖子當著我的面吹牛藕甩,可吹牛的內(nèi)容都是我干的施敢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼僵娃!你這毒婦竟也來了概作?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤默怨,失蹤者是張志新(化名)和其女友劉穎讯榕,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體先壕,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡瘩扼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了垃僚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡规辱,死狀恐怖谆棺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情罕袋,我是刑警寧澤改淑,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站浴讯,受9級特大地震影響朵夏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜榆纽,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一仰猖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奈籽,春花似錦饥侵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至狼忱,卻和暖如春膨疏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钻弄。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工佃却, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人斧蜕。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓双霍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子洒闸,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容