MySQL基础学习特殊篇 入门限定
相信看了一會(huì)第十三章 MySQL數(shù)據(jù)庫(kù)的你一定一頭霧水把?太抽象了也沒(méi)有什么詳細(xì)的學(xué)習(xí),根本無(wú)從下手,這篇特殊的文章照顧了一下零基礎(chǔ)的小伙伴,也是純實(shí)機(jī)演示。
本文章參照了 尚硅谷MySQL基礎(chǔ)學(xué)習(xí)視頻教學(xué)!
安裝數(shù)據(jù)庫(kù)的步驟還是非常簡(jiǎn)單的,只要網(wǎng)速好去官方下載msi的安裝包既可。
安裝過(guò)程比較簡(jiǎn)單,這邊設(shè)置不建議復(fù)雜,因?yàn)閷W(xué)習(xí)初期的階段。
安裝完畢后如何打開(kāi)數(shù)據(jù)庫(kù)
#sql專(zhuān)用代碼欄 #打開(kāi)數(shù)據(jù)庫(kù)的方法其實(shí)很多我們挑選一種常用既可 #首先先大概介紹一下登入的關(guān)鍵字 # mysql[數(shù)據(jù)庫(kù)] -u[用戶名] -h[主機(jī)名] -P[端口] -p[密碼] mysql -h localhost -u root -P 3306 -p #這里mysql指定了數(shù)據(jù)庫(kù) #-h localhost 表示輸入主機(jī)名 localhost代表本地的意思 #-u root 代表用戶名 默認(rèn)用戶名為 root #-P 3306 端口 端口默認(rèn)為3306 #-p 密碼 輸入完回車(chē)會(huì)要求輸入密碼 Enter password:我們看執(zhí)行詳細(xì)流程。
首先按下電腦快捷鍵 win+R 調(diào)出運(yùn)行并輸入 'cmd’打開(kāi)命令提示符,顯示窗口后輸入:
回車(chē)后會(huì)要求輸入密碼,輸入完密碼看到如圖的內(nèi)容代表成功進(jìn)入數(shù)據(jù)庫(kù)。
MySQL常見(jiàn)命令
#顯示數(shù)據(jù)庫(kù) show databases; #打開(kāi)/進(jìn)入 指定的數(shù)據(jù)庫(kù) use mysql; #顯示當(dāng)前數(shù)據(jù)庫(kù)所有的表 show table;
如果沒(méi)有表格會(huì)提示如下信息。
上面的數(shù)據(jù)庫(kù)比如:
這些都是系統(tǒng)的數(shù)據(jù)庫(kù)并不推薦在里面做練習(xí)或者修改數(shù)據(jù),所以我們通過(guò)如下代碼創(chuàng)建一個(gè)空的數(shù)據(jù)庫(kù)進(jìn)行學(xué)習(xí):
我們學(xué)習(xí)了打開(kāi)數(shù)據(jù)庫(kù)、創(chuàng)建數(shù)據(jù)庫(kù)、顯示數(shù)據(jù)庫(kù)里的表格等基本指令,現(xiàn)在我們組合這些操作一口氣創(chuàng)建一個(gè)表。
這里就完成了一個(gè)最簡(jiǎn)單的完整流程操作,繼續(xù)看基本指令的學(xué)習(xí):
Field代表字段、Type代表類(lèi)型,后面代表的是一些其他的約束,先不看這些。
這里表現(xiàn)的為沒(méi)有數(shù)據(jù)的結(jié)果,因?yàn)橹皇莿?chuàng)建了表的字段沒(méi)有賦值。
這時(shí)候我們?cè)俅问褂蔑@示數(shù)據(jù)的指令來(lái)訪問(wèn)數(shù)據(jù)。
可以看到如上的手動(dòng)添加的內(nèi)容。
通過(guò)小鍵盤(pán)的 上鍵 ↑來(lái)調(diào)用上次指令記憶,找到插入數(shù)據(jù)的代碼再次添加一條數(shù)據(jù)。
不小心添加了重復(fù)的數(shù)據(jù)?看如下操作
如果多添加了并且不想要的時(shí)候,通過(guò)如下代碼刪除:
我們看客戶端外查看的效果:
MySQL常見(jiàn)命令總結(jié)
我們現(xiàn)在登入方式改為:
mysql -u root -pMySQL的語(yǔ)法規(guī)范
不分區(qū)大寫(xiě)小,但建議關(guān)鍵字大寫(xiě),表名和列名小寫(xiě)
show databases; SHOW DATABASES;
最好每條命令以分號(hào)結(jié)尾
每條命令根據(jù)需要,可以進(jìn)行縮進(jìn)或換行
注釋
好,上面就是我們?nèi)腴T(mén)第十三章的小練習(xí),也是作為基礎(chǔ)鋪墊的內(nèi)容,接下來(lái)開(kāi)始嘗試學(xué)習(xí)文章里的MySQL內(nèi)容!
創(chuàng)建表
#注意這里test后面的一定是()圓括號(hào)不要是大括號(hào) create table test(#整形通用inttest_id int,#小數(shù)點(diǎn)數(shù)test_price decimal,#普通長(zhǎng)度文本,使用default 指定默認(rèn)值test_name varchar(255) default 'xxx',#大文本類(lèi)型test_desc text,#圖片test_img blob,test_date datetime);使用子查詢語(yǔ)句建表
#語(yǔ)法: create table [模式名.]表名[column[,column...]] as subquery; #創(chuàng)建hehe數(shù)據(jù)表,該數(shù)據(jù)表和test完全相同,數(shù)據(jù)也完全相同 create table hehe as select*from test;修改表結(jié)構(gòu)的語(yǔ)法
alter table 表名 add(#可以有多個(gè)列定義column_name1 datatype [default expr],... );上面語(yǔ)法格式中的圓括號(hào)部分與建表語(yǔ)法的圓括號(hào)部分完全相同,只是此時(shí)圓括號(hào)里的列定義是追加到已有表的列定義后面。還有一點(diǎn)需要指出,如果只是新增一列,則可以省略圓括號(hào),僅在add后緊跟一個(gè)列定義既可。為數(shù)據(jù)表增加字段的SQL語(yǔ)句如下:
上面第二條SQL語(yǔ)句增加aaa字段時(shí),為該字段指定默認(rèn)值為’xxx’,值得指出的是,SQL語(yǔ)句中的字符串值不是用雙引號(hào)引起的,而是用單引號(hào)引起的。
修改列定義的語(yǔ)法
alter table 表名 modify column_name datatype[default expr][first|after col_name];上面語(yǔ)法中first或者after col_name指定需要將目標(biāo)修改到指定位置。
修改前的hehe_id列
代碼執(zhí)行
修改bbb列前
修改后
從上面代碼中不難看出,使用SQL修改數(shù)據(jù)表里列定義的語(yǔ)法和為數(shù)據(jù)表里增加一個(gè)列定義的語(yǔ)法幾乎完全一樣,關(guān)鍵是增加列定義所使用的add關(guān)鍵字,而修改列定義使用modify(修改)關(guān)鍵字(alter直譯為 改變)。還有一點(diǎn)需要指出,add新增的列名必須是源表表中不存在的,而modify修改的列名必須是原表中已存在的。
MySQL的一個(gè)modify命令不支持修改多個(gè)列定義,其他數(shù)據(jù)庫(kù)支持,比如Oracle支持一個(gè)modify命令修改多個(gè)列,一個(gè)modify命令修改多個(gè)列定義的語(yǔ)法和一個(gè)add命令增加多個(gè)列定義的語(yǔ)法非常相似,也是需要使用圓括號(hào)將多個(gè)列定義括起來(lái)。如果需要修改多行列定義,只需要在alter table后使用多個(gè)modify命令即可。
刪除列
從數(shù)據(jù)表中刪除列的語(yǔ)法比較簡(jiǎn)單。
alter table 表名 drop column_name刪除列只要在drop后竟跟需要?jiǎng)h除的列名即可。例如:
#刪除hehe表中的aaa字段 alter table hehe drop aaa;
重命名數(shù)據(jù)表
重命名數(shù)據(jù)表的語(yǔ)法格式如下:
alter table 表名 rename to 新表名 #將hehe數(shù)據(jù)表重命名為wawa: alter table hehe rename to wawa;MySQL為alter table提供了change選項(xiàng),該選項(xiàng)可以改變列名。change選項(xiàng)的語(yǔ)法格式如下:
alter table 表名 change old+column_name new_cloumn_name type[default expr] [first[after col_name]]通過(guò)對(duì)比不難發(fā)現(xiàn) change和modify兩個(gè)選項(xiàng):change選項(xiàng)比modify選項(xiàng)多了一個(gè)列名,因?yàn)閏hange可以改變列名,所以它需要兩個(gè)列名。一般而言,如果不需要改變列名使用alter table 的 modify 選項(xiàng)即可,只有當(dāng)需要修改列名時(shí)才會(huì)使用change選項(xiàng)。語(yǔ)句如下:
像這種不小心使用 insert into 插入了新數(shù)據(jù)的情況下就應(yīng)該將其多余的內(nèi)容刪除掉。
通過(guò)如下操作刪除
刪除表的語(yǔ)法
刪除表的語(yǔ)法格式如下:
drop table 表名;如下SQL語(yǔ)句將會(huì)把數(shù)據(jù)庫(kù)中已有的表刪除:
#刪除數(shù)據(jù)表 drop table wawa;先看處理上面的語(yǔ)句
#刪除數(shù)據(jù)表的數(shù)據(jù) delete from wawa;
試了實(shí)驗(yàn)上面的drop語(yǔ)法 我們?cè)俅渭尤胄碌臄?shù)據(jù)
現(xiàn)在我們?cè)囋嚿厦娴?drop table wawa;
這里直接刪除了wawa數(shù)據(jù)表,而非刪除里面的數(shù)據(jù)列。
關(guān)于drop和delete的區(qū)別
上面的結(jié)果差距很大
看例子
delete : delete from 表名 where 條件
delete選中指定表的內(nèi)容刪除,刪除的是數(shù)據(jù)
drop : alter table 表名 drop 字段 drop table 表
drop刪除的是表
相當(dāng)于drop直接刪除了表,釋放了內(nèi)存,所以drop速度大于delete,所以使用drop也一定要慎重,雖然可以恢復(fù)但是很麻煩,使用delete也一定要帶上where子句。
刪除數(shù)據(jù)表的效果如下:
- 表結(jié)構(gòu)被刪除,表對(duì)象不再存在
- 表里的所有數(shù)據(jù)也被刪除
- 該表所有相關(guān)索引、約束也被刪除
truncate表
對(duì)于大部分?jǐn)?shù)據(jù)庫(kù)而言,truncate都被當(dāng)成DDL處理(和drop一列),truncate被稱(chēng)為“截?cái)唷蹦硞€(gè)表——它的作用是刪除該表里全部數(shù)據(jù),但保留表結(jié)構(gòu),相對(duì)于DML里的delete命令而言,truncate的速度要快的多,而且truncate不像delete可以刪除指定的記錄,truncate只能一次性刪除整個(gè)表的全部記錄。
truncate命令的語(yǔ)法如下:
這里做實(shí)驗(yàn)也很簡(jiǎn)單,我們?cè)俅蝿?chuàng)建wawa表
#這里起碼要在 test表里 show tables; use test; select database(); #這里表列我們就不搞那么復(fù)雜了 create table wawa(id int,name varchar(255)); desc wawa; #插入一列數(shù)據(jù) insert into wawa (id,name) values(1,'洛天依'); select*from wawa; truncate wawa; show tables; desc wawa;
MySQL對(duì)truncate的處理比較特殊——如果使用非InnoDB存儲(chǔ)機(jī)制,truncate比delete速度要快;如果使用InnoDB存儲(chǔ)機(jī)制,在MySQL5.0.3之前,truncate和delete完全一樣,在5.0.3之后,truncate table比delete效率高,但如果該表被建外約束所參照,truncate又變?yōu)閐elete操作。在5.0.13之后,快速truncate總是可用,即比delete性能要好。
數(shù)據(jù)庫(kù)約束
約束更好保證了數(shù)據(jù)表里數(shù)據(jù)的完整性。約束時(shí)在表上強(qiáng)行執(zhí)行的數(shù)據(jù)校驗(yàn)規(guī)則,約束主要還用于保證數(shù)據(jù)的完整性。除此之外,當(dāng)表中數(shù)據(jù)存在互相依賴性時(shí),可以保護(hù)相關(guān)的數(shù)據(jù)不被刪除。
大部分?jǐn)?shù)據(jù)庫(kù)支持下面5種完整性約束。
- NOT NULL:非空約束,指定某列不能為空。
- UNIQUE:唯一約束,指定某列或者幾列組合不能重復(fù)。
- PRIMARY KEY:主鍵,指定該列的值可以唯一地標(biāo)識(shí)該條記錄。
- FOREIGN KEY:外鍵,指定該行記錄從屬于主表中的一條記錄,主要用于保證參照完整性。
- CHECK:檢查,指定一個(gè)布爾表達(dá)施,用于指定對(duì)應(yīng)列的值必須滿足該表達(dá)式。
雖然大部分?jǐn)?shù)據(jù)庫(kù)都支持上面5種約束,但MySQL不支持CHECK約束,雖然MySQL的SQL語(yǔ)句也可以使用CHECK約束,但這個(gè)CHECK約束不會(huì)有任何作用。
雖然約束的作用只是保證數(shù)據(jù)表里數(shù)據(jù)的完整性,但約束也是數(shù)據(jù)庫(kù)對(duì)象,被存儲(chǔ)在系統(tǒng)表中,也擁有自己的名字。根據(jù)約束對(duì)數(shù)據(jù)列的限制,約束分為如下兩類(lèi)。
- 單列約束:每個(gè)約束只約束一列。
- 多列約束:每個(gè)約束可以約束多個(gè)數(shù)據(jù)列。
為數(shù)據(jù)表指定約束有如下兩個(gè)時(shí)機(jī):
- 建表的同時(shí)為相應(yīng)的數(shù)據(jù)列指定約束。
- 建表后創(chuàng)建,以修改表的方式來(lái)增加約束。
大部分約束都可以采用列級(jí)約束語(yǔ)法或者表級(jí)約束語(yǔ)法。下面依次介紹5種約束的建立和刪除(約束通常無(wú)法修改)。
MySQL使用information_schema數(shù)據(jù)庫(kù)里的TABLE_CONSTRAINTS表來(lái)保存該數(shù)據(jù)庫(kù)實(shí)例中所有的約束信息,用戶可以通過(guò)查詢TABLE_CONSTRAINTS來(lái)獲取該數(shù)據(jù)庫(kù)的約束信息。
1.NOT NULL約束
非口約束用于確保指定列不允許為空,非空約束是比較特殊的約束,它只能作為列級(jí)約束使用,只能使用列級(jí)約束語(yǔ)法定義。這里要介紹一下SQL中的null值,SQL的null不區(qū)分大小寫(xiě)。SQL中的null具有如下特征。
- 所有數(shù)據(jù)類(lèi)型的值都可以是null,包括int、float、boolean等數(shù)據(jù)類(lèi)型。
- 與Java類(lèi)似的是,空字符串不等于null,0也不等于null。
如果需要在建表時(shí)為指定列指定非空約束,只要在列定義后面增加 not null即可。建表語(yǔ)句如下:
#如果是跟著我的文章走的,那現(xiàn)在test表中肯定有個(gè)wawa,現(xiàn)在我們給它刪掉 #刪掉wawa表和test表 drop table test; drop table wawa; #使用函數(shù)來(lái)確定自己是否處于test數(shù)據(jù)庫(kù) select database(); create table hehe(#建立了非空約束,這意味著hehe_id不可以為nulhehe_id int not null,#MySQL的非空約束不能指定名字hehe_name varchar(255) default 'xyz' not null,#下面可以為空,默認(rèn)就是為空hehe_gender varchar(2) null);
除此之外,也可以在使用alter table 修改表時(shí)增加或刪除非空約束,SQL命令如下:
最終結(jié)果
UNIQUE約束
唯一約束用于保證指定列或指定列組合不允許出現(xiàn)重復(fù)值。雖然唯一約束的列不可以出現(xiàn)重復(fù)值,但可以出現(xiàn)多個(gè)null值(因?yàn)樵跀?shù)據(jù)庫(kù)中null不等于null)。
一個(gè)表內(nèi)可創(chuàng)建多個(gè)唯一約束,當(dāng)為某列創(chuàng)建唯一約束時(shí),MySQL會(huì)為該列相應(yīng)的創(chuàng)建唯一索引,如果不給唯一索引起名,則該唯一約束默認(rèn)與列名相同。
當(dāng)建立唯一約束時(shí),MySQL在唯一約束所在列或列組合上建立對(duì)應(yīng)的唯一索引。
使用列級(jí)約束語(yǔ)法建立唯一約束非常簡(jiǎn)單,只要簡(jiǎn)單地在列定義后增加unique關(guān)鍵字即可。SQL語(yǔ)句如下:
如果需要為多列組合建立唯一約束,或者向自行指定約束名,則需要使用表級(jí)約束語(yǔ)法。表級(jí)約束語(yǔ)法格式如下:
[constraint 約束名] 約束定義上面的表級(jí)約束語(yǔ)法格式既可以放在 create table 語(yǔ)句中與列定義并列,也可以放在 alter table 語(yǔ)句中使用 add關(guān)鍵字來(lái)添加約束。SQL語(yǔ)句如下:
上面的建表語(yǔ)句為test_name、test_pass分別建立了唯一約束,這意味著這兩列都不能出現(xiàn)重復(fù)值。除此之外,還可以為這兩列組合建立唯一約束,SQL語(yǔ)句如下:
對(duì)于上面的unique_test2和unique_test3兩個(gè)表,都是對(duì)test_name、test_pass建立唯一約束,其中unique_test2要求test_name、test_pass都不能出現(xiàn)重復(fù)值,而unique_test3只要求test_name、test_pass兩列值組合不能重復(fù)。
也可以在修改表結(jié)構(gòu)時(shí)使用add關(guān)鍵字來(lái)增加唯一約束,SQL語(yǔ)句?:
還可以在修改表時(shí)使用 modify關(guān)鍵字,為單列采用列級(jí)約束語(yǔ)法來(lái)增加唯一約束,代碼如下
#為unique test3表的test_name增加唯一約束 alter table unique_test3 add unique(test_name,test_pass);對(duì)于大部分?jǐn)?shù)據(jù)庫(kù)而言,刪除約束都是在alter table 語(yǔ)句后使用 "drop constraint 約束名"語(yǔ)法來(lái)完成的,但MySQL并不使用這種方式,而是使用 "drop index 約束名"的方式來(lái)刪除約束。例如如下SQL語(yǔ)句:
#刪除unique_test3表上的test3_uk唯一約束 alter table unique_test3 drop index test3_uk;PRIMARY KEY約束
主鍵約束相當(dāng)于非空約束和唯一約束,即主鍵約束的列既不允許出現(xiàn)重復(fù)值,也不允許出現(xiàn)null值;如果對(duì)多列組合建立主鍵約束,則多列里包含的每一列都不能為空,但只要求這些列組合不能重復(fù)。主鍵列的值可用于唯一地標(biāo)識(shí)表中的一條記錄。
每一個(gè)表只允許有一個(gè)主鍵,但這個(gè)主鍵可以由多個(gè)數(shù)據(jù)列組合而成,主鍵是表中能唯一確定一行記錄的字段或字段組合,和唯一約束的語(yǔ)法相似,建立主鍵約束使用 primary key。
練習(xí)結(jié)束就可以刪掉之前的數(shù)據(jù)庫(kù)了減少內(nèi)存和礙眼。
記得use數(shù)據(jù)庫(kù)哦。
其實(shí)這里也看到了,表級(jí)和列級(jí)從外觀來(lái)看的區(qū)別就像 表級(jí)定義像調(diào)用帶有參數(shù)的方法;而列級(jí)定義更像定義變量那樣字,在MySQL的變量定義是 名字在前 關(guān)鍵字在后 和Java是相反的。
建表時(shí)創(chuàng)建主鍵約束,以多列建立組合主鍵,只能使用表級(jí)約束語(yǔ)法。
create table primary_test3 (test_id varchar(255),test_pass varchar(255),#建立多列組合的主鍵約束primary key(test_name,test_pass) );
如果需要?jiǎng)h除指定表的主鍵約束,則在alter table 語(yǔ)句后使用 drop primary key子句即可。SQL語(yǔ)句如下:
這里不小心刪除了,少打了個(gè)3
如果需要為指定表增加主鍵約束,既可通過(guò)modify修改列定義來(lái)增加主鍵約束,這將采用列級(jí)約束語(yǔ)法來(lái)增加主鍵約束;也可以通過(guò)add來(lái)增加主鍵約束,這將采用表級(jí)約束語(yǔ)法來(lái)增加主鍵約束。SQL語(yǔ)句如下:
如果只是為單獨(dú)的數(shù)據(jù)列增加主鍵約束,則可使用modify修改列定義來(lái)實(shí)現(xiàn)。SQL語(yǔ)句如下:
注意,如果報(bào)錯(cuò)了,原因大概率是字母打錯(cuò)和重復(fù)添加主鍵看下面示意圖
這里因?yàn)樯厦嬲`刪了 primary_test的test_id的主鍵約束可以補(bǔ)回來(lái)
不要連續(xù)執(zhí)行上面兩條SQL語(yǔ)句,因?yàn)樯厦鎯蓷lSQL語(yǔ)句都是為primary_test3增加主鍵約束,而同一個(gè)表里最多只能有一個(gè)主鍵約束,所以連續(xù)執(zhí)行上面兩條SQL語(yǔ)句肯定出現(xiàn)錯(cuò)誤。為了避免這個(gè)問(wèn)題,可以在成功執(zhí)行了第一條增加主鍵約束的SQL語(yǔ)句之后,先將primary_test3里的主鍵約束刪除后再執(zhí)行第二條增加主鍵約束的SQL語(yǔ)句。
很多數(shù)據(jù)庫(kù)對(duì)主鍵列都支持一種自增長(zhǎng)的特性——如果某個(gè)數(shù)據(jù)列的類(lèi)型是整形,而且該列作為主鍵列,則可指定該列具有自增長(zhǎng)功能。指定自增長(zhǎng)功能通常用于設(shè)置邏輯主鍵列——該列的值沒(méi)有任何物理意義,僅僅用于標(biāo)識(shí)每行記錄。MySQL使用auto_increment來(lái)設(shè)置自增長(zhǎng),SQL語(yǔ)句如下:
SQL最后的一行不用 , 直接以)結(jié)尾即可
一旦指定了某列具有自增長(zhǎng)特性,則向該表插入記錄時(shí)不可為該列指定值,該列的值由數(shù)據(jù)庫(kù)系統(tǒng)自動(dòng)生成。
FOREIGN KEY 約束
外鍵約束主要用于保證一個(gè)或兩個(gè)數(shù)據(jù)表之間的參照完整性,外鍵是構(gòu)建與一個(gè)表的兩個(gè)字段或者兩個(gè)表的兩個(gè)字段之間的參照關(guān)系。外鍵確保了相關(guān)的兩個(gè)字段的參照關(guān)系:子(從)表外鍵列的值必須在主表被參照列的值范圍之內(nèi),或者為空(也可以通過(guò)非空約束來(lái)約束外鍵列不允許為空)。
當(dāng)刪除主表記錄時(shí)不允許直接刪除,而是需要?jiǎng)h除從表里參照該記錄的所有記錄,全部刪除后才可以刪除主表的該記錄。或者刪除主表記錄時(shí)級(jí)聯(lián)從表中的所有參照該記表的從表記錄。
值得指出的是,雖然MySQL支持使用列級(jí)約束語(yǔ)法來(lái)建立外鍵約束,但這種列級(jí)約束語(yǔ)法建立的外鍵約束不會(huì)生效,MySQL提供這種列級(jí)約束語(yǔ)法僅僅是為了和標(biāo)準(zhǔn)SQL保持良好的兼容性,因此,如果要使MySQL中的外鍵約束生效,則應(yīng)使用表級(jí)約束語(yǔ)法。
如果使用表級(jí)約束語(yǔ)法,則需要使用foregin key來(lái)指定本表的外鍵列,并使用references來(lái)指定參照哪個(gè)主表,以及參照到主表的哪個(gè)數(shù)據(jù)列。如果沒(méi)有創(chuàng)建約束名,則MySQL會(huì)為該外鍵約束命名為 table_name_ibfk_n,其中table_name是從表的表名,而n是從1開(kāi)始的整數(shù)。
如果需要顯式指定外鍵約束的名字,則可使用constraint來(lái)指定名字。SQL語(yǔ)句如下:
刪除外鍵約束的語(yǔ)法很簡(jiǎn)單,在alter table 后面增加“drop foreign key 約束名”子句即可。代碼如下:
增加外鍵約束通常使用add foreign key命令。SQL語(yǔ)句如下:
值得支出的是,外鍵約束不僅可以參照其他表,而且可以參照自身,這種參照自身的通常被稱(chēng)為自關(guān)聯(lián)。例如,如果一個(gè)包保存某個(gè)公司的所有員工記錄,員工之間有部門(mén)經(jīng)理和普通員工之分,部分經(jīng)理和普通員工之間存在一對(duì)多的關(guān)聯(lián)關(guān)系,但他們都是保存在同一個(gè)數(shù)據(jù)表里的記錄,這就是典型的自關(guān)聯(lián)。下面的SQL語(yǔ)句用于建立自關(guān)聯(lián)的外鍵約束。
如果想定義刪除主表記錄時(shí),從表記錄也會(huì)隨之刪除,則需要在建立外鍵約束后添加 on delete cascade或添加 on delete set null,第一種是刪除主表記錄時(shí),把參照該主表記錄的從表記錄全部級(jí)聯(lián)刪除;第二種是指定刪除主表記錄時(shí),把參照該主表記錄的從表記錄的外鍵設(shè)為null。SQL語(yǔ)句如下:
CHECK約束
當(dāng)前版本的MySQL支持建表時(shí)使用CHECK約束,但是這個(gè)CHECK約束不會(huì)有任何作用。建立CHECK約束的語(yǔ)法很簡(jiǎn)單,只要在建表時(shí)列定義后增加check(邏輯表達(dá)式)即可。SQL語(yǔ)句如下:
雖然上面的SQL語(yǔ)句建立的CHECK_test表中有CHECK約束,CHECK約束要求emp_salary大于0,但實(shí)際上并不會(huì)起作用。
MySQL作為一個(gè)開(kāi)源、免費(fèi)的數(shù)據(jù)庫(kù)系統(tǒng),對(duì)有些功能支持確實(shí)不太好,如果讀者確實(shí)希望MySQL創(chuàng)建數(shù)據(jù)表有CHECK約束,甚至有更復(fù)雜的完整性約束,則可借助于MySQL的觸發(fā)器機(jī)制。本階段(Java基礎(chǔ))不會(huì)介紹,可期待下一階段(MySQL)文章。
關(guān)于約束學(xué)習(xí)的總結(jié),其實(shí)約束這個(gè)內(nèi)容不是很難,只是現(xiàn)在剛剛學(xué)習(xí)MySQL基礎(chǔ)操作語(yǔ)句還很抽象,我也不清楚約束具體作用,這些都需要慢慢的學(xué)習(xí)去完善認(rèn)知和使用以及學(xué)習(xí)!
索引
索引是存在在模式中的一個(gè)數(shù)據(jù)庫(kù)對(duì)象,它加速了查詢,減少了磁盤(pán)的I/O。
索引作為數(shù)據(jù)庫(kù)對(duì)象,在數(shù)據(jù)字典中獨(dú)立存在,但不能獨(dú)立存在,必須屬于某個(gè)表。
MySQL使用information_schema數(shù)據(jù)庫(kù)里的STATISTICS表來(lái)保存該數(shù)據(jù)庫(kù)實(shí)例中的所有索引信息,用戶可通過(guò)查詢?cè)摫韥?lái)獲取該數(shù)據(jù)庫(kù)的索引信息。
創(chuàng)建索引有兩種方式.
- 自動(dòng):當(dāng)在表上定義主鍵約束、唯一約束和外鍵約束時(shí),系統(tǒng)會(huì)為該數(shù)據(jù)列自動(dòng)創(chuàng)建對(duì)應(yīng)索引。
- 手動(dòng):用戶可以通過(guò)create index…語(yǔ)句來(lái)創(chuàng)建索引。
刪除索引也有兩種方式。
- 自動(dòng):數(shù)據(jù)表被刪除時(shí),索引自動(dòng)被刪除。
- 手動(dòng):用戶可以通過(guò)drop index…語(yǔ)句來(lái)刪除指定數(shù)據(jù)表上的指定索引。
索引的作用類(lèi)似于書(shū)的目錄,幾乎沒(méi)有一本書(shū)沒(méi)有目錄,因此幾乎沒(méi)有一個(gè)表沒(méi)有索引。一個(gè)表中可以有多個(gè)索引列,每個(gè)索引都可以用于加速該列的查詢速度。
創(chuàng)建索引的語(yǔ)法格式如下:
下面的索引將會(huì)提供對(duì)employees表基于last_name字段的查詢速度。
變綠在cmd原始狀態(tài)下輸入 color a 就行了 也可以直接輸入color調(diào)出提示。
創(chuàng)建employees表中l(wèi)ast_name的索引
create index emp_last_name_idx on employees(last_name);也可同時(shí)對(duì)多列建立索引,SQL語(yǔ)句如下:
先刪掉原來(lái)的employees表
刪除索引
刪除索引需要指定表:
drop index 索引名 on 表名如下SQL語(yǔ)句刪除了employees表上的emp_last_name_idx索引:
drop index emp_last_name_idx on employees;有些數(shù)據(jù)庫(kù)刪除索引時(shí)無(wú)須指定表名,因?yàn)樗鼈円蠼⑺饕龝r(shí)每個(gè)索引都有唯一的名字,所以無(wú)須指定表名,例如Oracle就采用這種策略。但MySQL只要求同一個(gè)表內(nèi)的索引不能同名,所以刪除索引時(shí)必須指定表名。
索引的好處是可以加速查詢。但索引也有如下兩個(gè)壞處。
- 與書(shū)的目錄類(lèi)似,當(dāng)數(shù)據(jù)表中的記錄被添加、刪除、修改時(shí),數(shù)據(jù)庫(kù)系統(tǒng)需要維護(hù)索引,因此有一定的系統(tǒng)開(kāi)銷(xiāo)。
- 存儲(chǔ)索引信息需要一定的磁盤(pán)空間。
視圖
視圖看上去很像一個(gè)數(shù)據(jù)表,但它不是數(shù)據(jù)表,因?yàn)樗荒艽鎯?chǔ)數(shù)據(jù)。視圖只是一個(gè)或多個(gè)數(shù)據(jù)表中數(shù)據(jù)的邏輯顯示。使用視圖有如下幾個(gè)好處。
- 可以限制對(duì)數(shù)據(jù)的訪問(wèn)。
- 可以使復(fù)雜的查詢變得簡(jiǎn)單。
- 提供了數(shù)據(jù)的獨(dú)立性。
- 提供了對(duì)相同數(shù)據(jù)的不同顯示。
因?yàn)橐晥D只是數(shù)據(jù)表中數(shù)據(jù)邏輯的顯示——也就是一個(gè)查詢結(jié)果,所以創(chuàng)建視圖就是建立視圖名和查詢語(yǔ)句的關(guān)聯(lián)。創(chuàng)建視圖的語(yǔ)法如下:
從上面語(yǔ)法可以看出,創(chuàng)建、修改視圖都可使用上面語(yǔ)法。上面語(yǔ)法的含義是,如果該視圖不存在則創(chuàng)建視圖;如果指定視圖名的視圖已經(jīng)存在,則使用新視圖替換原有視圖。后面的subquery就是一個(gè)查詢語(yǔ)句,這個(gè)查詢可以非常復(fù)雜。
通過(guò)建立視圖的語(yǔ)法規(guī)則不難看出,所謂視圖的本質(zhì),其實(shí)就是一條被命名的SQL查詢語(yǔ)句。
一旦建立了視圖以后,使用該視圖與使用數(shù)據(jù)表就沒(méi)有上面區(qū)別了,但通常只是查詢視圖數(shù)據(jù),不會(huì)修改視圖里的數(shù)據(jù),因?yàn)橐晥D本身沒(méi)有存儲(chǔ)數(shù)據(jù)。
如下SQL語(yǔ)句就創(chuàng)建了一個(gè)簡(jiǎn)單的視圖:
這里因?yàn)閯h除了之前的 teacher_table,所以重新建立一個(gè)
創(chuàng)建視圖
create or replace view view_test as select teacher_name,teacher_pass from teacher_table;我們來(lái)看結(jié)果
可以看到,我們通過(guò) desc關(guān)鍵字查詢兩者時(shí),顯示的數(shù)據(jù)毫無(wú)區(qū)別。
通常不推薦直接改變視圖的數(shù)據(jù),因?yàn)橐晥D并不存儲(chǔ)數(shù)據(jù),它只是相當(dāng)于一條命名的查詢語(yǔ)句而已。為了強(qiáng)制不允許改變視圖的數(shù)據(jù),MySQL允許在創(chuàng)建視圖時(shí)使用with check option子句,使用該子句創(chuàng)建的視圖不允許修改,如下所示。
這里刪除視圖的語(yǔ)句就不再是
而是
drop view view_test; create or replace view view_test as select teacher_name from teacher_table #指定不允許修改該視圖的數(shù)據(jù) with check option;
大部分?jǐn)?shù)據(jù)庫(kù)都采用 with check option來(lái)強(qiáng)制不允許修改數(shù)據(jù)庫(kù)的數(shù)據(jù),但Oracle采用 with read olny 來(lái)強(qiáng)制不允許修改視圖的數(shù)據(jù)。
刪除視圖語(yǔ)句如下:
上面刪除過(guò)了一次 view_test視圖
drop view view_test;DML語(yǔ)句語(yǔ)法
與DDL操作數(shù)據(jù)庫(kù)對(duì)象不同,DML主要操作數(shù)據(jù)表里的數(shù)據(jù),使用DML可以完成如下三個(gè)任務(wù)。
- 插入新數(shù)據(jù)。
- 修改已有數(shù)據(jù)。
- 刪除不需要的數(shù)據(jù)。
DML語(yǔ)句由insert into、update 和 delete from三個(gè)命令組成。
1.insert into語(yǔ)句
其實(shí)這三個(gè)文章剛開(kāi)始就都講過(guò)了,所以只要前面的實(shí)例跟著做過(guò),再學(xué)這個(gè)還是非常簡(jiǎn)單的,包括會(huì)了前面文章的所有內(nèi)容。不過(guò)注意,文章剛開(kāi)始確實(shí)講過(guò)這三個(gè)關(guān)鍵字但是都是使用,并沒(méi)有將很多細(xì)節(jié),所以主要學(xué)習(xí)的時(shí)候才是最重要的,提前實(shí)習(xí)只是打下基礎(chǔ)。
insert into 用于向指定數(shù)據(jù)表中插入數(shù)據(jù)。對(duì)于標(biāo)準(zhǔn)的SQL語(yǔ)句而言,每次只能插入一條記錄。insert into語(yǔ)句的語(yǔ)法格式如下:
執(zhí)行插入操作時(shí),表名后可以用括號(hào)列出所有需要插入值的列名,而values后用括號(hào)列出對(duì)應(yīng)需要插入的值。
如果省略了表名后面的括號(hào)及括號(hào)里的列名列表,默認(rèn)將為所有列都插入值,則需要為每一列都指定一個(gè)值。如果既不想在表名后列出列名,又不想為所有列都指定值,則可以為那些無(wú)法確定值的列分配null。下面SQL語(yǔ)句示范了如何向數(shù)據(jù)表中插入記錄。
只有在數(shù)據(jù)庫(kù)中已經(jīng)成功創(chuàng)建了數(shù)據(jù)表之后,才可以向數(shù)據(jù)表中插入記錄。下面的SQL語(yǔ)句以前面外鍵約束時(shí)所創(chuàng)建的teacher_table2和student_table2為列來(lái)介紹數(shù)據(jù)插入操作。
在表名后使用括號(hào)列出所有需要插入值的列:
如果之前把前面的實(shí)例刪了,就再創(chuàng)建一下兩個(gè)表。
這里應(yīng)該使用 select查詢表中數(shù)據(jù),而不再是 desc
從上面中看到 abc記錄的主鍵列的值是2,而不是SQL語(yǔ)句插入的NULL,因?yàn)橹麈I列是自增長(zhǎng)的,系統(tǒng)自動(dòng)分配值。
根據(jù)前面介紹的外鍵約束規(guī)則:外鍵列里的值必須是被參照列里已有的值,所以向表中插入記錄之前,通常應(yīng)該先向主表中插入記錄。否則從表記錄的外鍵列只能為null、現(xiàn)在主表teacher_table2中已有了2條記錄,現(xiàn)在可以向從表student_table2中插入記錄了,SQL語(yǔ)句如下:
外鍵約束保證被參照的記錄存在,但并不保證必須有被參照記錄,即外建立可以為null,如果想保證每條記錄必須存在對(duì)應(yīng)的主表記錄,則應(yīng)使用非空、外鍵兩個(gè)約束。
在一些特殊的情況下,可以使用帶子查詢的插入語(yǔ)句,帶子查詢的插入語(yǔ)句可以一次插入多條記錄,SQL語(yǔ)句如下:
正如上面的SQL語(yǔ)句所示,帶子查詢的插入語(yǔ)句甚至不要求查詢數(shù)據(jù)的源表和插入數(shù)據(jù)的目標(biāo)表是同一個(gè)表,它只要求選擇出來(lái)的數(shù)據(jù)列和插入目的表的數(shù)據(jù)列個(gè)數(shù)相等、數(shù)據(jù)類(lèi)型匹配既可。
MySQL甚至提供了一種擴(kuò)展的語(yǔ)法,通過(guò)這種擴(kuò)展的語(yǔ)法也可以一次插入多條記錄。MySQL允許在values后使用多個(gè)括號(hào)包含多條記錄,表示多條記錄的多個(gè)括號(hào)之間以英文逗號(hào)格式。SQL語(yǔ)句如下:
2.update語(yǔ)句
這個(gè)文章初期也有講過(guò),修改語(yǔ)句。
update語(yǔ)句用于修改數(shù)據(jù)表的記錄,每次可以修改多條記錄,通過(guò)使用where子句限定修改哪些記錄。where子句是一個(gè)條件表達(dá)式,該條件表達(dá)式類(lèi)似于Java語(yǔ)句的if,只有符合該條件的記錄才會(huì)被修改。沒(méi)有where子句以意味著where表達(dá)式的值總是true。即該表的所有記錄都會(huì)被修改。update語(yǔ)句的語(yǔ)法格式如下。
使用update語(yǔ)句不僅可以一次修改多條記錄,也可以一次修改多列。修改多列都是通過(guò)在set關(guān)鍵字后使用 cloumn1 = value1,column2 = value2…來(lái)實(shí)現(xiàn)的,修改多列之間的值以英文逗號(hào)隔開(kāi)。
下面的SQL語(yǔ)句將把teacher_table2表中的所有記錄的teacher_name列的值都改為’孫悟空’。
也可以通過(guò)添加where條件來(lái)指定值修改特定記錄,SQL語(yǔ)句如下。
3.delete from語(yǔ)句
delete from語(yǔ)句用于刪除指定數(shù)據(jù)表的記錄。使用delete from語(yǔ)句刪除時(shí)不需要指定列名,因?yàn)榭偸钦械貏h除。
使用delete from語(yǔ)句可以一次刪除多行,刪除哪些行采用where子句限定,只刪除滿足where條件的記錄。沒(méi)有where子句限定將會(huì)把表中的全部記錄刪掉。
delete from語(yǔ)句的語(yǔ)法格式如下:
如下SQL語(yǔ)句將會(huì)把student_table2表的記錄全部刪除
也可以使用where條件來(lái)限定只刪除指定記錄,SQL語(yǔ)句如下:
當(dāng)主表記錄被從表記錄參照時(shí),主表記錄不能被餐廚,只有先將從表中參照主表記錄的所有記錄全部刪除后,才可以刪除主表記錄。還有一種情況,定義外鍵約束時(shí)定義了主表記錄和從表記錄之間的級(jí)聯(lián)刪除 on delete cascade,或者使用 on delete set null 用于指定當(dāng)主表記錄被刪除時(shí),從表中參照該記錄的從表記錄被外鍵列的值設(shè)為null。
單表查詢
有示意圖,但是不展示了,光看示意圖看不懂,看介紹。
select語(yǔ)句的功能就是查詢數(shù)據(jù),select語(yǔ)句也是SQL中最豐富的語(yǔ)句,select語(yǔ)句不僅可以執(zhí)行單表查詢,而且可以執(zhí)行多表連接查詢,還可以進(jìn)行子查詢,select語(yǔ)句用于從一個(gè)胡哦多個(gè)數(shù)據(jù)表中選出特定行、特定列的交集。
select后的列用于確定選擇哪些列,where條件用于確定選擇哪些行,只有滿足where條件的記錄才會(huì)被選擇出來(lái);如果沒(méi)有where條件,則默認(rèn)選出所有行。如果想選擇出所有列,則可使用星號(hào)代表所有列。
下面的SQL語(yǔ)句將會(huì)選擇出teacher_table表中的所有行、所有列的數(shù)據(jù)。
為了能看到查詢結(jié)果,必須準(zhǔn)備數(shù)據(jù)表,并向數(shù)據(jù)表中插入一些數(shù)據(jù),因此在運(yùn)行本節(jié)的select之前準(zhǔn)備好之前的數(shù)據(jù)表 student_table。
如果增加where條件,則只選擇出符合where條件的記錄。如下SQL語(yǔ)句將選擇出student_table表中java_teacher值大于3的記錄的student_name列的值。
先添加好數(shù)據(jù),再執(zhí)行上面的內(nèi)容:
當(dāng)使用select語(yǔ)句進(jìn)行查詢時(shí),還可以在select語(yǔ)句中使用算術(shù)運(yùn)算符(+、-、*、/),從而形成算術(shù)表達(dá)式。使用算術(shù)表達(dá)式的規(guī)則如下:
- 對(duì)數(shù)值型數(shù)據(jù)列、變量、常量可以使用算術(shù)運(yùn)算符(+、-、*、/)創(chuàng)建表達(dá)式。
- 對(duì)日期型數(shù)據(jù)、變量、常量可以使用部分運(yùn)算術(shù)運(yùn)算符(+、-)創(chuàng)建表達(dá)式,兩個(gè)日期之間可以進(jìn)行減法運(yùn)算,日期和數(shù)值之間可以進(jìn)行加、減運(yùn)算。
- 運(yùn)算符不僅可以在列和變量之間進(jìn)行運(yùn)算,也可以在兩列之間進(jìn)行運(yùn)算。
不論從哪個(gè)角度來(lái)看,數(shù)據(jù)列都很像一個(gè)變量,只是這個(gè)變量值具有指定的范圍——逐行計(jì)算表中的每條記錄時(shí),數(shù)據(jù)列的值依次變化。因此能使用變量的地方,基本上都可以使用數(shù)據(jù)列。
下面的select語(yǔ)句中使用了算術(shù)運(yùn)算符。
需要指出的是,select后的不僅可以是數(shù)據(jù)列,也可以是表達(dá)式,還可以是變量、常量等。例如:
SQL語(yǔ)句中算術(shù)運(yùn)算符的優(yōu)先級(jí)與Java語(yǔ)言中的運(yùn)算符優(yōu)先級(jí)完全相同,乘法和除法的優(yōu)先級(jí)高于加法和減法,同級(jí)運(yùn)算的順序是從左到右,表達(dá)式中使用括號(hào)可以強(qiáng)行改變優(yōu)先級(jí)的運(yùn)算順序。
MySQL中沒(méi)有提供字符串連接運(yùn)算符,即無(wú)法使用加號(hào)(+)將字符串常量、字符串變量或字符串列連接起來(lái)。MySQL使用concat函數(shù)來(lái)進(jìn)行字符串連接運(yùn)算。
SQL語(yǔ)句如下:
MySQL的算術(shù)表達(dá)式中也可以使用null,但是會(huì)導(dǎo)致整個(gè)算術(shù)表達(dá)式的返回結(jié)果都為null,使用字符串連接也是null。
如果不希望直接使用列名作為列標(biāo)題,則可以為數(shù)據(jù)列或表達(dá)式起一個(gè)別名,為數(shù)據(jù)列或表達(dá)式起別名時(shí),別名緊跟數(shù)據(jù)列,中間以空格隔開(kāi),或者使用as關(guān)鍵字隔開(kāi)。SQL語(yǔ)句如下:
可以看出,為列起別名,可以改變列的標(biāo)題頭,用于標(biāo)識(shí)計(jì)算結(jié)果的具體含義。如果列別名中使用特殊字符(如空格),或者強(qiáng)制大小寫(xiě)敏感,都可以通過(guò)為別名添加雙引號(hào)來(lái)實(shí)現(xiàn)。SQL語(yǔ)句如下:
如果要選擇多列,并未多列起名,則列與列之間以逗號(hào)隔開(kāi),但列與列名之間以空格隔開(kāi)。
也可以為表起別名,為表起別名的語(yǔ)法和為列或表達(dá)式起別名的語(yǔ)法完全一樣。
前面已經(jīng)提到,列名可以當(dāng)成變量處理,所以運(yùn)算符也可以在多列之間進(jìn)行運(yùn)算,SQL語(yǔ)句如下。
甚至可以在select、where子句中都不出現(xiàn)列名,SQL語(yǔ)句如下:
這種情況這叫特殊:where語(yǔ)句后的表達(dá)式總是true,所以會(huì)把teacher_table表中的每條記錄都選擇出來(lái))但SQL語(yǔ)句沒(méi)有選擇任何列,僅僅選擇了一個(gè)常量,所以SQL會(huì)把該常量當(dāng)成一列,teacher_table表中有多少條記錄,該常量就會(huì)出現(xiàn)多少次。
對(duì)于選擇常量的情形,指定數(shù)據(jù)表可能沒(méi)有太大的意義,所以MySQL提供了一種擴(kuò)展語(yǔ)法,允許select語(yǔ)句后沒(méi)有from子句,即可寫(xiě)成如下形成。
上面語(yǔ)句并不是標(biāo)準(zhǔn)的SQL語(yǔ)句,例如,Oracle就提供了一個(gè)名為dual的虛標(biāo)(最新的MySQL數(shù)據(jù)庫(kù)也支持dual虛標(biāo)),它沒(méi)有任何意義,僅僅相當(dāng)于from后的占位符。如果選擇常量,則可使用如下語(yǔ)句。
select默認(rèn)會(huì)把所有的符合條件的記錄全部選出來(lái),即使兩行記錄完全一樣。如果想除去重復(fù)行,則可以使用distinct關(guān)鍵字從查詢結(jié)果中清除重復(fù)行。
額實(shí)際上,沒(méi)有重復(fù)行,去了個(gè)寂寞
但是可以手動(dòng)添加一個(gè):
再次執(zhí)行如上指令。
這里看到了,查詢到了重復(fù)的值。
看去除重復(fù)行的效果
使用ddistinct去除重復(fù)行時(shí),distinct緊跟select關(guān)鍵字。它的作用是去除后面字段組合的重復(fù)值,而不管對(duì)應(yīng)記錄在數(shù)據(jù)庫(kù)里是否重復(fù)。例如,(1,‘a(chǎn)’,‘b’)和(2,‘a(chǎn)’,‘b’)兩條記錄在數(shù)據(jù)庫(kù)里是不重復(fù)的,但如果僅選擇后面兩列,則distinct會(huì)認(rèn)為兩條記錄重復(fù)。
前面已經(jīng)看到了where子句的作用——可以控制只選擇指定的行,因?yàn)閣here子句里包含的是一個(gè)條件表達(dá)式,所以可以使用 >、>=、<、<=、=和<>等基本的比較運(yùn)算符。SQL中比較運(yùn)算符不僅可以比較數(shù)值之間的大小,也可以比較字符串、日期之間的大小。
SQL中判斷兩個(gè)值是否相等的比較運(yùn)算符是單等號(hào),判斷不相等的運(yùn)算符是<>;SQL中的賦值運(yùn)算符不是等號(hào),而是冒號(hào)等號(hào)(:=)。
除此之外,SQL還支持如下表所示的特殊比較運(yùn)算符。
可能有點(diǎn)看不清楚
概念只是個(gè)人理解不一定正確。
下面的SQL語(yǔ)句選出student_id 大于等于2,且小于等于4的所有記錄。
使用betwwen val 1 and val2必須保證val1小于val2,否則將選不出任何記錄。此處之外,between val1and val2中的兩個(gè)值不僅可以是常量,也可以是變量,或者是列名也行。如下SQL語(yǔ)句選出java_teacher小于等于2,student_id大于等于2的所有記錄
使用in比較運(yùn)算符時(shí),必須在in后的括號(hào)里列出一個(gè)或多個(gè)值,它要求指定列必須與in括號(hào)里任意一個(gè)值相等,SQL語(yǔ)句如下:
與此類(lèi)似的是,in括號(hào)里的值既可以是常量,也可以是變量或者列名,SQL語(yǔ)句如下:
select*from student_table where 2 in (student_id,java_teacher);
運(yùn)行結(jié)果也就那幾個(gè),詳細(xì)使用還是等到JDBC吧。
like運(yùn)算主要用于模糊查詢,例如:查 ‘張開(kāi)頭的記錄’
這就需要使用模糊查詢了,比如查找 '張’姓名開(kāi)頭的學(xué)生。
SQL有兩個(gè)通配符:下畫(huà)線(_)和百分號(hào)(%),其中下畫(huà)線可以代表任意一個(gè)字符,百分號(hào)可以代表多個(gè)字符。
下面語(yǔ)句查詢名為張的學(xué)生。
這里比較坑,得自己再加點(diǎn)數(shù)據(jù)了
通過(guò)結(jié)構(gòu)顯示可以知道有3個(gè)數(shù)值,而id是自動(dòng)增長(zhǎng),所以可以直接null讓系統(tǒng)自動(dòng)分配,name是我們這次主要的內(nèi)容
我就新建這么多的數(shù)據(jù),主要看查詢結(jié)果。
下面SQL語(yǔ)句將查詢名為兩個(gè)字符的所有學(xué)生。
在某些特殊情況下,查詢的條件里需要使用下畫(huà)線或百分號(hào),不希望SQL把下畫(huà)線和百分號(hào)當(dāng)成通配符使用,這就需要使用轉(zhuǎn)義字符,MySQL使用反斜線(\)作為轉(zhuǎn)義字符,SQL語(yǔ)句如下:
這里再次自導(dǎo)自演一次,添加帶有_下畫(huà)線的數(shù)據(jù)
查詢帶有下畫(huà)線的數(shù)據(jù):
這里大意了
標(biāo)準(zhǔn)SQL語(yǔ)句并沒(méi)有提供反斜線(\)的轉(zhuǎn)義字符,而是使用escape關(guān)鍵字顯式進(jìn)行轉(zhuǎn)義。例如,為了實(shí)現(xiàn)上面的功能需要使用SQL語(yǔ)句。
這里就不要再執(zhí)行這個(gè)代碼了,有奇怪的BUG。
is null用于判斷某些值是否為空,判斷是否為空不要用=null來(lái)判斷,因?yàn)镾QL中 null=null返回null,如下SQL語(yǔ)句將選擇出student_table表中student_name為null的所有記錄。
如果where子句后有多個(gè)條件需要組合,SQL提供了and和or邏輯運(yùn)算符來(lái)組合兩個(gè)條件,并提供了not來(lái)對(duì)邏輯表達(dá)式求否。如下SQL語(yǔ)句將選出學(xué)生名字為2個(gè)字符,且student_id大于3的所有記錄。
下面語(yǔ)句將選出不以下畫(huà)線開(kāi)頭的name。
下面示意了邏輯運(yùn)算符的優(yōu)先級(jí)。
如果SQL代碼需要改變優(yōu)先級(jí)默認(rèn)順序,則可以使用括號(hào),括號(hào)的優(yōu)先級(jí)比所有的運(yùn)算符都高
執(zhí)行查詢后的查詢結(jié)果默認(rèn)按插入順序排列;如果需要查詢結(jié)果按某列值大小進(jìn)行排序,則可以使用 order by 子句。 order by 子句的語(yǔ)法格式如下:
進(jìn)行排序時(shí)默認(rèn)按升序排列,如果強(qiáng)制按降序排列,則需要在列后使用desc關(guān)鍵字(與之對(duì)應(yīng)的是asc關(guān)鍵字,用不用該關(guān)鍵字的效果完全一樣,因?yàn)槟J(rèn)就是按升序排序的)。
上面語(yǔ)法中設(shè)定排序列時(shí)可采用列名、序列名和列別名。如下SQL語(yǔ)句選出student_table表中所有記錄,選出后按java_teacher列的升序排列。
如果需要按多列排序,則每列的asc、desc必須單獨(dú)設(shè)定,如果指定了多個(gè)排序列,則第一個(gè)排序了是首要排序列,只有當(dāng)?shù)谝涣兄写嬖诙鄠€(gè)相同的值時(shí),第二個(gè)排序列才會(huì)起作用。如下SQL語(yǔ)句先按java_teacher列的降序排列,當(dāng)java_teacher列的相同值同時(shí)按student_name列的升序排列。
數(shù)據(jù)庫(kù)函數(shù)
前面看到的連接字符串使用的concat函數(shù),每個(gè)數(shù)據(jù)庫(kù)都會(huì)在標(biāo)準(zhǔn)的SQL基礎(chǔ)上擴(kuò)展一些函數(shù),這些函數(shù)用于進(jìn)行數(shù)據(jù)處理和復(fù)雜計(jì)算,它們通過(guò)對(duì)一組數(shù)據(jù)進(jìn)行計(jì)算,得到最終需要輸出的結(jié)果。
函數(shù)一般都會(huì)有一個(gè)或者多個(gè)輸入,這些輸入被稱(chēng)為函數(shù)的參數(shù),函數(shù)內(nèi)部會(huì)對(duì)這些參數(shù)進(jìn)行判斷和計(jì)算,最終只有一個(gè)值作為返回值。函數(shù)可以出現(xiàn)在SQL語(yǔ)句中的各個(gè)位置,比較常用的位置是select之后和where子句之中。
根據(jù)函數(shù)對(duì)多行數(shù)據(jù)的處理方式,函數(shù)被分為單行函數(shù)和多行函數(shù),單行函數(shù)對(duì)每行輸入值單獨(dú)計(jì)算,每行得到一個(gè)計(jì)算結(jié)果返回給用戶,多行函數(shù)對(duì)多行輸入值整體計(jì)算,最后只會(huì)得到一個(gè)結(jié)果。
SQL中的函數(shù)和Java語(yǔ)言中的方法有些相似,但SQL中的函數(shù)是獨(dú)立的程序單元,也就是說(shuō),調(diào)用函數(shù)時(shí)無(wú)須使用任何類(lèi)、對(duì)象作為調(diào)用者,而是直接執(zhí)行函數(shù)。執(zhí)行函數(shù)的語(yǔ)法如下:
多行函數(shù)也稱(chēng)為聚集函數(shù)、分組函數(shù),主要用于完成一些統(tǒng)計(jì)計(jì)算,在大部分?jǐn)?shù)據(jù)庫(kù)中基本相同。但不同數(shù)據(jù)庫(kù)中的單行函數(shù)差別非常大,MySQL中的單行函數(shù)具有如下特征。
- 單行函數(shù)的參數(shù)可以是變量、常量或數(shù)據(jù)列。
單行函數(shù)可以接收多個(gè)參數(shù),但只返回一個(gè)值。 - 單行函數(shù)會(huì)對(duì)每行單獨(dú)起作用,每行(可能包含多個(gè)參數(shù))返回一個(gè)結(jié)果。
- 使用單行函數(shù)可以改變參數(shù)的數(shù)據(jù)類(lèi)型。單行函數(shù)支持嵌套使用,即內(nèi)層函數(shù)的返回值是外層函數(shù)的參數(shù)。
MySQL數(shù)據(jù)庫(kù)的數(shù)據(jù)類(lèi)型大致分為數(shù)值型、字符串和日期時(shí)間型,所以MySQL提供了對(duì)應(yīng)的函數(shù)。轉(zhuǎn)換函數(shù)主要負(fù)責(zé)完成類(lèi)型轉(zhuǎn)換。其他函數(shù)又大致分為如下幾類(lèi)。
- 位函數(shù)
- 流程控制函數(shù)
- 加密解密函數(shù)
- 信息函數(shù)
每個(gè)數(shù)據(jù)庫(kù)都包含了大量的單行函數(shù),這些單行函數(shù)的用法也存在一些差異,但是有一點(diǎn)是相同的——每個(gè)數(shù)據(jù)庫(kù)都會(huì)為一些常用計(jì)算功能提供相應(yīng)的函數(shù),這些函數(shù)的函數(shù)名可能不同,用法可能有差異,但所有數(shù)據(jù)庫(kù)提供的函數(shù)庫(kù)所能完成的功能大致相似。
MySQL單行函數(shù)的用法。
這里代碼比較多
MySQL提供了如下幾個(gè)處理null的函數(shù)
- ifnull(expr1,expr2):如果expr1為null,則返回expr2,否則返回expr1。
- nullif(expr1,expr2):如果expr1和expr2相等,則返回null,否則返回expr1。
- if(expr1,expr2,expr3):有點(diǎn)類(lèi)似于 ? : 三目運(yùn)算符,如果expr1為true,不等于0,且不等于null,null返回expr2,否則返回expr3。
- isnull(expr1):判斷expr1是否為null,如果為null則返回true,否則返回false。
這里應(yīng)該只是針對(duì)兩個(gè)字符長(zhǎng)度的篩查
MySQL還提供了一個(gè)case函數(shù),該函數(shù)是一個(gè)流程控制函數(shù)。case函數(shù)有兩個(gè)用法,case函數(shù)第一個(gè)用法的語(yǔ)法格式如下:
case函數(shù)用value和后面的compare_value1、compare_value2、…依次比較,如果value和指定的compare_value1相等,則返回對(duì)應(yīng)的result1,否則返回else后的result。
case函數(shù)第二個(gè)用法的語(yǔ)法格式如下:
case when condition1 then result1 when condition2 then result2 ... else result end在第二個(gè)用法中,condition1、condition2都是一個(gè)返回boolean值的條件表達(dá)式,因此這種用法更加靈活。例如如下語(yǔ)句:
雖然此處介紹了一些MySQL常用函數(shù)的簡(jiǎn)單用法,但通常不推薦在Java程序中使用特定數(shù)據(jù)庫(kù)的函數(shù),因?yàn)檫@將導(dǎo)致程序代碼與特定數(shù)據(jù)庫(kù)耦合;如果需要把該程序移植到其他數(shù)據(jù)庫(kù)系統(tǒng)上時(shí),可能需要打開(kāi)源程序,重新修改SQL語(yǔ)句。
分組和組函數(shù)
組函數(shù)也是前面提到的多行函數(shù),組函數(shù)將一組記錄作為整體計(jì)算,每組記錄返回一個(gè)結(jié)果,而不是每條記錄返回一個(gè)結(jié)果。常用的組函數(shù)又如下5個(gè)
- avg([distinct|all]expr):計(jì)算多行expr的平均值,其中,expr可以是變量、常量或數(shù)據(jù)列,但起數(shù)據(jù)類(lèi)型必須是數(shù)值型。還可以在變量、列前使用distinct或all關(guān)鍵字,如果使用distinct,則表明不計(jì)算重復(fù)值;all用和不用效果完全一樣,表明需要計(jì)算重復(fù)值。
- count({*[distinct|all]expr}):計(jì)算多行expr的總條數(shù),其中expr可以是變量、常量或數(shù)據(jù)列,其數(shù)據(jù)類(lèi)型可以是任意類(lèi)型:用星號(hào)表示統(tǒng)計(jì)該表內(nèi)的記錄行數(shù);distinct表示不計(jì)算重復(fù)值。
- max(expr):計(jì)算多行expr的最大值,其中expr可以是變量、常量或數(shù)據(jù)列,其數(shù)據(jù)類(lèi)型可以是任意類(lèi)型。
- min(expr):計(jì)算多行expr的最小值,其中expr可以是變量、常量或數(shù)據(jù)列,其數(shù)據(jù)類(lèi)型可以是任意類(lèi)型。
- sum([distinct|all]expr):計(jì)算多行expr的總和,其中expr可以是變量、常量或數(shù)據(jù)列,但其數(shù)據(jù)類(lèi)型必須是數(shù)值型;distinct表示不計(jì)算重復(fù)值。
對(duì)于可能出現(xiàn)null的列,可以使用ifnull函數(shù)來(lái)處理該列。
值得支出的是,distinct和*不同時(shí)使用,如下SQL語(yǔ)句有錯(cuò)誤
select count(distinct *) from student_table;在默認(rèn)情況下,組函數(shù)會(huì)把所有記錄當(dāng)一組,為了對(duì)記錄進(jìn)行顯式分組,可以在select語(yǔ)句后使用group by子句,group by子句后通常會(huì)跟一個(gè)或多個(gè)列名,表明查詢結(jié)果根據(jù)一列或多列進(jìn)行分組——當(dāng)一列或多列組合的值完全相同時(shí),系統(tǒng)會(huì)把這些記錄當(dāng)成一組。SQL語(yǔ)句如下:
如果對(duì)多列進(jìn)行分組,則要求多列的值完全相同才會(huì)被當(dāng)成一組。SQL語(yǔ)句如下:
select count(*) from student_table #當(dāng)java_teacher、student_name兩列的值完全相同時(shí)才會(huì)被當(dāng)成一組 group by java_teacher,student_name;
如果需要對(duì)組過(guò)濾
- 不能在where子句中過(guò)濾組,where子句僅用于過(guò)濾行。過(guò)濾組必須使用having子句。
- 不能在where子句中使用組函數(shù),having子句才可使用組函數(shù)。
多表連接查詢
很多時(shí)候,需要選擇的數(shù)據(jù)并不是來(lái)自一個(gè)表,而是來(lái)自多個(gè)數(shù)據(jù)表,這就需要使用多表連接查詢,例如,對(duì)于上面的student_table和teacher_table兩個(gè)數(shù)據(jù)表,如果希望查詢出所有學(xué)生以及他的老師名字,這就需要從兩個(gè)表中取數(shù)據(jù)。
多表連接查詢有兩種規(guī)范,較早的SQL92規(guī)范支持如下幾種多表連接查詢。
- 等值連接。
- 非等值連接。
- 外連接。
- 廣義笛卡兒積。
SQL99規(guī)范提供了可讀性更好的多表連接 - 交叉連接。
- 自然連接。
- 使用using子句的連接。
- 使用on子句的連接。
- 全外連接或者左、右外連接。
1.SQL92的連接查詢
SQL92的多表連接查詢語(yǔ)法比較簡(jiǎn)潔。多個(gè)表都放在from之后,多個(gè)表以逗號(hào)可開(kāi),連接條件在where之后,與查詢條件之間用and邏輯運(yùn)算符連接。如果連接條件要求兩列值相等,則稱(chēng)為等值連接,否則稱(chēng)為非等值連接;如果沒(méi)有任何連接條件,則被稱(chēng)為廣義笛卡兒積,SQL92中多表連接查詢的語(yǔ)法格式如下:
select column1,colum2... from table1,table2... [where join_coondition]多表連接查詢中可能出現(xiàn)兩個(gè)或多個(gè)數(shù)據(jù)列具有相同的列名,則需要在這些同名列之間使用表名前綴或表別名前綴作為限制,避免系統(tǒng)混淆。
如果只是單表查詢是不可能重復(fù)的,但是多表查詢應(yīng)該加上前綴或表別名。
如下SQL語(yǔ)句查詢出所有學(xué)生的資料以及對(duì)應(yīng)的老師姓名。
實(shí)際上,多表查詢的過(guò)程可以理解成一個(gè)嵌套循環(huán)。這個(gè)嵌套循環(huán)的偽碼如下:
與此類(lèi)似的是,非等值連接的執(zhí)行結(jié)果可以使用上面的嵌套循環(huán)來(lái)計(jì)算,SQL語(yǔ)句如下:
select s.*,teacher_name #指定多個(gè)數(shù)據(jù)表,并指定表別名 from student_table s,teacher_table t #使用where指定連接條件,并指定student_name列不能為null where s.java_teacher = t.teacher_id and student_name is ot null;SQL不支持SQL 92的左外連接、右外連接。
自連接只是連接的一種用法,并不是一種連接類(lèi)型,不管是SQL92還是SQL99棟可以使用自連接查詢。自連接本質(zhì)就是把一個(gè)表當(dāng)兩個(gè)表來(lái)用。
下面的SQL語(yǔ)句建立了一個(gè)自連接的數(shù)據(jù)表,并向表中插入了4條數(shù)據(jù)。
如果需要查詢?cè)摂?shù)據(jù)表中的所有員工名,以及每個(gè)員工對(duì)應(yīng)的經(jīng)理名,則必須使用自連接查詢。所謂自連接就是把一個(gè)表當(dāng)成兩個(gè)表來(lái)用,這就需要為一個(gè)表起兩個(gè)別名,而且查詢中用的所有數(shù)據(jù)列都要加表別名前綴,因?yàn)閮蓚€(gè)表數(shù)據(jù)完全一樣。下面的自連接查詢可以查詢出所有的員工名,以及對(duì)應(yīng)的經(jīng)理名。
select emp.emp_id,emp.emp_name 員工名, mar.emp_name 經(jīng)理名 from emp_table emp,emp_table mgr where emp.manager_id = mgr.emp_id;SQL99的連接查詢
SQL99的連接查詢與SQL 92的連接查詢?cè)砘鞠嗨?#xff0c;不同的是SQL99連接查詢的可讀性更強(qiáng)——查詢用多個(gè)數(shù)據(jù)表顯式使用 xxx join連接,而不是直接依次排列在from之后,from后只需要放一個(gè)數(shù)據(jù)表;連接條件不再放在where之后,而是提供了專(zhuān)門(mén)的連接條件子句。
- 交叉連接(cross join):交叉連接效果就是SQL92中的廣義笛卡兒積,所以交叉連接無(wú)須任何條件。
- 自然連接(natural join):自然連接表面上看起來(lái)也無(wú)須指定連接條件,但自然連接是有連接條件的,自然連接會(huì)以兩個(gè)表中的同名列作為連接條件;如果兩個(gè)表中沒(méi)有同名列,則自然連接與交叉連接效果完全一樣——因?yàn)闆](méi)有連接條件。
- using子句連接:using子句可以指定一列或多列,用于顯式指定兩個(gè)表中的同名列作為連接條件。假設(shè)兩個(gè)表中有超過(guò)一列的同名列,如果使用natural join ,則會(huì)把所有的同名列當(dāng)成連接條件;使用using子句,就可顯式指出使用哪些同名列作為連接條件。SQL語(yǔ)句如下:
運(yùn)行上面語(yǔ)句將出現(xiàn)一個(gè)錯(cuò)誤,因?yàn)閟tudent_table表中并不存在名為teacher_id的列,也就是說(shuō),如果使用using子句來(lái)指定連接條件,則兩個(gè)表必須有同名列,否則將會(huì)出現(xiàn)錯(cuò)誤。
- on子句連接:這是最常用的連接方式,SQL99語(yǔ)法的連接條件放在on子句只指定一個(gè)連接條件。這意味著:如果需要進(jìn)行N表連接,則需要有N-1個(gè)join…on對(duì)。
使用on子句的連接完全可以替代SQL92的等值連接、非等值連接,因?yàn)閛n子句的連接條件除等值條件之外,也可以是非等值條件。如下SQ語(yǔ)句就是SQL99中的非等值連接。
select s.*,teacher_name #SQL 99多表連接查詢的from后只有一個(gè)表名 from student_table s #join連接另一個(gè)表 #使用on來(lái)指定連接條件;非等值連接 on s.java_teacher>t.teacher_id;- 左、右、全外連接:這三種外連接分別使用left[outer] join、right[outer]join和full[outer]join,這三種外連接的連接條件一樣通過(guò)on子句來(lái)指定,既可以是等值連接條件,也可以是非等值連接條件。
下面使用右外連接,連接條件時(shí)非等值連接
內(nèi)連接:結(jié)合兩張表的記錄,返回相關(guān)的查詢結(jié)果,返回的是兩個(gè)表的交集部分。 關(guān)鍵字:INNER JOIN
左連接:左連接查詢,左表的信息全部展示出來(lái),右表只會(huì)展示符合搜索條件的信息,不滿足的地方記為NULL 關(guān)鍵字:LEFT JOIN
右連接:右連接查詢,右表的信息全部展示出來(lái),左表只會(huì)展示符合搜索條件的信息,不滿足的地方記為NULL RIGHT JOIN
來(lái)自該博主的借鑒。
下面使用左外連接,連接條件是非等值連接。
不難發(fā)現(xiàn)SQL99與SQL92外連接恰好相反,SQL99左外連接會(huì)把左邊表中所有不滿足連接條件的記錄全部列出;SQL99右外連接將會(huì)把右邊表中所有不滿足條件的記錄全部列出。
下面的SQL語(yǔ)句使用全外連接,連接條件是等值連接。
會(huì)出錯(cuò)誤,因?yàn)镸ySQL并不支持全外連接。
這些查詢我也懵,到了JDBC多練練就行了,現(xiàn)在有點(diǎn)抽象
子查詢
子查詢就是指定查詢語(yǔ)句中嵌套另一個(gè)查詢,子查詢可以支持多層嵌套。對(duì)于一個(gè)普通的查詢語(yǔ)句而言,子查詢可以出現(xiàn)在兩個(gè)位置。
- 出現(xiàn)在from語(yǔ)句后當(dāng)成數(shù)據(jù)表,這種用法也被稱(chēng)為行內(nèi)視圖,因?yàn)樵撟硬樵兊膶?shí)質(zhì)就是一個(gè)臨時(shí)視圖。
- 出現(xiàn)在where條件后作為過(guò)濾條件的值
使用子查詢時(shí)要注意如下幾點(diǎn)。 - 子查詢要用括號(hào)括起來(lái)
- 把子查詢當(dāng)數(shù)據(jù)表時(shí)(出現(xiàn)在from之后),可以為該子查詢起別名,尤其是作為前綴來(lái)限定數(shù)據(jù)列時(shí),必須給子查詢起別名。
- 把子查詢當(dāng)成過(guò)濾條件時(shí),將子查詢放在比較運(yùn)算符的右邊,這樣可增強(qiáng)程序的可讀性。
- 把子查詢當(dāng)成過(guò)濾條件時(shí),單行子查詢使用單行運(yùn)算符,多行子查詢使用多行運(yùn)算符。
對(duì)于把子查詢當(dāng)成數(shù)據(jù)表是完全把子查詢當(dāng)做數(shù)據(jù)表來(lái)用,只是把之前的表名變成子查詢(也可為子查詢起別名),其他部分與普通查詢沒(méi)有任何區(qū)別。下面SQL語(yǔ)句示范了把子查詢當(dāng)數(shù)據(jù)表的用法。
把子查詢當(dāng)數(shù)據(jù)表的用法更準(zhǔn)確地說(shuō)是當(dāng)成視圖,可以把上面的SQL語(yǔ)句理解成在執(zhí)行查詢時(shí)創(chuàng)建了一個(gè)臨時(shí)視圖,該視圖名為t,所以這種臨時(shí)創(chuàng)建的視圖被稱(chēng)為行內(nèi)視圖。
還有一種情形:把子查詢當(dāng)where條件中的值,如果子查詢返回單行、單列值,則被當(dāng)成一個(gè)標(biāo)準(zhǔn)量使用,也就是可以單行記錄比較運(yùn)算符。例如如下SQL語(yǔ)句:
先加一個(gè)數(shù)據(jù)
這里因?yàn)榍懊娑际窍嗟鹊?#xff0c;所以只有最后幾列輸出了出來(lái)。比如容易誤導(dǎo)。
上面查詢語(yǔ)句中的子查詢將返回一個(gè)單行、單列值(該值就是1),如果把上面查詢語(yǔ)句的括號(hào)部分換位1,那么這條語(yǔ)句就再簡(jiǎn)單不過(guò)了——實(shí)際上,這就是這種子查詢的實(shí)質(zhì),單行、單列子查詢被當(dāng)成標(biāo)準(zhǔn)量處理。
如果子查詢返回多個(gè)值,則需要使用in、any和all等關(guān)鍵字,in可以單獨(dú)使用,與前面介紹比較運(yùn)算符所講的in完全一樣,此時(shí)可以把子查詢返回的多個(gè)值當(dāng)成一個(gè)值列表。
上面查詢語(yǔ)句中的子查詢將返回多個(gè)值,這多個(gè)值將被當(dāng)成一個(gè)值列表,只要student_id與該值列表的任意一個(gè)值相等,就可以選中這條記錄。
any和all可以與>、>=、<、<=、<>、=等運(yùn)算符結(jié)合使用,與any結(jié)合使用分表表示大于、大于等于、小于、小于等于、不等于、等于其中任意一個(gè)值;與all結(jié)合使用分別表示大于、大于等于、小于、小于等于、不等于、等于全部值。從上面介紹可以看出,=any的作用與in的作用相同。如下語(yǔ)句使用=any來(lái)替代上面的in。
還有一種子查詢可以返回多行、多列,此時(shí)where子句中應(yīng)該有對(duì)應(yīng)的數(shù)據(jù)列,并使用圓括號(hào)將多個(gè)數(shù)據(jù)列組合起來(lái)。SQL語(yǔ)句如下:
查了個(gè)寂寞,我們直接看集合運(yùn)算然后看JDBC基礎(chǔ)入門(mén)。
集合運(yùn)算
select語(yǔ)句查詢的結(jié)果是一個(gè)包含多條數(shù)據(jù)的結(jié)果級(jí),類(lèi)似于數(shù)學(xué)里的集合,還可以進(jìn)行交(intersect)、并(union)和差(minus)運(yùn)算,select查詢得到的結(jié)果集也可能需要進(jìn)行這三種運(yùn)算。
為了對(duì)兩個(gè)結(jié)果集進(jìn)行集合運(yùn)算。這兩個(gè)結(jié)果集必須滿足如下條件。
- 兩個(gè)結(jié)果集所包含的數(shù)據(jù)列的數(shù)量必須相等。
- 兩個(gè)結(jié)果集所包含的數(shù)據(jù)列的數(shù)據(jù)類(lèi)型也必須一一對(duì)應(yīng)。
1.unicon運(yùn)算
union運(yùn)算的語(yǔ)法格式如下:
select 語(yǔ)句 union select 語(yǔ)句下面的SQL語(yǔ)句查詢出所有教師的信息和主鍵小于4的學(xué)生信息。
2.minus運(yùn)算
minus運(yùn)算的語(yǔ)法格式如下:
select 語(yǔ)句 minus select 語(yǔ)句上面的語(yǔ)法格式十分簡(jiǎn)單,不過(guò)很遺憾,MySQL并不支持使用minus運(yùn)算符們只能借助于子查詢來(lái)“曲線”實(shí)現(xiàn)上面的minus運(yùn)算。
假如向從所有學(xué)生記錄中“減去”與老師記錄的ID相同、姓名相同的記錄,則可進(jìn)行如下的minus運(yùn)算
MySQL并不支持這種運(yùn)算。但可以通過(guò)如下子查詢來(lái)實(shí)現(xiàn)上面的運(yùn)算。
3.intersect運(yùn)算
intersect運(yùn)算的語(yǔ)法格式如下:
select 語(yǔ)句 intersect select 語(yǔ)句上面的語(yǔ)法格式十分簡(jiǎn)單,不過(guò)很遺憾,MySQL并不支持使用intersect運(yùn)算符,因此只能借助于多表連接查詢來(lái)“曲線”實(shí)現(xiàn)上面的intersect運(yùn)算。
假如想找出學(xué)生記錄中與老師記錄中的ID相同、姓名相同的記錄,則可以進(jìn)行如下的intersect運(yùn)算。
不過(guò)MySQL并不支持這種運(yùn)算。但可以通過(guò)如下多表連接查詢來(lái)實(shí)現(xiàn)上面運(yùn)算。
需要指出的是,如果進(jìn)行intersect運(yùn)算的兩個(gè)select子句中都包括了where條件,那么將intersect運(yùn)算改成多表連接查詢后還需要將兩個(gè)where條件進(jìn)行and運(yùn)算。假如有如下intersect運(yùn)算的SQL語(yǔ)句:
上面語(yǔ)句改寫(xiě)如下;
某種意義上來(lái)說(shuō) 沒(méi)有數(shù)據(jù)就是查詢了個(gè)寂寞。
JDBC的典型用法
重頭戲來(lái)了。
連接方式
準(zhǔn)備好驅(qū)動(dòng)JAR包即可
本文章就此結(jié)束了,加油哦。
總結(jié)
以上是生活随笔為你收集整理的MySQL基础学习特殊篇 入门限定的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Qt 多线程并发高阶类QtConcurr
- 下一篇: Mysql数据库课程设计