MySQL 使用標準 SQL 檢索和處理數據,體積小、開源、免費,易於快速部署。正是由於這些特色,使得其在互聯網行業,特別是 Web 應用方面使用至關普遍。至今最新的版本已到 8.0。html
一 基本操做mysql
MySQL 和 SQL Server 不一樣,它沒有官方的圖形化操做管理軟件,它主要經過命令行的方式操做。sql
本文主要介紹 MySQL 編程相關的知識,安裝和部署不在本文講解範圍,對於 MySQL 的安裝和部署,請自行查閱官方文檔或其餘資料。數據庫
1,基本命令編程
1 net start mysql80(服務名) 2 net stop mysql80 3 /* 啓動 mysql 服務,不一樣版本的 MySQL 服務名默認不一致,但安裝的時候能夠本身指定 */ 4 mysql -h 主機地址 -u 用戶名 -p 用戶密碼 5 /* 登陸 MySQL 服務器,若是是在本地登陸能夠省略主機地址 */ 6 exit 7 /* 退出登陸 */
2,基礎語法服務器
MySQL 採用標準 SQL 語法,他們一樣分爲 DDL、DQL、DML、DCL。編程語言
詳情能夠移步個人《SQL入門,就這麼簡單》。函數
3,註釋oop
MySQL 使用 # 標記單行註釋,/* */ 標記多行註釋。測試
1 #這是單行註釋 2 /* 3 這是多行註釋 4 */ 5 -- 這也是單行註釋
使用雙橫線註釋時,雙橫線後面至少須要一個空格。
4,語句結束
因爲 MySQL 使用命令行的方式操做數據庫,因此對於每一條命令,咱們必須明確的指定結束符。MySQL 默認的語句結束符是分號";"。
1 1 語句 1; 2 2 語句 2; 3 3 delimiter $ 4 4 /* 經過 delimiter 指定新的結束標識 */ 5 5 語句3$ 6 6 語句4$
好比,咱們在建立存儲過程或函數時,函數或存儲過程內部有多條語句,但建立過程自己也是一條語句,爲了不衝突,因此在建立存儲過程和函數時通常會臨時修改語句結束符。不要忘記在建立完後再把結束符改成默認的分號哦。
5,約束
MySQL 中對約束進行了分類:表約束和列約束,語法稍有差別。
1 create table myTable( 2 col1 type[AUTO_INCREMENT], 3 col2 type, 4 col3 type, 5 col4 type, 6 col5 type NOT NULL, 7 col6 type DEFAULT 'something', 8 PRIMARY KEY (col1), 9 FOREIGN KEY (col2) REFERENCES mytable1(somecol), 10 UNIQUE(col3), 11 CHECK(col4<200) 12 ); 13 /*AUTO_INCREMENT 設置主鍵自增,類似的,MsSQL 使用IDENTITY(1,1) 設置自增*/
列約束只有 NOT NULL 和 DEFAULT,其餘的均屬於表約束。
6,查詢相關
HAVING 關鍵字對聚合後的數據進行再篩選。WHERE 關鍵字是對原始數據的篩選。
1 select a.dep,avg(a.sal) as 平均工資 from salary a 2 left join department b 3 on a.dep=b.dep 4 where b.sta_num>10 5 having avg(sal)>10000; 6 /* 鏈接查詢部門和部門平均工資,部門人數在10以上,且平均工資大於10000 */
LIMIT 關鍵字,能夠用來返回指定條數的記錄,經常使用來作分頁查詢(MsSQL 使用 top 關鍵字)。limit 須要指定兩個 int 類型的參數,分別表示從哪條記錄開始(第一條數據索引爲0),提取多少條記錄。當從第一條數據開始時,第一個參數能夠省略。
1 /* 基礎用法:返回指定數量記錄 */ 2 select * from department order by sta_num limit 10; 3 /* 查詢人數最少的10各部門狀況 */
1 /* 分頁查詢 */ 2 SET @num:=10;#定義用戶變量,稍後會詳細講解;每頁須要查詢的記錄數 3 SET @page:=2;#須要查詢第幾頁 4 SET @index=(@page-1)*@num;#開始索引 5 PREPARE mysql FROM "select * from country limit ?,?";#因爲 limit 不支持使用變量,因此必須先使用 prepare 預編譯 SQL 語句,? 標識變量 6 EXECUTE mysql USING @index,@num;#使用 execute 執行預編譯的語句,並使用 using 傳遞參數,順序必須和預編譯時一致
子查詢又稱嵌套查詢,是指一個 SELECT 語句的查詢結果被嵌套在另外一個語句之中,子查詢既能夠放在 FROM 關鍵字後面,也能夠放在 WHERE 後面。外部的語句能夠是 SELECT、INSERT、DELETE、UPDATE。
1 select * from ( 2 selec * from tableA where col1>( 3 select min(col1) from tableB 4 ) 5 )a;
二 函數
1,字符函數
函數 | 功能 | 例子 | 說明 |
concat() | 鏈接多個字符串 | concat('a','b') | 鏈接‘a’和‘b’,返回新的字符串‘ab’ |
substr() | 截取字符串 | substr('abcde',1,3) | 在字符串‘abcde’中從第1個字符開始截取3個字符,並返回 |
lower()/upper() | 字符串大小寫轉換 | lower('abD') | 把字符串‘abD’都轉換成小寫,並返回 |
replace() | 替換指定字符 | replace('abcda','a','x') | 把字符串‘abcda’中的‘a’都替換成‘x’,並返回新的字符串 |
length() | 計算字符串長度 | length('abcde') | 返回字符串‘abcde’的長度 |
trim() | 去掉先後空格 | trim(' abc ') | 返回去掉了先後空格的新字符串 |
lpad()/rpad() | 左右填充指定字符 | lpad('abc',10,'-') | 用‘-’填充字符串‘abc’至長度爲10 |
instr() | 子串第一次出現的索引 | instr('abcde','c') | 返回在‘abcde’中第一次出現‘c’的索引 |
2,數學函數
函數 | 功能 | 例子 | 說明 |
ceil() | 向上取整 | ceil(1.1) | 2 |
floor() | 向下取整 | ceil(1.9) | 1 |
round() | 四捨五入 | round(2.5) | 3 |
mod() | 取模 | mod(21,4) | 1 |
truncate() | 截斷小數 | truncate(1.258,2) | 1.25(多餘的小數位直接截斷) |
rand() | 返回隨機數 | rand() | 隨機數[0,1) |
format() | 截斷位數 | format(1.258,2) | 1.26(最後一位四捨五入得來) |
3,日期函數
函數 | 功能 | 例子 | 說明 |
now() | 返回當前日期時間 | now() | 2020-05-15 16:27:59 |
year()/month()/day() | 返回年/月/日 | year(now()) | 2020 |
hour()/minute()/secend() | 返回時/分/秒 | hour(now()) | 16 |
curtime() | 返回時間部分 | curtime(now()) | 16:27:59 |
curdate() | 返回日期部分 | curdate(now()) | 2020-05-15 |
date_format() | 格式化日期 | date_format(now(),'%Y/%m/%d') | 2020/05/15 |
str_to_date() | 把字符串表示的日期轉換成日期格式 | str_to_date('2020-05-15 00:00:00','%Y%m%d') | 2020/05/15 |
datediff() | 返回兩個日期之間的天數差 | datediff(now(),'2020-01-01') | 135 |
4,聚合函數
函數 | 功能 | 例子 | 說明 |
max() | 返回最大值 | max(列名) | 返回一列的最大值 |
min() | 返回最小值 | min(列名) | 返回一列的最小值 |
avg() | 返回平均值 | avg(列名) | 返回一列的平均值 |
sum() | 返回和 | sum(列名) | 返回一列的和 |
count() | 返回數量 | count(列名) | 返回一列的數量(不計算NULL) |
5,其餘函數
A:IFNULL()
1 /*MySQL*/ 2 select IFNULL(NULL,1,2) 3 /*若是第一個參數是 NULL ,則返回第三個參數,不然返回第二個*/ 4 /*MsSQL*/ 5 select ISNULL(NULL,1) 6 /*若是第一個參數是 NULL,則返回第二個參數,不然原樣返回*/
B:IF()
1 IF(expr1,expr2,expr3) 2 /*若是 expr1 的值爲 true,則返回 expr2 的值,不然返回 expr3 的值。*/
C:其餘
1 SELECT DATABASE() 2 SELECT VERSION() 3 SELECT USER() 4 /* 分別返回當前鏈接數據庫,當前數據庫版本,當前用戶 */
三 編程對象
1,視圖
A:建立
1 use world; 2 create view v_1 3 as 4 select * from country limit 10; 5 /* mysql8.0 自帶一個 world 庫*/
B:刪除
1 drop view v_name;
C:修改
1 /*方式一:*/ 2 alter view v_name 3 as 4 語句; 5 /*方式二:*/ 6 create or replace view v_name 7 as 8 語句;
2,變量
MySQL 中變量分爲 4 種:系統變量,會話變量,用戶變量,局部變量。
A:系統變量
1 SHOW GLOBAL VARIABLES; 2 /* 查看系統變量。當服務啓動時,它將全部系統變量初始化爲默認值。要想更改全局變量,必須具備super權限。 */
B:會話變量
1 SHOW SESSION VARIABLES; 2 /* 查看會話變量,只做用於當前鏈接,查看指定系統或會話變量使用:select @@+變量名 */
C:用戶變量
1 set @name='張三'; 2 set @age:=12; 3 select @sex='男'; 4 select @var:=max(col) from table 5 /* 用戶變量直接賦值便可,使用 select 賦值時只能使用 :=,這是爲了讓系統避免混淆賦值和等於操做,推薦都使用 := */
D:局部變量
1 1 declare age int default 0; 2 2 set age:=12; 3 3 select @age:=18; 4 4 select max(col) into age from table; 5 5 /* declare 語句專門用於定義局部變量,可使用 default 來指定默認值,直接賦值時,使用 set,則不須要用 @ 標記變量,使用 select 則須要。若是使用查詢賦值,則須要使用 select into.
局部變量只能在 BENGIN...END 語句塊中使用,好比下面將要講到的存儲過程或函數中。若是如上例中那樣直接運行將報錯。
3,存儲過程
A:建立
1 create procedure proc_name(參數列表) 2 begin 3 語句塊; 4 end
參數包含三個部分:參數模式,參數名,參數類型。
參數模式也分爲三種:IN(僅用來像存儲過程輸入),OUT(僅用來像存儲過程外部輸出),INOUT(便可以用來輸入也能夠用來輸出)。
存儲過程也能夠沒有參數,括號內留空便可。
B:調用
1 call proc_name(實參列表);
1 DELIMITER $ 2 CREATE PROCEDURE p_1(IN cname VARCHAR(20),OUT cregion VARCHAR(20)) 3 BEGIN 4 SELECT region INTO cregion FROM country 5 WHERE country.name=cname; 6 END$ 7 /*修改默認結束符後,這種語法只能在命令行模式使用,圖形化界面會報錯(SQLyog,navicat等) 8 這裏使用的依然是 MySQL8.0 自帶的 world 庫*/
9 CALL('Aruba',@cregion);
10 SELECT @cregion;
C:刪除
1 drop procedure proc_name;
存儲過程是一組預編譯的 SQL 語句,使用存儲過程,能夠提升代碼的重用性,簡化操做,由於已經預編譯好了 SQL 代碼,執行時減小了預編譯環節,能夠提升執行效率,通常用來對錶數據進行增刪改。
4,自定義函數
A:建立
1 DELIMITER $ 2 CREATE FUNCTION func_name(參數列表) 3 RETURNS 返回類型 4 BEGIN 5 函數體 6 END$
函數的參數和存儲過程不一樣,只須要指定參數名和參數類型。而且單獨使用關鍵字 RETURNS 指定返回值類型。因爲函數必須返回值,因此函數內部必須使用 RETURN 關鍵字。RETURN 建議放在函數末尾,由於它會阻斷後面語句的執行。
1 delimiter $ 2 create function f_1(num1 float,num2 float) 3 returns float 4 begin 5 declare sum float default 0; 6 set sum:=num1+num2; 7 return sum; 8 end$ 9 select f_1(1.1,2.2)$
MySQL 不支持存儲過程和函數的修改,若是須要修改,必須刪除原來的,並新建同名的過程名或函數名。
1 create percedure|function if not exists name 2 ... 3 /* 建立以前先判斷是否已存在,省得報錯,刪除時也應該檢測是否不存在 */
5,事務
MySQL 中事務分爲兩類:顯示事務和隱式事務。
隱式事務不用顯式的指定開始和結束標記。好比 INSERT、UPDATE、DELETE語句都數據隱式事務,他們不須要指定開始和結束,執行就開啓並自動提交。
顯式事務是指有顯式指定開始和結束標記的事務,這類事務通常由用戶建立。因爲系統默認是開啓了事務自動提交功能的,因此在建立顯式事務時咱們必須先手動的關閉自動提交功能。
1 set autocommit=0; 2 select @@autocommit; 3 /*0爲關閉,1爲開啓,該設置只在本次會話生效*/
語法:
1 start transaction; 2 /*開啓顯式事務*/ 3 語句1; 4 savepoint point_name; 5 /*設置事務斷點,不是必須的*/ 6 語句2; 7 ... 8 rollback to point_name; 9 /*回滾到指定斷點,該斷點以前的將不會被回滾*/ 10 commit; 11 /*提交事務,全部的操做被提交到數據庫,源數據被修改*/
若是沒有設置事務斷點,那麼回滾將對全部事務中的語句生效,固然 rollback 後也不須要指定斷點名稱了。提交和回滾不必定會同時存在。
事務通常是結合應用程序來使用的,直接在 MySQL 中沒法測試。好比,在應用程序中,用戶輸入的信息要被提交到數據庫,當用戶輸入完畢後,點擊提交,咱們能夠設置等待時間,並提示用戶是否確認提交。若是在等待時間結束以後用戶無任何操做,或用戶點擊確認,那麼咱們直接提交事務,若是用戶點擊了取消,那麼咱們能夠回滾事務。
須要注意的是,MySQL 默認配置了許多不一樣的存儲引擎(又稱表類型),不一樣的存儲引擎使用了不一樣的存儲技術,它們在插入、讀取、修改、事務等方面各有優劣,你能夠爲不一樣的表或庫配置不一樣的存儲引擎。存儲引擎不在本文的講解範圍,這裏專門提到它是想指明另外一個問題:並非全部的 MySQL 存儲引擎都支持事務,只有 InnoDB 引擎支持。因此,若是你但願在 MySQL 中使用事務,請爲其配置 InnoDB 存儲引擎。
四 流程控制
1,選擇
A:CASE 結構
和其餘編程語言同樣,MySQL 中的 case 語句也是用來實現多分支結構的。不一樣的是,MySQL 中的 case 不只能夠用來作等值判斷,還能夠用來實現相似多重 IF 的邏輯。
等值判斷:
1 case 表達式或字段 2 when 用來比較的值1 then 返回的值1或語句1; 3 when 用來比較的值2 then 返回的值2或語句2; 4 ... 5 else 返回的值n或語句n; 6 end case; 7 /* case 後面直接跟須要被作等值判斷的表達式或表字段 */
區間判斷:
1 case 2 when 判斷條件1 then 返回的值1或語句1; 3 when 判斷條件2 then 返回的值2或語句2; 4 ... 5 else 返回的值n或語句n; 6 end case; 7 /* case 後面不跟任何值或表達式,在 when 後經過條件表達式來判斷所屬狀況 */
若是把 case 結構做爲表達式,那麼它能夠被嵌套在其餘語句中(then 後不須要分號),用在任何地方。若是做爲獨立的語句使用,那麼必須在 begin...end 中。
B:IF 結構
IF 結構主要用來實現多重分支的結構,IF 結構只能包含在 BEGIN...END 中使用,不能做爲獨表達式使用,若是想做爲表達式,可使用 IF() 函數,但它只能實現兩個分支。
1 if 判斷條件1 2 then 語句1; 3 elseif 判斷條件2 4 then 語句2; 5 ... 6 else 判斷條件n 7 then 語句n; 8 end if; 9 /* 與其餘編程語言不一樣,這裏的 elseif 中間沒有空格 */
2,循環
MySQL 中的循環控制語句有兩個:iterate(結束本次循環,執行下一次循環,相似其餘語言中的 continue),leave(結束整個循環,相似 break)。
另外,循環控制語句必須指明當前退出的是哪一個循環。因此,若是你要使用它們精準控制循環執行,那麼你須要在循環語句最開始指明當前循環的別稱。固然,這不是必須的。
A:while 循環
1 [循環名稱:]while 循環條件 2 do 3 循環體; 4 end while [循環名稱]; 5 /* 經過判斷循環條件來決定是否執行循環體 */
B:repeat 循環
1 [循環名稱:]repeat 2 循環體; 3 until 循環條件 4 end repeat [循環名稱]; 5 /* 先執行一次循環,再檢查循環條件 */
C:loop 循環
1 [循環名稱:]loop 2 循環條件; 3 end loop [循環名稱]; 4 /* 沒有循環條件,只能經過循環控制語句結束 */
MySQL 中的循環語句都只能包含在 begin...end 中使用,因此通常在存儲過程和函數中使用。