001.MYSQL資料庫概念+資料庫分類
資料庫概念
資料庫(Database)是按照資料結構來組織、儲存和管理資料的建立在計算機儲存裝置上的倉庫。
資料庫分類
網路資料庫:指把資料庫技術引入到計算機網路系統中,藉助於網路技術將儲存於資料庫中的大量資訊及時釋出出去;而計算機網路藉助於成熟的資料庫技術對網路中的各種資料進行有效管理,並實現使用者與網路中的資料庫進行實時動態資料互動。
層級資料庫:層次結構模型實質上是一種有根結點的定向有序樹(在數學中"樹"被定義為一個無回的連通圖)。
關係資料庫:是建立在關係模型基礎上的資料庫,藉助於集合代數等數學概念和方法來處理資料庫中的資料。
資料庫的另外一種區分方式:基於儲存介質(磁碟和記憶體),關係型資料庫儲存在磁碟中,非關係型資料庫儲存在記憶體中。
關係型資料庫
基本概念:關係資料庫,是建立在關係模型基礎上的資料庫,藉助於集合代數等數學概念和方法來處理資料庫中的資料。現實世界中的各種實體以及實體之間的各種聯絡均用關係模型來表示。關係模型是由埃德加·科德於1970年首先提出的,並配合“科德十二定律”。現如今雖然對此模型有一些批評意見,但它還是資料儲存的傳統標準。關係模型由關係資料結構、關係操作集合、關係完整性約束三部分組成。
關係資料結構:指的資料以什麼方式來儲存,是一種二維表的形式儲存。
姓名 |
年齡 |
身高 |
體重 |
張三 |
30 |
187 |
70 |
李四 |
40 |
|
|
關係操作集合:如何來關聯和管理對應的儲存資料,SQL指令。
關係完整性約束:資料內部有對應的關聯關係,以及資料與資料之間也有對應的關聯關係。
姓名 |
年齡 |
身高 |
體重 |
張三 |
30 |
187 |
70 |
李四 |
40 |
|
|
表內約束:對應的具體列只能放對應的資料(不能亂放)
表間約束:自然界各實體都是有著對應的關聯關係(外來鍵)
典型關係型資料庫
Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL、SQLite
小型關係型資料庫:Microsoft Access,SQLite
中型關係型資料庫:SQL Server,Mysql
大型關係型資料庫:Oracle,DB2
Mysql當前跟Oracle是一個公司的:隸屬於Oracle
SQL介紹
SQL基本介紹:結構化查詢語言(Structured Query Language)簡稱SQL,是一種特殊目的的程式語言,是一種資料庫查詢和程式設計語言,用於存取資料以及查詢、更新和管理關係資料庫系統;同時也是資料庫指令碼檔案的副檔名。SQL就是專門為關係型資料庫而設計出來的。
SQL分類
1.資料查詢語言(DQL:Data Query Language):其語句,也稱為“資料檢索語句”,用以從表中獲得資料,確定資料怎樣在應用程式給出。保留字SELECT是DQL(也是所有SQL)用得最多的動詞,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。這些DQL保留字常與其他型別的SQL語句一起使用。
2.資料操作語言(DML:Data Manipulation Language):其語句包括動詞INSERT,UPDATE和DELETE。它們分別用於新增,修改和刪除表中的行。也稱為動作查詢語言。
3.事務處理語言(TPL):它的語句能確保被DML語句影響的表的所有行及時得以更新。TPL語句包括BEGIN TRANSACTION,COMMIT和ROLLBACK(不是所有的關係型資料庫都提供事務安全處理)。
4.資料控制語言(DCL):它的語句通過GRANT或REVOKE獲得許可,確定單個使用者和使用者組對資料庫物件的訪問。某些RDBMS可用GRANT或REVOKE控制對錶單個列的訪問。
5.資料定義語言(DDL):其語句包括動詞CREATE和DROP。在資料庫中建立新表或刪除表(CREAT TABLE 或 DROP TABLE);為表加入索引等。DDL包括許多與人資料庫目錄中獲得資料有關的保留字。它也是動作查詢的一部分。
MySQL基本介紹:MySQL是一個關係型資料庫管理系統,由瑞典MySQL AB 公司開發,目前屬於 Oracle 旗下產品。MySQL 是最流行的關係型資料庫管理系統之一,在 WEB 應用方面,MySQL是最好的 RDBMS (Relational Database Management System,關係資料庫管理系統) 應用軟體。Mysql是一種開源免費的資料庫產品,Mysql對PHP的支援是最好(wamp或者lamp)。
啟動和停止MySQL服務
Mysql是一種C/S結構:客戶端和服務端
服務端對應的軟體:Mysqld.exe
命令列方式:通過Windows下開啟cmd控制器,然後使用命令進行管理
Net start 服務(mysql):開啟服務
Net stop mysql:關閉服務
系統服務方式:在安裝的Mysql的時候將mysql新增到Windows的服務中去了,通過服務對Mysql伺服器進行管理。
登入和退出MySQL系統:通過客戶端(mysql.exe)與伺服器進行連線認證,就可以進行操作。
通常:服務端與客戶端不在同一臺電腦上
登入:
1.找到mysql.exe(通過cmd控制檯:如果在安裝的時候指定了mysql.exe所在的路徑為環境變數,就可以直接訪問;如果沒有,那麼就必須進入到mysql.exe所在路徑)
2. 輸入對應的伺服器地址:-h:host -h[IP地址/域名]
3. 輸入伺服器中Mysql監聽的埠: -P:port –P:3306
4. 輸入使用者名稱:-u:username -u:root
5. 輸入密碼:-p:password –p:root
連線認證基本語法:Mysql.exe/mysql -h主機地址 -P埠 -u使用者名稱 -p密碼
注意事項:
1.通常埠都可以預設:mysql堅挺的埠通常都是3306
2.密碼的輸入可以先輸入-p,直接換行,然後再以密文方式輸入密碼
退出:斷開與伺服器的連線:通常Mysql提供的伺服器數量有限,一旦客戶端用完,建議就應該斷開連線。
建議方式:使用SQL提供的指令。Exit;\q;Quit;
Mysql服務端架構有以下幾層構成:
1.資料庫管理系統(最外層):DBMS,專門管理伺服器端的所有內容
2.資料庫(第二層):DB,專門用於儲存資料的倉庫(可以有很多個)
3.二維資料表(第三層):Table,專門用於儲存具體實體的資料
4.欄位(第四層):Field,具體儲存某種型別的資料(實際儲存單元)
資料庫中常用的幾個關鍵字:Row行、Column列(field)
資料庫基本操作
資料庫是資料儲存的最外層(最大單元)
建立資料庫
基本語法:create database 資料庫名字 [庫選項];
庫選項:資料庫的相關屬性
字符集:charset 字符集,代表著當前資料庫下的所有表儲存的資料預設指定的字符集(如果當前不指定,那麼採用DBMS預設的)
校對集:collate 校對集
Create database 資料庫名字 charset 字符集名稱;
顯示資料庫:每當使用者通過SQL指令建立一個數據庫,那麼系統就會產生一個對應的儲存資料的資料夾(data)。其實,每個資料庫資料夾下都有一個opt檔案,儲存的是對應的資料庫選項。
顯示全部
基本語法:show databases;
顯示部分
基本語法:show databases like ‘匹配模式’;
_:匹配當前位置單個字元
%:匹配指定位置多個字元
顯示資料庫建立語句
基本語法:show create database 資料庫名字;
選擇資料庫基本語法:use 資料庫名字;
為什麼要選擇資料庫?因為資料是儲存到資料表,表存在資料庫下。如果要操作資料,那麼必須進入到對應的資料庫才行。
修改資料庫基本語法:alter database 資料庫名字 charset = 字符集;
修改資料庫字符集(庫選項):字符集和校對集
一旦修改成功,那麼對應的opt檔案中就會體現
是否可以修改資料庫名字?mysql5.5之前是可以修改的rename命令;但是5.5之後就不可以。
刪除資料庫
基本語法:drop database 資料庫名字;
刪除雖簡單,但是切記要做好安全操作:確保裡面資料沒有問題。(重要)
刪除資料庫之後:對應的儲存資料的資料夾也會被刪除(opt檔案也被刪除)
資料表操作
建立資料表
普通建立表
基本語法:create table 表名(欄位名 欄位型別 [欄位屬性],欄位名 欄位型別 [欄位屬性],…) [表選項]
表必須放到對應的資料庫下:有兩種方式可以將表掛入到指定的資料庫下。
1.在資料表名字前面加上資料庫名字,用“.”連線即可:資料庫.資料表
2.在建立資料表之前先進入到某個具體的資料庫即可:use 資料庫名字;
表選項:與資料庫選項類似
Engine:儲存引擎,mysql提供的具體儲存資料的方式,預設有一個innodb(5.5以前預設是myisam)
Charset:字符集,只對當前自己表有效(級別比資料庫高)
Collate:校對集
複製已有表結構:從已經存在的表複製一份(只複製結構:如果表中有資料不復制)
基本語法:create table 新表名 like 表名; //只要使用資料庫.表名,就可以在任何資料庫下訪問其他資料庫的表名
顯示資料表:每當一張資料表建立,那麼就會在對應的資料庫下建立一些檔案(與儲存引擎有關)
注意:這個結構檔案來自於innodb儲存引擎,innodb儲存引擎所有的檔案都儲存在外部的ibdata檔案中
顯示所有表
基本語法:show tables;
匹配顯示錶
基本語法:show tables like ‘匹配模式’;
顯示錶結構
本質含義:顯示錶中所包含的欄位資訊(名字,型別,屬性等)
Describe 表名
Desc 表名
show columns from 表名
顯示錶建立語句基本語法:show create table 表名;
檢視資料表建立時的語句:此語句看到的結果已經不是使用者之前自己輸入的。
Mysql中有多種語句結束符
;與\g所表示的效果是一樣的,都是欄位在上排橫著,下面跟對應的資料
\G欄位在左側豎著,資料在右側橫著
設定表屬性基本語法:alter table 表名 表選項 [=] 值;
表屬性指的就是表選項:engine,charset和collate
注意:如果資料庫已經確定了,裡面有很多資料了,不要輕易修改表選項(字符集影響不大)
修改表結構
修改表名:rename table 舊錶名 to 新表名
修改表選項:alter table 表名 表選項 [=] 新值
新增欄位:alter table 表名 add [column] 新欄位名 列型別 [列屬性] [位置first/after 欄位名]
欄位位置:欄位想要存放的位置
First:在某某之前(最前面),第一個欄位
After 欄位名:放在某個具體的欄位之後(預設的)
修改欄位名:alter table 表名 change 舊欄位名 新欄位名 欄位型別 [列屬性] [新位置]
修改欄位型別(屬性):alter table 表名 modify 欄位名 新型別 [新屬性] [新位置]
刪除欄位:alter table 表名 drop 欄位名
刪除表結構
基礎語法:drop table 表名[,表名2…],可以同時刪除多個數據表
批量刪除表
資料基礎操作
插入操作
本質含義:將資料以SQL的形式儲存到指定的資料表(欄位)裡面
基本語法:向表中指定欄位插入資料
Insert into 表名[(欄位列表)] values(對應欄位列表)
1. 注意:後面(values中)對應的值列表只需要與前面的欄位列表相對應即可(不一定與表結構完全一致)
2. 注意:欄位列表並不一定非要有所有的表中欄位
基本語法:向表中所有欄位插入資料
Insert into 表名 values(對應表結構) //值列表必須與欄位列表一致
查詢操作
查詢表中全部資料:select * from 表名; //*表示匹配所有的欄位
查詢表中部分欄位:select 欄位列表 from 表名; //欄位列表使用逗號“,”隔開
簡單條件查詢資料:select 欄位列表/* from 表名 where 欄位名 = 值; //mysql中沒有==符號
刪除操作
基本語法:delete from 表名 [where 條件]; //如果沒有where條件:意味著系統會自動刪除該表所有資料(慎用)
更新操作:將資料進行修改(通常是修改部分欄位資料)
基本語法:update 表名 set 欄位名 = 新值 [where 條件];//如果沒有where條件,那麼所有的表中對應的那個欄位都會被修改成統一值。
字符集
字元編碼概念
字元(Character)是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。在計算機中所看到的任何內容都是字元構成的。
字元編碼(character code)是計算機針對各種符號,在計算機中的一種二進位制儲存代號。
字符集概念:字符集(Character set)是多個字元的集合,字符集種類較多,每個字符集包含的字元個數不同。
常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。計算機要準確的處理各種字符集文字,需要進行字元編碼,以便計算機能夠識別和儲存各種文字。中文文字數目大,而且還分為簡體中文和繁體中文兩種不同書寫規則的文字,而計算機最初是按英語單位元組字元設計的,因此,對中文字元進行編碼,是中文資訊交流的技術基礎。
設定客戶端所有字符集
如果直接通過cmd下的mysql.exe進行中文資料插入,那麼可能出錯
出錯原因:
1.使用者是通過mysql.exe來操作mysqld.exe
2. 真正的SQL執行是Mysqld.exe來執行
3. mysql.exe將資料傳入mysqld.exe的時候,沒有告知其對應的符號規則(字符集),而mysqld也沒有能力自己判斷,就會使用自己預設的(字符集)
解決方案:mysql.exe客戶端在進行資料操作之前將自己所使用的字符集告訴mysqld
Cmd下的mysql.exe預設都只有一個字符集:GBK
Mysql.exe如果告知Mysqld.exe對應的字符集型別為gbk?
快捷方式:set names 字符集
重新進行資料插入:中文(GBK)
深層原理:客戶端,服務端,連線層(show variables like ‘character_set_%’)
Mysql.exe與Mysqld.exe之間的處理關係一共分為三層
客戶端傳入資料給服務端:client:character_set_client
服務端返回資料給客戶端:server:character_set_results
客戶端與服務端之間的連線:connection:character_set_connection
Set names 字符集的本質:就是一次性打通三層關係的字符集,變得一致。
在系統中有三個變數來記錄著這三個關係對應的字符集:show variables like ‘character_set_%’;
檢視一個新的客戶端的對應的字符集關係
修改伺服器端變數的值
Set 變數名 = 值;
重新進行資料插入和檢視的結果:插入OK,但是檢視亂碼
修改結果字符集為GBK
Connection只是為了更方便客戶端與服務端進行字符集轉換而設。
Set names gbk;
Set character_set_client = gbk; //為了讓伺服器識別客戶端傳來的資料
Set character_set_connection = gbk;//更好的幫助客戶端與服務端之間進行字符集轉換
Set character_set_results = gbk;//為了告訴客戶端服務端所有的返回的資料字符集
列型別(欄位型別)
整數型別
Tinyint:迷你整形,系統採用一個位元組來儲存的整形:一個位元組 = 8位,最大能表示的數值是0-255
Smallint:小整形,系統採用兩個位元組來儲存的整形:能表示0-65535之間
Mediumint:中整形,採用三個位元組來儲存資料。
Int:整形(標準整形),採用四個位元組來儲存資料。
Bigint:大整形,採用八個位元組來儲存資料。
1. 建立資料表
2. 插入合理資料
3. 插入錯誤資料(超出對應的資料範圍)
4.錯誤原因:並不是說tinyint沒有這麼大的空間,而是因為mysql預設的為整形增加負數。
實際表示的區間為-128,127
實際應用中,應該根據對應的資料的範圍來選定對應的整形型別:通常使用的比較多的TINYINT和int。
無符號標識設定
無符號:表示儲存的資料在當前欄位中,沒有負數(只有正數,區間為0-255)
基本語法:在型別之後加上一個 unsigned
顯示長度
顯示長度:指資料(整型)在資料顯示的時候,到底可以顯示多長位。
Tinyint(3): 表示最長可以顯示3位,unsigned說明只能是正數,0-255永遠不會超過三個長度
Tinyint(4):表示最長可以顯示4位,-128~127
顯示長度只是代表了資料是否可以達到指定的長度,但是不會自動滿足到指定長度:如果想要資料顯示的時候,保持最高位(顯示長度),那麼還需要給欄位增加一個zerofill屬性才可以。
Zerofill:從左側開始填充0(左側不會改變數值大小),所以負數的時候就不能使用zerofill,一旦使用zerofill就相當於確定該欄位為unsigned
資料顯示的時候,zerofill會在左側填充0到指定位:如果不足3位,那麼填充到3位,如果本身已經夠了或者超出,那麼就不在填充。
顯示長度可以自己設定:超出長度(但是不超出範圍)不會影響,只會對不夠長度的進行補充(顯示長度)
小數型別
專門用來儲存小數的。在Mysql中將小數型別又分為兩類:浮點型和定點型
浮點型
浮點型又稱之為精度型別:是一種有可能丟失精度的資料型別,資料有可能不那麼準確(由其是在超出範圍的時候)
浮點型之所以能夠儲存較大的數值(不精確),原因就是利用儲存資料的位來儲存指數
整型:所有位都為1
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
計算結果:
浮點型:有部分用於儲存資料,有部分用於存指數
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
前三位轉換成十進位制之後用作10的指數: 10^7 * 資料值
Float
Float又稱之為單精度型別:系統提供4個位元組用來儲存資料,但是能表示的資料範圍比整型大的多,大概是10^38;只能保證大概7個左右的精度(如果資料在7位數以內,那麼基本是準確的,但是如果超過7位數,那麼就是不準確的)
基本語法
Float:表示不指定小數位的浮點數
Float(M,D):表示一共儲存M個有效數字,其中小數部分佔D位
Float(10,2):整數部分為8位,小數部分為2位
1. 建立一個數據表儲存浮點資料
2. 存入資料:合法資料
注意:如果資料精度丟失,那麼浮點型是按照四捨五入的方式進行計算
3. 插入資料,超出大小
4.資料長度剛好滿足條件,但是會超出精度
說明:使用者不能插入資料直接超過指定的整數部分長度,但是如果是系統自動進位導致,系統可以承擔。
5.浮點數可以採用科學計數法來儲存資料
浮點數的應用:通常是用來儲存一些數量特別大,大到可以不用那麼精確的資料。
Double
Double又稱之為雙精度:系統用8個位元組來儲存資料,表示的範圍更大,10^308次方,但是精度也只有15位左右。
定點數
定點數:能夠保證資料精確的小數(小數部分可能不精確,超出長度會四捨五入),整數部分一定精確
Decimal
Decimal定點數:系統自動根據儲存的資料來分配儲存空間,每大概9個數就會分配四個位元組來進行儲存,同時小數和整數部分是分開的。
Decimal(M,D):M表示總長度,最大值不能超過65,D代表小數部分長度,最長不能超過30。
1. 建立表:與浮點數對比
2.插入正常資料
3. 插入最大資料
4.嘗試定點數進行四捨五入
定點數的應用:如果涉及到錢的時候有可能使用定點數
時間日期型別
Date
日期型別:系統使用三個位元組來儲存資料,對應的格式為:YYYY-mm-dd,能表示的範圍是從1000-01-01 到9999-12-12,初始值為0000-00-00
Time
時間型別:能夠表示某個指定的時間,但是系統同樣是提供3個位元組來儲存,對應的格式為:HH:ii:ss,但是mysql中的time型別能夠表示時間範圍要大的多,能表示從-838:59:59~838:59:59,在mysql中具體的用處是用來描述時間段。
Datetime
日期時間型別:就是將前面的date和time合併起來,表示的時間,使用8個位元組儲存資料,格式為YYYY-mm-dd HH:ii:ss,能表示的區間1000-01-01 00:00:00 到9999-12-12 23:59:59,其可以為0值:0000-00-00 00:00:00
Timestamp
時間戳型別:mysql中的時間戳只是表示從格林威治時間開始,但是其格式依然是:YYYY-mm-dd HH:ii:ss
Year
年型別:佔用一個位元組來儲存,能表示1900~2155年,但是year有兩種資料插入方式:0~99和四位數的具體年
1. 建立對應的時間日期型別的資料表
2.插入資料:正常資料
3. year的特殊性:可以採用兩位數的資料插入,也可以採用四位數的年份插入
4. year進行兩位數插入的時候,有一個區間劃分,零界點為69和70:當輸入69以下,那麼系統時間為20+數字,如果是70以上,那配系統時間為19+數字
5. timestamp當對應的資料被修改的時候,會自動更新(這個被修改的資料不是自己)
6.time型別特殊性:本質是用來表示時間區間(當前時間之後的多少個小時),能表示的範圍比較大
7. 在進行時間類型錄入的時候(time)還可以使用一個簡單的日期代替時間,在時間格式之前加一個空格,然後指定一個數字(可以是負數):系統會自動將該數字轉換成天數 * 24小時,再加上後面的時間。
PHP中有著非常強大的時間日期轉換函式:date將時間戳轉換成想要的格式,strtotime又可以將很多格式轉換成對應的時間戳。PHP通常不需要資料庫來幫助處理這麼複雜的時間日期,所以通常配合PHP的時候,時間的儲存通常使用時間戳(真正),從而用整型來儲存。字串型
Mysql記錄長度
在mysql中,有一項規定:mysql的記錄長度(record == 行row)總長度不能超過65535個位元組。
Varchar能夠儲存的理論值為65535個字元:字元在不同的字符集下可能佔用多個位元組。
1. 建立表:證明varchar在mysql中能夠達到的理論值(utf8和GBK)
Varchar除了儲存的資料本身要佔用空間:還需要額外的空間來儲存記錄長度
2. 計算在utf8和GBK下對應的varchar能夠儲存的長度
Utf8 最多隻能儲存21844個字元
GBK最多隻能儲存32766個字元
字串型
Char
定長字元:指定長度之後,系統一定會分配指定的空間用於儲存資料
基本語法:char(L),L代表字元數(中文與英文字母一樣),L長度為0到255
Varchar
變長字元:指定長度之後,系統會根據實際儲存的資料來計算長度,分配合適的長度(資料沒有超出長度)
基本語法:Varchar(L),L代表字元數,L的長度理論值位0到65535
因為varchar要記錄資料長度(系統根據資料長度自動分配空間),所以每個varchar資料產生後,系統都會在資料後面增加1-2個位元組的額外開銷:是用來儲存資料所佔用的空間長度
如果資料本身小於127個字元:額外開銷一個位元組;如果大於127個,就開銷兩個位元組
Char和varchar資料儲存對比(utf8,一個字元都會佔用3個位元組)
儲存資料 |
Char(2) |
Varchar(2) |
Char所佔位元組 |
Varchar所佔位元組 |
A |
A |
A |
2 * 3 = 6 |
1 * 3 + 1 = 4 |
AB |
AB |
AB |
2 * 3 = 6 |
2 * 3 + 1 = 7 |
Char和varchar的區別
1.char一定會使用指定的空間,varchar是根據資料來定空間
2.char的資料查詢效率比varchar高:varchar是需要通過後面的記錄數來計算
如果確定資料一定是佔指定長度,那麼使用char型別;
如果不確定資料到底有多少,那麼使用varchar型別;
如果資料長度超過255個字元,不論是否固定長度,都會使用text,不再使用char和varchar
Text
文字型別:本質上mysql提供了兩種文字型別
Text:儲存普通的字元文字
Blob:儲存二進位制文字(圖片,檔案),一般都不會使用blob來儲存檔案本身,通常是使用一個連結來指向對應的檔案本身。
Text:系統中提供的四種text
Tinytext:系統使用一個位元組來儲存,實際能夠儲存的資料為:2 ^ 8 + 1
Text:使用兩個位元組儲存,實際儲存為:2 ^ 16 + 2
Mediumtext:使用三個位元組儲存,實際儲存為:2 ^ 24 + 3
Longtext:使用四個位元組儲存,實際儲存為:2 ^ 32 + 4
注意:
1. 在選擇對應的儲存文字的時候,不用刻意去選擇text型別,系統會自動根據儲存的資料長度來選擇合適的文字型別。
2.在選擇字元儲存的時候,如果資料超過255個字元,那麼一定選擇text儲存
Enum
列舉型別:在資料插入之前,先設定幾個項,這幾個項就是可能最終出現的資料結果。
如果確定某個欄位的資料只有那麼幾個值:如性別,男、女、保密,系統就可以在設定欄位的時候規定當前欄位只能存放固定的幾個值:使用列舉
基本語法:enum(資料值1,資料值2…)
系統提供了1到2個位元組來儲存列舉資料:通過計算enum列舉的具體值來選擇實際的儲存空間:如果資料值列表在255個以內,那麼一個位元組就夠,如果超過255但是小於65535,那麼系統採用兩個位元組儲存。
1. 建立表
2. 插入資料:合法資料,欄位對應的值必須是設定表的時候所確定的值
3. 錯誤資料:enum有規範資料的功能,能夠保證插入的資料必須是設定的範圍,其他型別都不可以
4. 列舉enum的儲存原理:實際上欄位上所儲存的值並不是真正的字串,而是字串對應的下標:當系統設定列舉型別的時候,會給列舉中每個元素定義一個下標,這個下標規則從1開始
Enum(1=>‘男’,2=>’女’,3=>’保密’)
特性:在mysql中系統是自動進行型別轉換的:如果資料碰到“+、-、*、/”系統就會自動將資料轉換成數值:而普通字串轉換成數值為0
Select 欄位名 + 0 from 表名;
5. 既然實際enum欄位儲存的結果是數值:那麼在進行資料插入的時候,就可以使用對應的數值來進行。
列舉的意義:
1.規範資料本身,限定只能插入規定的資料項
2.節省儲存空間
Set
集合:是一種將多個數據選項可以同時儲存的資料型別,本質是將指定的項按照對應的二進位制位來進行控制:1表示該選項被選中,0表示該選項沒有被選中。
基本語法:set(‘值1’,’值2’,’值3’…)
系統為set提供了多個位元組進行儲存,但是系統會自動計算來選擇具體的儲存單元
1個位元組:set只能有8個選項
2個位元組:set只能有16個選項
3個位元組:set只能表示24個選項
8個位元組:set可以表示64個選項
Set和enum一樣,最終儲存到資料欄位中的依然是數字而不是真實的字串
1. 建立表
2.插入資料:可以插入多個數據,就是在資料插入的字串中,使用對應的逗號“,”將選項進行隔開
3. 資料選項所在的資料與資料插入的順序無關:最終都會變成選項對應的順序
4.分析資料儲存的方式
系統將對應的資料選項(設計)按照順序進行編排:從第一個開始進行佔位,每一個都對應一個二進位制位。
資料在儲存的時候,如果被選中,那麼對應的位的值就為1,否則為0
系統在進行儲存的時候會自動將得到的最終的二進位制顛倒過來,然後再進行轉換成十進位制儲存
5. 檢視資料:按照自動轉換成數值來檢視
6.既然是數值,那麼就可以插入數值來代替實際插入資料
注意:數字插入的前提是對應的二進位制位上都有對應的資料項
Set集合的意義:
1.規範資料
2.節省儲存空間
Enum:單選框
Set:複選框
列屬性
列屬性又稱之為欄位屬性,在mysql中一共有6個屬性:null,預設值,列描述,主鍵,唯一鍵和自動增長
Null屬性
NULL屬性:代表欄位為空
如果對應的值為YES表示該欄位可以為NULL
注意:
1. 在設計表的時候,儘量不要讓資料為空
2.Mysql的記錄長度為65535個位元組,如果一個表中有欄位允許為NULL,那麼系統就會設計保留一個位元組來儲存NULL,最終有效儲存長度為65534個位元組。
預設值
Default:預設值,當欄位被設計的時候,如果允許預設條件下,使用者不進行資料的插入,那麼就可以使用事先準備好的資料來填充:通常填充的是NULL
測試:不給當前欄位提供資料值
Default關鍵字的另外一層使用:顯示的告知欄位使用預設值:在進行資料插入的時候,對欄位值直接使用default
列描述
列描述:comment,是專門用於給開發人員進行維護的一個註釋說明
基本語法:comment ‘欄位描述’;
檢視Comment:必須通過查看錶建立語句
主鍵
顧名思義:主要的鍵,primary key,在一張表中,有且只有一個欄位,裡面的值具有唯一性
建立主鍵
隨表建立
系統提供了兩種增加主鍵的方式
1.方案1:直接在需要當做主鍵的欄位之後,增加primary key屬性來確定主鍵
2.方案2:在所有欄位之後增加primary key選項:primary key(欄位資訊)
表後增加
基本語法:alter table 表名 add primary key(欄位);
檢視主鍵
方案1:查看錶結構
方案2:查看錶的建立語句
刪除主鍵
基本語法:alter table 表名 drop primary key;
複合主鍵
案例:有一張學生選修課表:一個學生可以選修多個選修課,一個選修課也可以由多個學生來選:但是一個學生在一個選修課中只有一個成績。
主鍵約束
主鍵一旦增加,那麼對對應的欄位有資料要求
1.當前欄位對應的資料不能為空;
2. 當前欄位對應的資料不能有任何重複
主鍵分類
主鍵分類採用的是主鍵所對應的欄位的業務意義分類
業務主鍵:主鍵所在的欄位,具有業務意義(學生ID,課程ID)
邏輯主鍵:自然增長的整型(應用廣泛)
自動增長
自動增長:auto_increment,當給定某個欄位該屬性之後,該列的資料在沒有提供確定資料的時候,系統會根據之前已經存在的資料進行自動增加後,填充資料。
通常自動增長用於邏輯主鍵。
原理
自動增長的原理:
1.在系統中有維護一組資料,用來儲存當前使用了自動增長屬性的欄位,記住當前對應的資料值,再給定一個指定的步長
2.當用戶進行資料插入的時候,如果沒有給定值,系統在原始值上再加上步長變成新的資料
3.自動增長的觸發:給定屬性的欄位沒有提供值
4.自動增長只適用於數值
使用自動增長
基本語法:在欄位之後增加一個屬性auto_increment
插入資料:觸發自動增長,不能給定具體值
修改自動增長
1.檢視自增長:自增長一旦觸發使用之後,會自動的在表選項中增加一個選項(一張表最多隻能擁有一個自增長)
2.表選項可以通過修改表結構來實現
Alter table 表名 auto_increment = 值;
刪除自動增長
刪除自增長:就是在欄位屬性之後不再保留auto_increment,當用戶修改自增長所在欄位時,如果沒有看到auto_increment屬性,系統會自動清除該自增長
初始設定
在系統中,有一組變數用來維護自增長的初始值和步長
Show variables like ‘auto_increment%’;
細節問題
1.一張表只有一個自增長:自增長會上升到表選項中
2.如果資料插入中沒有觸發自增長(給定了資料),那麼自增長不會表現
3.自增長修改的時候,值可以較大,但是不能比當前已有的自增長欄位的值小
唯一鍵
唯一鍵:unique key,用來保證對應的欄位中的資料唯一的。
主鍵也可以用來保證欄位資料唯一性,但是一張表只有一個主鍵。
1.唯一鍵在一張表中可以有多個。
2.唯一鍵允許欄位資料為NULL,NULL可以有多個(NULL不參與比較)
建立唯一鍵
建立唯一鍵與建立主鍵非常類似
1.直接在表字段之後增加唯一鍵識別符號:unique[ key]
2.在所有的欄位之後使用unique key(欄位列表);
3.在建立完表之後也可以增加唯一鍵
alter table 表名 add unique key(欄位列表);
檢視唯一鍵
唯一鍵是屬性,可以通過查看錶結構來實現
唯一鍵效果:在不為空的情況下,不允許重複
在查看錶建立語句的時候,會看到與主鍵不同的一點:多出一個“名字”
刪除唯一鍵
一個表中允許存在多個唯一鍵:假設命令為主鍵一樣:alter table 表名 drop unique key;//錯誤的
Index關鍵字:索引,唯一鍵是索引一種(提升查詢效率)
刪除的基本語法:alter table 表名 drop index 唯一鍵名字;
修改唯一鍵:先刪除後增加
複合唯一鍵
唯一鍵與主鍵一樣可以使用多個欄位來共同保證唯一性;
一般主鍵都是單一欄位(邏輯主鍵),而其他需要唯一性的內容都是由唯一鍵來處理。
表關係
表關係:表與表之間(實體)有什麼樣的關係,每種關係應該如何設計表結構。
一對一
一對一:一張表中的一條記錄與另外一張表中最多有一條明確的關係:通常,此設計方案保證兩張表中使用同樣的主鍵即可
學生表
學生ID(PRI) |
姓名 |
年齡 |
性別 |
籍貫 |
婚否 |
住址 |
|
|
|
|
|
|
|
表的使用過程中:常用的資訊會經常去查詢,而不常用的資訊會偶爾才會用到。
解決方案:將兩張表拆分,常見的放一張表,不常見的放一張表
常用表
學生ID(PRI) |
姓名 |
年齡 |
性別 |
|
|
|
|
不常用表
學生ID(PRI) |
籍貫 |
婚否 |
住址 |
|
|
|
|
一對多
一對多,通常也叫作多對一的關係。通常一對多的關係設計的方案,在“多”關係的表中去維護一個欄位,這個欄位是“一”關係的主鍵。
母親表
母親ID |
姓名 |
年齡 |
身高 |
M1 |
|
|
|
M2 |
|
|
|
孩子表
孩子ID |
姓名 |
年齡 |
身高
|
母親ID |
K1 |
|
|
|
M1 |
K2 |
|
|
|
M1 |
多對多
多對多:一張表中的一條記錄在另外一張表中可以匹配到多條記錄,反過來也一樣。
多對多的關係如果按照多對一的關係維護:就會出現一個欄位中有多個其他表的主鍵,在訪問的時候就會帶來不便。
既然通過兩張表自己增加欄位解決不了問題,那麼就通過第三張表來解決。
師生關係
1. 一個老師教過多個班級的學生;
2.一個學生聽過多個老師講的課;
首先得有兩個實體:老師表和學生表
從中間設計一張表:維護兩張表對應的聯絡:每一種聯絡都包含
多對多解決方案;增加一箇中間表,讓中間表與對應的其他表形成兩個多對一的關係:多對一的解決方案是在“多”表中增加“一”表對應的主鍵欄位。
高階資料操作
新增資料
多資料插入
只要寫一次insert指令,但是可以直接插入多條記錄
基本語法:insert into 表名 [(欄位列表)] values(值列表),(值列表)…;
主鍵衝突
主鍵衝突:在有的表中,使用的是業務主鍵(欄位有業務含義),但是往往在進行資料插入的時候,又不確定資料表中是否已經存在對應的主鍵。
主鍵衝突的解決方案:
1.主鍵衝突更新:
類似插入資料語法,如果插入的過程中主鍵衝突,那麼採用更新方法。
Insert into 表名 [(欄位列表)] values(值列表) on duplicate key update 欄位 = 新值;
2.主鍵衝突替換:
當主鍵衝突之後,幹掉原來的資料,重新插入進去。
Replace into [(欄位列表)] values(值列表);
蠕蟲複製
蠕蟲複製:一分為二,成倍的增加。從已有的資料中獲取資料,並且將獲取到的資料插入到資料表中。
基本語法:
Insert into 表名 [(欄位列表)] select */欄位列表 from 表;
注意:
1.蠕蟲複製的確通常是重複資料,沒有太大業務意義:可以在短期內快速增加表的資料量,從而可以測試表的壓力,還可以通過大量資料來測試表的效率(索引)
2.蠕蟲複製雖好,但是要注意主鍵衝突。
更新資料
1.在更新資料的時候,特別要注意:通常一定是跟隨條件更新
Update 表名 set 欄位名 = 新值 where 判斷條件;
2.如果沒有條件,是全表更新資料。但是可以使用limit 來限制更新的數量;
Update 表名 set 欄位名 = 新值 [where 判斷條件] limit 數量;
改變4個a變成e
Update my_simple set name = ‘e’ where name = ‘a’ limit 4;
刪除資料
1.刪除資料的時候儘量不要全部刪除,應該使用where進行 判定;
2.刪除資料的時候可以使用limit來限制要刪除的具體數量
Delete刪除資料的時候無法重置auto_increment
Mysql有一個能夠重置表選項中的自增長的語法;
Truncate 表名; ==è drop -à create
查詢資料
完整的查詢指令:
Select select選項 欄位列表 from 資料來源 where條件 group by分組 having條件 order by排序 limit限制;
Select選項:系統該如何對待查詢得到的結果
All:預設的,表示儲存所有的記錄
Distinct:去重,去除重複的記錄,只保留一條(所有的欄位都相同)
欄位列表:有的時候需要從多張表獲取資料,在獲取資料的時候,可能存在不同表中有同名的欄位,需要將同名的欄位命名成不同名的:別名 alias
基本語法:欄位名 [as] 別名
From資料來源
From是為前面的查詢提供資料:資料來源只要是一個符合二維表結構的資料即可。
單表資料
From 表名;
多表資料
從多張表獲取資料,基本語法:from 表1,表2…
結果:兩張表的記錄數相乘,欄位數拼接
本質:從第一張表取出一條記錄,去拼湊第二張表的所有記錄,保留所有結果。得到的結果在數學上有一個專業的說法:笛卡爾積,這個結果出了給資料庫造成壓力,沒有其他意義:應該儘量避免出現笛卡爾積。
動態資料
From後面跟的資料不是一個實體表,而是一個從表中查詢出來得到的二維結果表(子查詢)。
基本語法:from (select 欄位列表 from 表) as 別名;
Where子句
Where字句:用來從資料表獲取資料的時候,然後進行條件篩選。
資料獲取原理:針對表去對應的磁碟處獲取所有的記錄(一條條),where的作用就是在拿到一條結果就開始進行判斷,判斷是否符合條件:如果符合就儲存下來,如果不符合直接捨棄(不放到記憶體中)
Where是通過運算子進行結果比較來判斷資料。
Group by子句
Group by表示分組的含義:根據指定的欄位,將資料進行分組:分組的目標是為了統計
分組統計
基本語法: group by 欄位名;
Group by是為了分組後進行資料統計的,如果只是想看資料顯示,那麼group by沒什麼含義:group by將資料按照指定的欄位分組之後,只會保留每組的第一條記錄。
利用一些統計函式:(聚合函式)
count():統計每組中的數量,如果統計目標是欄位,那麼不統計為空NULL欄位,如果為*那麼代表統計記錄
avg():求平均值
sum():求和
max():求最大值
min():求最小值
Group_concat():為了將分組中指定的欄位進行合併(字串拼接)
多分組
將資料按照某個欄位進行分組之後,對已經分組的資料進行再次分組
基本語法:group by 欄位1,欄位2; //先按照欄位1進行排序,之後將結果再按照欄位2進行排序,以此類推。
分組排序
Mysql中,分組預設有排序的功能:按照分組欄位進行排序,預設是升序
基本語法:group by 欄位 [asc|desc],欄位 [asc|desc]
回溯統計
當分組進行多分組之後,往上統計的過程中,需要進行層層上報,將這種層層上報統計的過程稱之為回溯統計:每一次分組向上統計的過程都會產生一次新的統計資料,而且當前資料對應的分組欄位為NULL。
基本語法:group by 欄位 [asc|desc] with rollup;
多分組回溯統計
Having子句
Having的本質和where一樣,是用來進行資料條件篩選。
1. Having是在group by子句之後:可以針對分組資料進行統計篩選,但是where不行
查詢班級人數大於等於4個以上的班級
Where不能使用聚合函式:聚合函式是用在group by分組的時候,where已經執行完畢
Having在group by分組之後,可以使用聚合函式或者欄位別名(where是從表中取出資料,別名是在資料進入到記憶體之後才有的)
強調:having是在group by之後,group by是在where之後:where的時候表示將資料從磁碟拿到記憶體,where之後的所有操作都是記憶體操作。
Order by子句
Order by排序:根據校對規則對資料進行排序
基本語法:order by 欄位 [asc|desc]; //asc升序,預設的
Order by也可以像group by一樣進行多欄位排序:先按照第一個欄位進行排序,然後再按照第二個欄位進行排序。
Order by 欄位1 規則,欄位2 規則;
Limit子句
Limit限制子句:主要是用來限制記錄數量獲取
記錄數限制
純粹的限制獲取的數量:從第一條到指定的數量
基本語法: limt 數量;
Limit通常在查詢的時候如果限定為一條記錄的時候,使用的比較多:有時候獲取多條記錄並不能解決業務問題,但是會增加伺服器的壓力。
分頁
利用limit來限制獲取指定區間的資料。
基本語法:limit offset,length; //offset偏移量:從哪開始,length就是具體的獲取多少條記錄
Mysql中記錄的數量從0開始
Limit 0,2; 表示獲取前兩條記錄
注意:limit後面的length表示最多獲取對應數量,但是如果數量不夠,系統不會強求
查詢中的運算子
算術運算子
+、-、*、/、%
基本算術運算:通常不在條件中使用,而是用於結果運算(select 欄位中)
比較運算子
>、>=、<、<=、=、<>
通常是用來在條件中進行限定結果
=:在mysql中,沒有對應的 ==比較符號,就是使用=來進行相等判斷
<=>:相等比較
特殊應用:就是在欄位結果中進行比較運算
在條件判斷的時候,還有有對應的比較運算子:計算區間
Between 條件1 and 條件2;
Between中條件1必須小於條件2,反過來不可以
邏輯運算子
and、or、not
and:邏輯與
or:邏輯或
not:邏輯非
In運算子
In:在什麼裡面,是用來替代=,當結果不是一個值,而是一個結果集的時候
基本語法: in (結果1,結果2,結果3…),只要當前條件在結果集中出現過,那麼就成立
Is運算子
Is是專門用來判斷欄位是否為NULL的運算子
基本語法:is null / is not null
Like運算子
Like運算子:是用來進行模糊匹配(匹配字串)
基本語法:like ‘匹配模式’;
匹配模式中,有兩種佔位符:
_:匹配對應的單個字元
%:匹配多個字元
聯合查詢
基本概念
聯合查詢是可合併多個相似的選擇查詢的結果集。等同於將一個表追加到另一個表,從而實現將兩個表的查詢組合到一起,使用謂詞為UNION或UNION ALL。
聯合查詢:將多個查詢的結果合併到一起(縱向合併):欄位數不變,多個查詢的記錄數合併。
應用場景
1. 將同一張表中不同的結果(需要對應多條查詢語句來實現),合併到一起展示資料
男生身高升序排序,女生身高降序排序
2. 最常見:在資料量大的情況下,會對錶進行分表操作,需要對每張表進行部分資料統計,使用聯合查詢來講資料存放到一起顯示。
QQ1表獲取線上資料
QQ2表獲取線上資料 ---》將所有線上的資料顯示出來
基本語法
基本語法:
Select 語句
Union [union 選項]
Select 語句;
Union選項:與select選項基本一樣
Distinct:去重,去掉完全重複的資料(預設的)
All:儲存所有的結果
注意細節:union理論上只要保證欄位數一樣,不需要每次拿到的資料對應的欄位型別一致。永遠只保留第一個select語句對應的欄位名字。
Order by的使用
1. 在聯合查詢中,如果要使用order by,那麼對應的select語句必須使用括號括起來
正確的語法:加上括號
2.orderby在聯合查詢中若要生效,必須配合使用limit:而limit後面必須跟對應的限制數量(通常可以使用一個較大的值:大於對應表的記錄數)
連線查詢
連線查詢:將多張表連到一起進行查詢(會導致記錄數行和欄位數列發生改變)
連線查詢的意義
在關係型資料庫設計過程中,實體(表)與實體之間是存在很多聯絡的。在關係型資料庫表的設計過程中,遵循著關係來設計:一對一,一對多和多對多,通常在實際操作的過程中,需要利用這層關係來保證資料的完整性。
連線查詢分類
連線查詢一共有以下幾類:
交叉連線
內連線
外連線:左外連線(左連線)和右外連線(右連線)
自然連線
交叉連線
交叉連線:將兩張表的資料與另外一張表彼此交叉
原理
1.從第一張表依次取出每一條記錄
2. 取出每一條記錄之後,與另外一張表的全部記錄挨個匹配
3.沒有任何匹配條件,所有的結果都會進行保留
4.記錄數 = 第一張表記錄數 * 第二張表記錄數;欄位數 = 第一張表字段數 + 第二張表字段數(笛卡爾積)
語法
基本語法:表1 cross join 表2;
應用
交叉連線產生的結果是笛卡爾積,沒有實際應用。
本質:from 表1,表2;
內連線
內連線:inner join,從一張表中取出所有的記錄去另外一張表中匹配:利用匹配條件進行匹配,成功了則保留,失敗了放棄。
原理
1. 從第一張表中取出一條記錄,然後去另外一張表中進行匹配
2. 利用匹配條件進行匹配:
匹配到:保留,繼續向下匹配
匹配失敗:向下繼續,如果全表匹配失敗,結束
語法
基本語法:表1 [inner] join 表2 on 匹配條件;
1.如果內連線沒有條件(允許),那麼其實就是交叉連線(避免)
2.使用匹配條件進行匹配
3.因為表的設計通常容易產生同名欄位,尤其是ID,所以為了避免重名出現錯誤,通常使用表名.欄位名,來確保唯一性
4.通常,如果條件中使用到對應的表名,而表名通常比較長,所以可以通過表別名來簡化
5.內連線匹配的時候,必須保證匹配到才會儲存
6.內連線因為不強制必須使用匹配條件(on)因此可以在資料匹配完成之後,使用where條件來限制,效果與on一樣(建議使用on)
應用
內連線通常是在對資料有精確要求的地方使用:必須保證兩種表中都能進行資料匹配。
外連線
外連結:outer join,按照某一張表作為主表(表中所有記錄在最後都會保留),根據條件去連線另外一張表,從而得到目標資料。
外連線分為兩種:左外連線(left join),右外連線(right join)
左連線:左表是主表
右連線:右表是主表
原理
1. 確定連線主表:左連線就是left join左邊的表為主表;right join就是右邊為主表
2.拿主表的每一條記錄,去匹配另外一張表(從表)的每一條記錄
3.如果滿足匹配條件:保留;不滿足即不保留
4.如果主表記錄在從表中一條都沒有匹配成功,那麼也要保留該記錄:從表對應的欄位值都未NULL
語法
基本語法:
左連線:主表 left join 從表 on 連線條件;
右連線:從表 right join 主表 on連線條件;
左連線對應的主表資料在左邊;右連線對應的主表資料在右邊:
右連線檢視資料
特點
1.外連線中主表資料記錄一定會儲存:連線之後不會出現記錄數少於主表(內連線可能)
2、 左連線和右連線其實可以互相轉換,但是資料對應的位置(表順序)會改變
應用
非常常用的一種獲取的資料方式:作為資料獲取對應主表以及其他資料(關聯)
Using關鍵字
是在連線查詢中用來代替對應的on關鍵字的,進行條件匹配。
原理
1.在連線查詢時,使用on的地方用using代替
2.使用using的前提是對應的兩張表連線的欄位是同名(類似自然連線自動匹配)
3.如果使用using關鍵字,那麼對應的同名欄位,最終在結果中只會保留一個。
語法
基本語法:表1 [inner,left,right] join 表2 using(同名欄位列表); //連線欄位
子查詢
什麼是子查詢
子查詢概念
子查詢:sub query
子查詢是一種常用計算機語言SELECT-SQL語言中巢狀查詢下層的程式模組。當一個查詢是另一個查詢的條件時,稱之為子查詢。
子查詢:指在一條select語句中,嵌入了另外一條select語句,那麼被嵌入的select語句稱之為子查詢語句。
主查詢概念
主查詢:主要的查詢物件,第一條select語句,確定的使用者所有獲取的資料目標(資料來源),以及要具體得到的欄位資訊。
子查詢和主查詢的關係
1.子查詢是嵌入到主查詢中的;
2.子查詢的輔助主查詢的:要麼作為條件,要麼作為資料來源
3.子查詢其實可以獨立存在:是一條完整的select語句
子查詢分類
按功能分
標量子查詢:子查詢返回的結果是一個數據(一行一列)
列子查詢:返回的結果是一列(一列多行)
行子查詢:返回的結果是一行(一行多列)
表子查詢:返回的結果是多行多列(多行多列)
Exists子查詢:返回的結果1或者0(類似布林操作)
按位置分
Where子查詢:子查詢出現的位置在where條件中
From子查詢:子查詢出現的位置在from資料來源中(做資料來源)
標量子查詢
概念
標量子查詢:子查詢得到結果是一個數據(一行一列)
語法
基本語法:select * from 資料來源 where 條件判斷 =/<> (select 欄位名 from 資料來源 where 條件判斷); //子查詢得到的結果只有一個值
列子查詢
概念
列子查詢:子查詢得到的結果是一列資料(一列多行)
語法
基本語法:
主查詢 where 條件 in (列子查詢);
行子查詢
概念
行子查詢:子查詢返回的結果是一行多列
行元素
行元素:欄位元素是指一個欄位對應的值,行元素對應的就是多個欄位:多個欄位合起來作為一個元素參與運算,把這種情況稱之為行元素。
語法
基本語法:
主查詢 where 條件[(構造一個行元素)] = (行子查詢);
總結
已經學過三個子查詢:常見的三個子查詢
標量子查詢、列子查詢和行子查詢:都屬於where子查詢
表子查詢
概念
表子查詢:子查詢返回的結果是多行多列,表子查詢與行子查詢非常相似,只是行子查詢需要產生行元素,而表子查詢沒有。
行子查詢是用於where條件判斷:where子查詢
表子查詢是用於from資料來源:from子查詢
語法
基本語法:
Select 欄位表 from (表子查詢) as 別名 [where] [group by] [having] [order by] [limit];
Exists子查詢
概念
Exists子查詢:查詢返回的結果只有0或者1,1代表成立,0代表不成立
語法
基本語法:where exists(查詢語句); //exists就是根據查詢得到的結果進行判斷:如果結果存在,那麼返回1,否則返回0
Where 1:永遠為真
子查詢中特定關鍵字的使用
In
主查詢 where 條件 in (列子查詢);
Any
任意一個
= any(列子查詢):條件在查詢結果中有任意一個匹配即可,等價於in
<>any(列子查詢):條件在查詢結果中不等於任意一個
1 =any(1,2,3) ===== true
1 <>any(1,3) ===== true
Some
與any完全一樣:在國外,some與any的正面含義一致,但是否定就大不相同:not any與not some
開發者為了讓對應的使用者不要在語法上糾結:重新設計了some
All
= all(列子查詢):等於裡面所有
<>all(列子查詢):不等於其中所有
All資料展示
如果對應的匹配欄位有NULL,那麼不參與匹配
整庫資料備份與還原
整庫資料備份也叫SQL資料備份:備份的結果都是SQL指令
在Mysql中提供了一個專門用於備份SQL的客戶端:mysqldump.exe
應用場景
SQL備份是一種mysql非常常見的備份與還原方式,SQL備份不只是備份資料,還備份對應的SQL指令(表結構):即便是資料庫遭到毀滅性的破壞(資料庫被刪),那麼利用SQL備份依然可以實現資料還原。
SQL備份因為需要備份結構,因此產生的備份檔案特別大,因此不適合特大型資料備份,也不適合資料變換頻繁型資料庫備份。
應用方案
SQL備份
SQL備份用到的是專門的備份客戶端,因此還沒與資料庫伺服器進行連線。
基本語法:mysqldump/mysqldump.exe -hPup 資料庫名字 [表1 [表2…]] > 備份檔案地址
備份可以有三種形式:
1. 整庫備份(只需要提供資料庫名字)
2.單表備份:資料庫後面跟一張表
3.多表備份:資料庫後跟多張表
檢視備份的成果
檢視備份檔案中的具體內容
資料還原
Mysql提供了多種方式來實現:兩種
Mysqldump備份的資料中沒有關於資料庫本身的操作,都是針對表級別的操作:當進行資料(SQL還原),必須指定資料庫
1.利用mysql.exe客戶端:沒有登入之前,可以直接用該客戶端進行資料還原
Mysql.exe –hPup 資料庫 < 檔案位置
2.在SQL指令,提供了一種匯入SQL指令的方式
Source SQL檔案位置; //必須先進入到對應的資料庫
3.人為操作:開啟備份檔案,複製所有SQL指令,然後到mysql.exe客戶端中去貼上執行。(不推薦)
使用者許可權管理
使用者許可權管理:在不同的專案中給不同的角色(開發者)不同的操作許可權,為了保證資料庫資料的安全。
通常,一個使用者的密碼不會長期不變,所以需要經常性的變更資料庫使用者密碼來確保使用者本身安全(mysql客戶端使用者)
使用者管理
Mysql需要客戶端進行連線認證才能進行伺服器操作:需要使用者資訊。Mysql中所有的使用者資訊都是儲存在mysql資料庫下的user表中。
預設的,在安裝Mysql的時候,如果不選擇建立匿名使用者,那麼意味著所有的使用者只有一個:root超級使用者
在mysql中,對用的使用者管理中,是由對應的Host和User共同組成主鍵來區分使用者。
User:代表使用者的使用者名稱
Host:代表本質是允許訪問的客戶端(IP或者主機地址)。如果host使用%代表所有的使用者(客戶端)都可以訪問
建立使用者
理論上講可以採用兩種方式建立使用者:
1.直接使用root使用者在mysql.user表中插入記錄(不推薦)
2.專門建立使用者的SQL指令
基本語法:create user 使用者名稱 identified by ‘明文密碼’;
使用者:使用者名稱@主機地址
主機地址:’’ / ‘%’
檢視mysql.user表中是否存在新增的使用者
簡化版建立使用者(誰都可以訪問,不需要密碼)
當用戶建立完成之後,使用者是否可以使用?
刪除使用者
注意:mysql中user是帶著host本身的(具有唯一性)
基本語法:drop user 使用者名稱@host;
修改使用者密碼
Mysql中提供了多種修改的方式:基本上都必須使用對應提供的一個系統函式:password(),需要靠該函式對密碼進行加密處理。
1.使用專門的修改密碼的指令
基本語法:set password for 使用者 = password(‘新的明文密碼’);
修改後的資料測試
2.使用更新語句update來修改表
基本語法:update mysql.user set password = password(‘新的明文密碼’) where user = ‘’ and host= ‘’;
許可權管理
在mysql中將許可權管理分為三類:
1.資料許可權:增刪改查(select\update\delete\insert)
2.結構許可權:結構操作(create\drop)
3.管理許可權:許可權管理(create user\grant\revoke):通常只給管理員如此許可權
授予許可權:grant
將許可權分配給指定的使用者
基本語法:grant 許可權列表 on 資料庫/*.表名/* to 使用者;
許可權列表:使用逗號分隔,但是可以使用all privileges代表全部許可權
資料庫.表名:可以是單表(資料庫名字.表名),可以是具體某個資料庫(資料庫.*),也可以整庫(*.*)
使用者被分配許可權以後不需要退出就可以看到效果
具體許可權檢視:單表許可權只能看到資料庫中的一張表
取消許可權:revoke
許可權回收:將許可權從使用者手中收回
基本語法:revoke 許可權列表/all privileges on 資料庫/*.表/* from 使用者;
許可權回收,同樣不需要重新整理,使用者馬上就會感受到
重新整理許可權:flush
Flush:重新整理,將當前對使用者的許可權操作,進行一個重新整理,將操作的具體內容同步到對應的表中。
基本語法:flush privileges;
密碼丟失的解決方案
如果忘記了root使用者密碼,就需要去找回或者重置root使用者密碼
1.停止服務
2.重新啟動服務:mysqld.exe –skip-grant-tables //啟動伺服器但是跳過許可權
3.當前啟動的伺服器沒有許可權概念:非常危險,任何客戶端,不需要任何使用者資訊都可以直接登入,而且是root許可權:新開客戶端,使用mysql.exe登入即可
4.修改root使用者的密碼:指定 使用者名稱@host
5.趕緊關閉伺服器,重啟服務
外來鍵
外來鍵概念
如果公共關鍵字在一個關係中是主關鍵字,那麼這個公共關鍵字被稱為另一個關係的外來鍵。由此可見,外來鍵表示了兩個關係之間的相關聯絡。以另一個關係的外來鍵作主關鍵字的表被稱為主表,具有此外來鍵的表被稱為主表的從表。外來鍵又稱作外關鍵字。
外來鍵:foreign key
一張表(A)中有一個欄位,儲存的值指向另外一張表(B)的主鍵
B:主表
A:從表
外來鍵的操作
增加外來鍵
Mysql中提供了兩種方式增加外來鍵
1.方案1:在建立表的時候增加外來鍵(類似主鍵)
基本語法:在欄位之後增加一條語句
[constraint `外來鍵名`] foreign key(外來鍵欄位) references 主表(主鍵);
MUL:多索引,外來鍵本身是一個索引,外來鍵要求外來鍵欄位本身也是一種普通索引
2.方案2:在建立表後增加外來鍵
Alter table 從表 add [constraint `外來鍵名`] foreign key(外來鍵欄位) references 主表(主鍵);
外來鍵名字可以指定
修改&刪除外來鍵
外來鍵不允許修改,只能先刪除後增加
基本語法:alter table 從表 drop foreign key 外來鍵名字;
外來鍵不能刪除產生的普通索引,只會刪除外來鍵自己
如果想刪除對應的索引:alter table 表名 drop index 索引名字;
外來鍵基本要求
1.外來鍵欄位需要保證與關聯的主表的主鍵欄位型別完全一致;
2.基本屬性也要相同
3.如果是在表後增加外來鍵,對資料還有一定的要求(從表資料與主表的關聯關係)
4.外來鍵只能使用innodb儲存引擎:myisam不支援
外來鍵約束
外來鍵約束:通過建立外來鍵關係之後,對主表和從表都會有一定的資料約束效率。
約束的基本概念
1.當一個外來鍵產生時:外來鍵所在的表(從表)會受制於主表資料的存在從而導致資料不能進行某些不符合規範的操作(不能插入主表不存在的資料);
2.如果一張表被其他表外來鍵引入,那麼該表的資料操作就不能隨意:必須保證從表資料的有效性(不能隨便刪除一個被從表引入的記錄)
外來鍵約束的概念
可以在建立外來鍵的時候,對外來鍵約束進行選擇性的操作。
基本語法: add foreign key(外來鍵欄位) references 主表(主鍵) on 約束模式;
約束模式有三種:
1.district:嚴格模式,預設的,不允許操作
2.cascade:級聯模式,一起操作,主表變化,從表資料跟著變化
3.set null:置空模式,主表變化(刪除),從表對應記錄設定為空:前提是從表中對應的外來鍵欄位允許為空
外來鍵約束主要約束的物件是主表操作:從表就是不能插入主表不存在的資料
通常在進行約束時候的時候,需要指定操作:update和delete
常用的約束模式: on update cascade,on delete set null,更新級聯,刪除置空
更新模式
刪除模式
約束作用
保證資料的完整性:主表與從表的資料要一致
正是因為外來鍵有非常強大的資料約束作用,而且可能導致資料在後臺變化的不可控。導致程式在進行設計開發邏輯的時候,沒有辦法去很好的把握資料(業務),所以外來鍵比較少使用。
檢視基本操作
建立檢視
檢視的本質是SQL指令(select語句)
基本語法:create view 檢視名字 as select指令; //可以是單表資料,也可以是連線查詢,聯合查詢或者子查詢
檢視檢視結構:檢視本身是虛擬表,所以關於表的一些操作都適用於檢視
Show tables/show create table[view]/desc 檢視名字;
使用檢視
檢視是一張虛擬表:可以直接把檢視當做“表”操作,但是檢視本身沒有資料,是臨時執行select語句得到對應的結果。檢視主要使用者查詢操作。
基本語法:select 欄位列表 from 檢視名字 [子句];
修改檢視
修改檢視:本質是修改檢視對應的查詢語句
基本語法:alter view 檢視名字 as 新select指令;
刪除檢視
基本語法:drop view 檢視名字;
事務安全
事務概念
事務(Transaction)是訪問並可能更新資料庫中各種資料項的一個程式執行單元(unit)。事務通常由高階資料庫操縱語言或程式語言書寫的使用者程式的執行所引起。事務由事務開始(begin transaction)和事務結束(end transaction)之間執行的全體操作組成。
事務基本原理
基本原理:Mysql允許將事務統一進行管理(儲存引擎INNODB),將使用者所做的操作,暫時儲存起來,不直接放到資料表(更新),等到用於確認結果之後再進行操作。
事務在mysql中通常是自動提交的,但是也可以使用手動事務。
自動事務
自動事務:autocommit,當客戶端傳送一條SQL指令(寫操作:增刪改)給伺服器的時候,伺服器在執行之後,不用等待使用者反饋結果,會自動將結果同步到資料表。
證明:利用兩個客戶端,一個客戶端執行SQL指令,另外一個客戶端檢視執行結果
自動事務:系統做了額外的步驟來幫助使用者操作,系統是通過變數來控制的。Autocommit
Show variables like ‘autocommit%’;
關閉自動事務:關閉之後系統就不在幫助使用者提交結果了
Set autocommit = Off;
檢視執行結果
一旦自動事務關閉,那麼需要使用者提供是否同步的命令
Commit:提交(同步到資料表:事務也會被清空)
Rollback:回滾(清空之前的操作,不要了)
事務沒有提交的對比檢視:在執行事務端的客戶端中,系統在進行資料檢視的時候會利用事務日誌中儲存的結果對資料進行加工
通常,我們不會關閉自動事務:這樣操作太麻煩。因此只會在需要使用事務處理的時候,才會進行操作(手動事務)
手動事務
手動事務:不管是開始還是過程還是結束都需要使用者(程式設計師),手動的傳送事務操作指令來實現。
手動事務對應的命令:
1.start transaction; //開啟事務:從這條語句開始,後面的所有語句都不會直接寫入到資料表(儲存在事務日誌中)
2.事務處理:多個寫指令構成
3.事務提交:commit/rollback,到這個時候所有的事務才算結束
開啟事務
執行事務
將多個連續的但是是一個整體的SQL指令,逐一執行
1.事務操作1:新增資料
2.事務操作2:更新資料
提交事務
確認提交:commit,資料寫到資料表(清空)
回滾操作:rollback,所有資料無效並清空
回滾點
回滾點:savepoint,當有一系列事務操作時,而其中的步驟如果成功了,沒有必要重新來過,可以在某個點(成功),設定一個記號(回滾點),然後如果後面有失敗,那麼可以回到這個記號位置。
增加回滾點:savepoint 回滾點名字; //字母數字和下劃線構成
回到回滾點:rollback to 回滾點名字; //那個記號(回滾點)之後的所有操作沒有了
注意:在一個事務處理中,如果有很多個步驟,那麼可以設定多個回滾點。但是如果回到了前面的回滾點,後面的回滾點就失效;
1.增加回滾點操作
2.出現錯誤步驟
3.回到正確點:回滾
事務特點
事務應該具有4個屬性:原子性、一致性、隔離性、永續性。這四個屬性通常稱為ACID特性。
原子性(atomicity)。一個事務是一個不可分割的工作單位,事務中包括的諸操作要麼都做,要麼都不做。
事務從start transaction起到提交事務(commit或者rollback),要麼所有的操作都成功,要麼就是所有的操作都失敗;
一致性(consistency)。事務必須是使資料庫從一個一致性狀態變到另一個一致性狀態。一致性與原子性是密切相關的。
資料表中的資料修改,要麼是所有操作一次性修改,要麼是根本不懂
隔離性(isolation)。一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
如果一個客戶端在使用事務操作一個數據(可能是一行/整表)的時候,另外一個客戶端不能對該資料進行操作
什麼時候是行被隔離?什麼時候是整表被隔離?
說明:如果條件中使用了索引(主鍵),那麼系統是根據主鍵直接找到某條記錄,這個時候與其他記錄無關,那麼只隔離一條記錄;反之,如果說系統是通過全表檢索(每一條記錄都去檢查:沒有索引),被檢索的所有資料都會被鎖定(整表)
永續性(durability)。永續性也稱永久性(permanence),指一個事務一旦提交,它對資料庫中資料的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。
變數
Mysql本質是一種程式語言,需要很多變數來儲存資料。Mysql中很多的屬性控制都是通過mysql中固有的變數來實現的。
系統變數
系統內部定義的變數,系統變數針對所有使用者(MySQL客戶端)有效。
檢視系統所有變數:show variables [like ‘pattern’];
Mysql允許使用者使用select查詢變數的資料值(系統變數)
基本語法:select @@變數名;
修改系統變數:分為兩種修改方式
1.區域性修改(會話級別):只針對當前自己客戶端當次連線有效
基本語法:set 變數名 = 新值;
2.全域性修改:針對所有的客戶端,“所有時刻”都有效
基本語法:set global 變數名 = 值; || set @@global.變數名 = 值;
全域性修改之後:所有連線的客戶端並沒發現改變?全域性修改只針對新客戶端生效(正在連著的無效)
注意:如果想要本次連線對應的變數修改有效,那麼不能使用全域性修改,只能使用會話級別修改(set 變數名 = 值);
會話變數
會話變數也稱之為使用者變數,會話變數跟mysql客戶端是繫結的,設定的變數,只對當前使用者使用的客戶端生效。
定義使用者變數:set @變數名 = 值;
在mysql中因為沒有比較符號==,所以是用=代替比較符號:有時候在賦值的時候,會報錯:mysql為了避免系統分不清是賦值還是比較:特定增加一個變數的賦值符號: :=
Set @變數名 := 值;
Mysql是專門儲存資料的:允許將資料從表中取出儲存到變數中:查詢得到的資料必須只能是一行資料(一個變數對應一個欄位值):Mysql沒有陣列。
1.賦值且檢視賦值過程:select @變數1 := 欄位1,@變數2 := 欄位2 from 資料表 where 條件;
錯誤語法:就是因為使用=,系統會當做比較符號來處理
正確處理:使用:=
2.只賦值,不看過程:select 欄位1,欄位2… from 資料來源 where條件 into @變數1,@變數2…
檢視變數:select @變數名;
區域性變數
作用範圍在begin到end語句塊之間。在該語句塊裡設定的變數,declare語句專門用於定義區域性變數。
1.區域性變數是使用declare關鍵字宣告
2.區域性變數declare語句出現的位置一定是在begin和end之間(beginend是在大型語句塊中使用:函式/儲存過程/觸發器)
3.宣告語法:declare 變數名 資料型別 [屬性];
流程結構
流程結構:程式碼的執行順序
If分支
基本語法
If在Mysql中有兩種基本用法
1.用在select查詢當中,當做一種條件來進行判斷
基本語法:if(條件,為真結果,為假結果)
2.用在複雜的語句塊中(函式/儲存過程/觸發器)
基本語法
If 條件表示式 then
滿足條件要執行的語句;
End if;
複合語法
複合語法:程式碼的判斷存在兩面性,兩面都有對應的程式碼執行。
基本語法:
If 條件表示式 then
滿足條件要執行的語句;
Else
不滿足條件要執行的語句;
//如果還有其他分支(細分),可以在裡面再使用if
If 條件表示式 then
//滿足要執行的語句
End if;
End if;
While迴圈
基本語法
迴圈體都是需要在大型程式碼塊中使用
基本語法
While 條件 do
要迴圈執行的程式碼;
End while;
結構識別符號
結構識別符號:為某些特定的結構進行命名,然後為的是在某些地方使用名字
基本語法
標識名字:While 條件 do
迴圈體
End while [標識名字];
識別符號的存在主要是為了迴圈體中使用迴圈控制。在mysql中沒有continue和break,有自己的關鍵字替代:
Iterate:迭代,就是以下的程式碼不執行,重新開始迴圈(continue)
Leave:離開,整個迴圈終止(break)
標識名字:While 條件 do
If 條件判斷 then
迴圈控制;
Iterate/leave 標識名字;
End if;
迴圈體
End while [標識名字];
函式
在mysql中,函式分為兩類:系統函式(內建函式)和自定義函式
不管是內建函式還是使用者自定義函式,都是使用select 函式名(引數列表);
內建函式
字串函式
Char_length():判斷字串的字元數
Length():判斷字串的位元組數(與字符集)
Concat():連線字串
Instr():判斷字元在目標字串中是否存在,存在返回其位置,不存在返回0
Lcase():全部小寫
Left():從左側開始擷取,直到指定位置(位置如果超過長度,擷取所有)
Ltrim():消除左邊對應的空格
Mid():從中間指定位置開始擷取,如果不指定擷取長度,直接到最後
時間函式
Now():返回當前時間,日期 時間
Curdate():返回當前日期
Curtime():返回當前時間
Datediff():判斷兩個日期之間的天數差距,引數日期必須使用字串格式(用引號)
Date_add(日期,interval 時間數字 type):進行時間的增加
Type:day/hour/minute/second
Unix_timestamp():獲取時間戳
From_unixtime():將指定時間戳轉換成對應的日期時間格式
數學函式
Abs():絕對值
Ceiling():向上取整
Floor():向下取整
Pow():求指數,誰的多少次方
Rand():獲取一個隨機數(0-1之間)
Round():四捨五入函式
其他函式
Md5():對資料進行md5加密(mysql中的md5與其他任何地方的md5加密出來的內容是完全相同的)
Version():獲取版本號
Databse():顯示當前所在資料庫
UUID():生成一個唯一識別符號(自增長):自增長是單表唯一,UUID是整庫(資料唯一同時空間唯一)
自定義函式
自定義函式:使用者自己定義的函式
函式:實現某種功能的語句塊(由多條語句組成)
1.函式內部的每條指令都是一個獨立的個體:需要符合語句定義規範:需要語句結束符分號;
2.函式是一個整體,而且函式是在呼叫的時候才會被執行,那麼當設計函式的時候,意味著整體不能被中斷;
3.Mysql一旦見到語句結束符分號,就會自動開始執行
解決方案:在定義函式之前,嘗試修改臨時的語句結束符
基本語法:delimiter
修改臨時語句結束符:delimiter 新符號[可以使用系統非內建即可$$]
中間為正常SQL指令:使用分號結束(系統不會執行:不認識分號)
使用新符號結束
修改回語句結束符:delimiter ;
建立函式
自定義函式包含幾個要素:function關鍵字,函式名,引數(形參和實參[可選]),確認函式返回值型別,函式體,返回值
函式定義基本語法:
修改語句結束符
Create function 函式名(形參) returns 返回值型別
Begin
//函式體
Return 返回值資料; //資料必須與結構中定義的返回值型別一致
End
語句結束符
修改語句結束符(改回來)
並不是所有的函式都需要begin和end:如果函式體本身只有一條指令(return),那麼可以省略begin和end
形參:在mysql中需要為函式的形參指定資料型別(形參本身可以有多個)
基本語法:變數名 欄位型別
檢視函式
1.可以通過檢視function狀態,檢視所有的函式
Show function status [like ‘pattern’];
2.檢視函式的建立語句:show create function 函式名字;
呼叫函式
自定義函式的呼叫與內建函式的呼叫是一樣的:select 函式名(實參列表);
刪除函式
刪除函式:drop function 函式名;
注意事項
1.自定義函式是屬於使用者級別的:只有當前客戶端對應的資料庫中可以使用
2.可以在不同的資料庫下看到對應的函式,但是不可以呼叫
3.自定義函式:通常是為了將多行程式碼集合到一起解決一個重複性的問題
4.函式因為必須規範返回值:那麼在函式內部不能使用select指令:select一旦執行就會得到一個結果(result set):select 欄位 into @變數;(唯一可用)
函式流程結構案例
需求:從1開始,直到使用者傳入的對應的值為止,自動求和:凡是5的倍數都不要。
設計:
1.建立函式
2.需要一個形參:確定要累加到什麼位置
3.需要定義一個變數來儲存對應的結果:set @變數名;
使用區域性變數來操作:此結果是在函式內部使用
Declare 變數名 型別 [= 預設值];
4.內部需要一個迴圈來實現迭代累加
5.迴圈內部需要進行條件判斷控制:5的倍數
6.函式必須有返回值
定義函式結構完成
呼叫函式:select 函式名(實參);
變數作用域
變數作用域:變數能夠使用的區域範圍
區域性作用域
使用declare關鍵字宣告(在結構體內:函式/儲存過程/觸發器),而且只能在結構體內部使用
declare關鍵字宣告的變數沒有任何符號修飾,就是普通字串,如果在外部訪問該變數,系統會自動認為是欄位
會話作用域
使用者定義的,使用@符號定義的變數,使用set關鍵字
會話作用域:在當前使用者當次連線有效,只要在本連線之中,任何地方都可以使用(可以在結構內部,也可以跨庫)
會話變數可以在函式內部使用
會話變數可以跨庫
全域性作用域
所有的客戶端所有的連線都有效:需要使用全域性符號來定義
Set global 變數名 = 值;
Set @@global.變數名 = 值;
通常,在SQL程式設計的時候,不會使用自定義變數來控制全域性。一般都是定義會話變數或者在結構中使用區域性變數來解決問題。
儲存過程
儲存過程概念
儲存過程(Stored Procedure)是在大型資料庫系統中,一組為了完成特定功能的SQL 語句集,儲存在資料庫中,經過第一次編譯後再次呼叫不需要再次編譯(效率比較高),使用者通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它。儲存過程是資料庫中的一個重要物件(針對SQL程式設計而言)。
儲存過程:簡稱過程
與函式的區別
相同點
1.儲存過程和函式目的都是為了可重複地執行操作資料庫的sql語句的集合。
2.儲存過程函式都是一次編譯,後續執行
不同點
1.識別符號不同。函式的識別符號為FUNCTION,過程為:PROCEDURE。
2.函式中有返回值,且必須返回,而過程沒有返回值。
3.過程無返回值型別,不能將結果直接賦值給變數;函式有返回值型別,呼叫時,除在select中,必須將返回值賦給變數。
4.函式可以在select語句中直接使用,而過程不能:函式是使用select呼叫,過程不是。
儲存過程操作
建立過程
基本語法
Create procedure 過程名字([引數列表])
Begin
過程體
End
結束符
如果過程體中只有一條指令,那麼可以省略begin和end
過程基本上也可以完成函式對應的所有功能
檢視過程
檢視過程與檢視函式完全一樣:除了關鍵字
檢視全部儲存過程:show procedure status [like ‘pattern’];
檢視過程建立語句:show create procedure 過程名字;
呼叫過程
過程:沒有返回值,select不可能呼叫
呼叫過程有專門的語法:call 過程名([實參列表]);
刪除過程
基本語法:drop procedure 過程名字;
儲存過程的形參型別
儲存過程也允許提供引數(形參和實參):儲存的引數也和函式一樣,需要指定其型別。
但是儲存過程對引數還有額外的要求:自己的引數分類
In
表示引數從外部傳入到裡面使用(過程內部使用):可以是直接資料也可以是儲存資料的變數
Out
表示引數是從過程裡面把資料儲存到變數中,交給外部使用:傳入的必須是變數
如果說傳入的out變數本身在外部有資料,那麼在進入過程之後,第一件事就是被清空,設為NULL
Inout
資料可以從外部傳入到過程內部使用,同時內部操作之後,又會將資料返還給外部。
引數使用級別語法(形參)
過程型別 變數名 資料型別; //in int_1 int
分析結果:out型別的資料會被清空,其他正常
在執行過程之後,再次檢視會話變數(外部)
觸發器
觸發器概念
基本概念
觸發器是一種特殊型別的儲存過程,它不同於我們前面介紹過的儲存過程。觸發器主要是通過事件進行觸發而被執行的,而儲存過程可以通過儲存過程名字而被直接呼叫。
觸發器:trigger,是一種非常接近於js中的事件的知識。提前給某張表的所有記錄(行)繫結一段程式碼,如果改行的操作滿足條件(觸發),這段提前準備好的程式碼就會自動執行。
作用
1.可在寫入資料表前,強制檢驗或轉換資料。(保證資料安全)
2.觸發器發生錯誤時,異動的結果會被撤銷。(如果觸發器執行錯誤,那麼前面使用者已經執行成功的操作也會被撤銷:事務安全)
3.部分資料庫管理系統可以針對資料定義語言(DDL)使用觸發器,稱為DDL觸發器。
4.可依照特定的情況,替換異動的指令 (INSTEAD OF)。(mysql不支援)
觸發器優缺點
優點
1.觸發器可通過資料庫中的相關表實現級聯更改。(如果某張表的資料改變,可以利用觸發器來實現其他表的無痕操作[使用者不知道])
2.保證資料安全:進行安全校驗
缺點
1.對觸發器過分的依賴,勢必影響資料庫的結構,同時增加了維護的複雜程度。
2.造成資料在程式層面不可控。(PHP層)
觸發器基本語法
建立觸發器
基本語法
Create trigger 觸發器名字 觸發時機 觸發事件 on 表 for each row
Begin
End
觸發物件:on 表 for each row,觸發器繫結實質是表中的所有行,因此當每一行發生指定的改變的時候,就會觸發觸發器。
觸發時機
觸發時機:每張表中對應的行都會有不同的狀態,當SQL指令發生的時候,都會令行中資料發生改變,每一行總會有兩種狀態:資料操作前和操作後
Before:在表中資料發生改變前的狀態
After:在表中資料已經發生改變後的狀態
觸發事件
觸發事件:mysql中觸發器針對的目標是資料發生改變,對應的操作只有寫操作(增刪改)
Insert:插入操作
Update:更新操作
Delete:刪除操作
注意事項
一張表中,每一個觸發時機繫結的觸發事件對應的觸發器型別只能有一個:一張表中只能有一個對應after insert觸發器
因此,一張表中最多的觸發器只能有6個:before insert,before update,before delete,after insert,after update,after delete
需求:有兩張表,一張是商品表,一張是訂單表(保留商品ID),每次訂單生成,商品表中對應的庫存就應該發生變化。
1.建立兩張表:商品表和訂單表
2.建立觸發器:如果訂單表發生資料插入,對應的商品就應該減少庫存
Create trigger 名字 after insert on my_orders for each row
檢視觸發器
1.檢視全部觸發器
Show triggers;
2.檢視觸發器的建立語句
Show create trigger 觸發器名字;
觸發觸發器
想辦法讓觸發器執行:讓觸發器指定的表中,對應的時機發生對應的操作即可。
1.表為my_orders
2.在插入之後
3.插入操作
刪除觸發器
基本語法:drop trigger 觸發器名字;
觸發器應用
記錄關鍵字:new、old
觸發器針對的是資料表中的每條記錄(每行),每行在資料操作前後都有一個對應的狀態,觸發器在執行之前就將對應的狀態獲取到了,將沒有操作之前的狀態(資料)都儲存到old關鍵字中,而操作後的狀態都放到new中。
在觸發器中,可以通過old和new來獲取繫結表中對應的記錄資料。
基本語法:關鍵字.欄位名
Old和new並不是所有觸發器都有:
Insert:插入前全為空,沒有old
Delete:清空資料,沒有new
商品自動扣除庫存
驗證結果
如果庫存數量沒有商品訂單多怎麼辦?
操作目標:訂單表,操作時機:下單前;操作事件:插入
結果驗證