拆解 MySQL 的高階使用與概念

前面咱們主要分享了MySQL中的常見知識與使用。這裏咱們主要分享一下MySQL中的高階使用,主要包括:函數、存儲過程和存儲引擎。php

對於MySQL中的基礎知識,能夠參見mysql

《與 MySQL 的零距離接觸》算法

1 函數

函數能夠返回任意類型的值,也能夠接收這些類型的參數。sql

字符函數

函數名稱 描述
CONCAT() 字符鏈接
CONCAT_WS() 使用指定的分隔符進行字符鏈接
FORMAT() 數字格式化
LOWER() 轉換成小寫字母
UPPER() 轉換成大寫字母
LEFT() 獲取左側字符
RIGHT() 獲取右側字符
LENGTH() 獲取字符串長度
LTRIM() 刪除前導空格
RTRIM() 刪除後續空格
TRIM() 刪除前導和後續空格
SUBSTRING() 字符串截取
[NOT] LIKE 模式匹配
REPLACE() 字符串替換

函數能夠嵌套使用。
%(百分號):表明任意個字符。
_(下劃線):表明任意一個字符。數據庫

# 刪除前導'?'符號
SELECT TRIM(LEADING '?' FROM '??MySQL???');
# 刪除後續'?'符號
SELECT TRIM(TRAILING '?' FROM '??MySQL???');
# 刪除先後'?'符號
SELECT TRIM(BOTH '?' FROM '??My??SQL???');
# 將'?'符號替換成'!'符號
SELECT REPLACE('??My??SQL???', '?', '!');
# 從中'MySQL'第1個開始,截取2個字符
SELECT SUBSTRING('MySQL', 1, 2);
# 從中'MySQL'截取最後1個字符
SELECT SUBSTRING('MySQL', -1);
# 從中'MySQL'第2個開始,截取至結尾
SELECT SUBSTRING('MySQL', 2);

數值運算符函數

函數名稱 描述
CEIL() 進一取整
DIV 整數除法
FLOOR() 舍一取整
MOD 取餘數(取模)
POWER() 冪運算
ROUND() 四捨五入
TRUNCATE() 數字截取

比較運算符函數

函數名稱 描述
[NOT]BETWEEN...AND.. [不]在範圍以內
[NOT]IN() [不]在列出值範圍內
IS[NOT]NULL [不]爲空

日期時間函數

函數名稱 描述
NOW() 當前日期和時間
CURDATE() 當前日期
CURTIME() 當前時間
DATE_ADD() 日期變化
DATEDIFF() 日期差值
DATE_FORMAT() 日期格式化
# 時間增長1年
SELECT DATE_ADD('2016-05-28', INTERVAL 365 DAY);
# 時間減小1年
SELECT DATE_ADD('2016-05-28', INTERVAL -365 DAY);
# 時間增長3周
SELECT DATE_ADD('2016-05-28', INTERVAL 3 WEEK);
# 日期格式化
SELECT DATE_FORMAT('2016-05-28', '%m/%d/%Y');
# 更多時間格式能夠前往MySQL官網查看手冊

信息函數

函數名稱 描述
CONNECTION_ID() 鏈接ID
DATEBASE() 當前數據庫
LAST_INSERT_ID() 最後插入記錄的ID號
USER() 當前用戶
VERSION() 版本信息

聚合函數

函數名稱 描述
AVG() 平均值
COUNT() 計數
MAX() 最大值
MIN() 最小值
SUM() 求和

加密函數

函數名稱 描述
MD5() 信息摘要算法
PASSWORD() 密碼算法

自定義函數

用戶自定義函數(user-defined function,UDF)是一種對MySQL擴展的途徑,其用法與內置函數相同。UDF是對MySQL擴展的一種途徑。安全

必要條件

  • 參數:能夠有零個或多個服務器

  • 返回值:只能有一個網絡

參數和返回值沒有必然的聯繫。併發

建立自定義函數

CREATE FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL} routine_body函數

函數體(routine_body)

  • 函數體由合法的SQL語句構成;

  • 函數體能夠是簡單的SELECT或INSERT語句;

  • 函數體若是爲複合結構則使用BEGIN...END語句;

  • 複合結構能夠包含聲明,循環,控制結構。

示例

# 不帶參數
CREATE FUNCTION f1() RETURNS VARCHAR(30) RETURN DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');

# 帶參數
CREATE FUNCTION f2(num1 SMALLINT UNSIGNED, num2 SMALLINT UNSIGNED) RETURNS FLOAT(10, 2) UNSIGNED RETURN (num1 + num2) / 2;

# 具備複合結構函數體
# 可能須要使用DELIMITER命令修改分隔符
CREATE FUNCTION f3(username VARCHAR(20)) RETURNS INT UNSIGNED 
BEGIN 
INSERT test(username) VALUES(username);
RETURN LAST_INSERT_ID();
END

2 存儲過程

命令執行流程
存儲過程是SQL語句和控制語句的預編譯集合,以一個名稱存儲做爲一個單元處理。能夠由用戶調用執行,容許用戶聲明變量以及進行流程控制。存儲過程能夠接收輸入類型的參數,也能夠接收輸出類型的參數,並能夠存在多個返回值。執行效率比單一的SQL語句高。

優勢

  • 加強SQL語句的功能和靈活性

在存儲過程當中能夠寫控制語句具備很強的靈活性,能夠完成複雜的判斷及較複雜的運算。

  • 實現較快的執行速度

若是某一操做包含了大量的SQL語句,那麼這些SQL語句都將被MySQL引擎執行語法分析、編譯、執行,因此效率相對太低。而存儲過程是預編譯的,當客戶端第一次調用存儲過程時,MySQL的引擎將對它進行語法分析、編譯等操做,而後把這個編譯的結果存儲到內存中,因此說第一次使用的時候效率和之前是相同的。可是之後客戶端再次調用這個存儲過程時,直接從內存中執行,因此說效率比較高,速度比較快。

  • 減小網絡流量

若是經過客戶端每個單獨發送SQL語句讓服務器來執行,那麼經過http協議來提交的數據量相對來講較大。

建立

CREATE [DEFINER = {user|CURRENT_USER}] PROCEDURE sp_name ([proc_parameter[, ...]]) [characteristic ...] routine_body

proc_parameter :
[IN | OUT | INOUT] param_name type

參數:
IN,表示該參數的值必須在調用存儲過程時指定。
OUT,表示該參數值能夠被存儲過程改變,而且能夠返回。
INOUT,表示該參數的調用時指定,而且能夠被改變和返回。

特性:
COMMENT註釋
CONTAINS SQL包含SQL語句,但不包含讀或寫數據的語句。
NO SQL不包含SQL語句。
READS SQL DATA包含讀寫數據的語句。
MODIFIES SQL DATA包含寫數據的語句。
SQL SECURITY {DEFINER | INVOKER}指明誰有權限來執行。

過程體

  • 過程體由合法的SQL語句構成;

  • 過程體能夠是任意SQL語句;
    不能經過存儲過程來建立數據表、數據庫。能夠經過存儲過程對數據進行增、刪、改、查和多表鏈接操做。

  • 過程體若是爲複合結構則使用BEGIN...END語句;

  • 複合結構中能夠包含聲明、循環、控制結構。

調用

CALL sp_name ([parameter[, ...]])
CALL sp_name[()]

刪除

DROP PROCEDURE [IF EXISTS] sp_name

修改

ALTER PROCEDURE sp_name [characteristic ...] COMMENT 'string'
| {CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA}
| SQL SECURITY {DEFINER | INVOKER}

存儲過程與自定義函數的區別

  • 存儲過程實現的功能要複雜一些,而函數的針對性更強。

  • 存儲過程能夠返回多個值,函數只能有一個返回值。

  • 存儲過程通常獨立執行,函數能夠做爲其餘SQL語句的組成部分來實現。

示例:

# 建立不帶參數的存儲過程
CREATE PROCEDURE sp1() SELECT VERSION();

# 建立帶有IN類型參數的存儲過程(users爲數據表名)
# 參數的名字不能和數據表中的記錄名字同樣
CREATE PROCEDURE removeUserById(IN p_id INT UNSIGNED)
BEGIN
DELETE FROM users WHERE id = p_id;
END

# 建立帶有IN和OUT類型參數的存儲過程(users爲數據表名)
CREATE PROCEDURE removeUserAndReturnUserNumsById(IN p_id INT UNSIGNED, OUT userNums INT UNSIGNED)
BEGIN
DELETE FROM users WHERE id = p_id;
SELECT COUNT(id) FROM users INTO userNums;
END

# 建立帶有多個OUT類型參數的存儲過程(users爲數據表名)
CREATE PROCEDURE removeUserAndReturnInfosByAge(IN p_age SMALLINT UNSIGNED, OUT delUser SMALLINT UNSIGNED,  OUT userNums SMALLINT UNSIGNED)
BEGIN
DELETE FROM users WHERE age = p_age;
SELECT ROW_COUNT INTO delUser;
SELECT COUNT(id) FROM users INTO userNums;
END

3 存儲引擎

MySQL能夠將數據以不一樣的技術存儲在文件(內存)中,這種技術就稱爲存儲引擎。
每一種存儲引擎使用不一樣的存儲機制、索引技巧、鎖定水平,最終提供普遍且不一樣的功能。


  • 共享鎖(讀鎖):在同一時間段內,多個用戶能夠讀取同一個資源,讀取過程當中數據不會發生任何變化。

排他鎖(寫鎖):在任什麼時候候只能有一個用戶寫入資源,當進行寫鎖時會阻塞其餘的讀鎖或者寫鎖操做。

  • 鎖顆粒
    表鎖:是一種開銷最小的鎖策略。

行鎖:是一種開銷最大的鎖策略。

  • 併發控制
    當多個鏈接記錄進行修改時保證數據的一致性和完整性。

  • 事務
    事務用於保證數據庫的完整性。

舉例:用戶銀行轉帳
用戶A 轉帳200元 用戶B
實現步驟:
1)從當前帳戶減掉200元(帳戶餘額大於等於200元)。
2)在對方帳戶增長200元。

事務特性:
1)原子性(atomicity)
2)一致性(consistency)
3)隔離性(isolation)
4)持久性(durability)

  • 外鍵
    是保證數據一致性的策略。

  • 索引
    是對數據表中一列或多列的值進行排序的一種結構。

類型

MySQL主要支持如下幾種引擎類型:

  • MyISAM

  • InnoDB

  • Memory

  • CSV

  • Archive

各種存儲引擎特色

特色 MyISAM InnoDB Memory Archive
存儲限制 256TB 64TB
事務安全 - 支持 - -
支持索引 支持 支持 支持
鎖顆粒 表鎖 行鎖 表鎖 行鎖
數據壓縮 支持 - - 支持
支持外鍵 - 支持 - -

CSV:其實是由逗號分隔的數據引擎,在數據庫子目錄爲每個表建立一個.csv的文件,這是一種普通的文本文件,每個數據行佔用一個文本行。不支持索引。

BlackHole:黑洞引擎,寫入的數據都會消失,通常用於作數據複製的中繼。

MyISAM:適用於事務的處理很少的狀況。

InnoDB:適用於事務處理比較多,須要有外鍵支持的狀況。

索引分類:普通索引、惟一索引、全文索引、btree索引、hash索引...

修改存儲引擎

  • 經過修改MySQL配置文件
    default-storage-engine=engine_name

  • 經過建立數據表命令實現
    CREATE TABLE table_name(...)ENGINE=engine_name

  • 經過修改數據表命令實現
    ALTER TABLE table_name ENGINE[=]engine_name

4 管理工具

  • phpMyAdmin
    須要有PHP環境

  • Navicat

  • MySQL Workbench

相關文章
相關標籤/搜索