MySQL基礎語法

注:表名和列名儘可能避免使用MySQL關鍵字sql

1、經常使用SQL語句

1.DDL語句

create, alter, drop數據庫

# 建立數據庫
create database e_mall;

# 刪除數據庫
drop database e_mall;

# 建立表
create table if not exists `product_order`(
`id` bigint(20) unsigned auto_increment,
`product_id` bigint(20) unsigned not null comment '產品id',
`count` int unsigned not null comment '購買數量',
`amount` decimal(10,2) not null comment '總價格',
`create_time` datetime not null comment '下單時間',
`modified_time` datetime default null comment '修改時間',
primary key (`id`)
)engine=InnoDB default charset=utf8mb4;

# 查看錶信息
desc product_order;
# 查看建立語句
show create table product\G

# 刪除表: drop
drop table product_order;

# 修改表: alter
# 添加列: add
alter table product_order add column user_id bigint(20) unsigned not null comment '用戶id' after id;
# 刪除列: drop
alter table product_order drop column user_id;
# 修改列定義: modify
alter table product_order modify amount decimal(10,2) not null comment '總價(元)';
# 修改列定義及列名: change
alter table product_order change count quantity int unsigned not null comment '購買數量';
# 添加普通索引: add index
alter table product_order add index idx_product_id (`product_id`);
# 刪除普通索引: drop index
alter table product_order drop index idx_product_id;
# 添加惟一索引
alter table product_order add unique (`order_serial`);
# 修改表名: alter table rename
alter table product_order rename product_orders;
# 跨庫修改表名: rename table to
rename table e_mall_2.product to e_mall_0.product;

2.DML語句

insert, update, delete, select安全

# 插入記錄: insert
insert into product_order(product_id, quantity, amount, create_time) values (3, 1, 7388.00, now());
# insert select語句
insert into product_order(product_id, quantity, amount, create_time)
  select id, 2, 2*price, now() from product where id = 1;

# 更新記錄: (join) update
update product_order o join product p on o.product_id = p.id
  set o.quantity = 5, amount = 5*p.price where o.id = 1;

# 刪除記錄: delete
delete from product_order where id = 10;
# 刪除表中全部數據: truncate, 與不帶where條件的delete效果相同, 須要事務資源少, 速度快
# delete是DML語句, truncate是DDL語句
truncate table product_order;

# 查詢記錄
select * from product_order where quantity > 0 order by amount desc limit 1, 1;\
# 聚合查詢: group by [having], having關鍵字對分類後的結果再進行過濾
select product_id, count(1) as order_count, sum(quantity) as total_quantity, sum(amount) as total_amount
  from product_order where quantity > 0 group by product_id having total_quantity > 2;

# 錶鏈接查詢: join
# 全鏈接: full join
select * from product full join product_order;
# 查詢多表的全鏈接
select * from product, product_order;
# 子鏈接: in, not in, =, !=, exists, not exists
# in查詢: 索引用在product_order, 與exists的區別在於索引做用的表不一樣
select * from product_order where product_id in (select id from product);
# exists條件查詢: 當能返回結果集則爲1, 不能返回結果集則爲0; 索引用在product表
select * from product_order where exists (select * from product where product.id = product_order.product_id);

3.DCL語句

grant服務器

# 用戶受權
grant select,insert on e_mall.* to 'test_user'@'%' identified by 'Dev!@#123' with grant option;
# 幫助使用: ? Xxx
# 查看全部的show命令
? show

2、數據類型

1.數值類型

整數類型 字節數
TINYINT 1
SMALLINT 2
MEDIUMINT 3
INT, INTEGER 4
BIGINT 8
浮點數類型 字節數
FLOAT 4
DOUBLE 8
定點數類型 字節數
DEC(M,D) M+2
DECIMAL(M,D) M+2
位類型 字節數
BIT(M) 1~8(M: 1~64)

2.日期類型

類型 字節數 描述
DATETIME 8 YYYY-MM-DD HH:MM:SS
DATE 4 YYYY-MM-DD
TIME 3 HH:MM:SS
TIMESTAMP 4 時間戳

3.字符串類型

類型 字節數 描述
CHAR(M) M M: 0~255, 固定長度
VARCHAR(M) M: 0~65535, 可變長
TINYBLOB 0~255
BLOB 0~65535
MEDIUMBLOB
LONGBLOB
TINYTEXT 0~255
TEXT 0~65535
MEDIUMTEXT
LONGTEXT
BINARY(M)
VARBINARY

4.枚舉類型和SET類型

# 建立表
create table if not exists `member` (
`id` int unsigned auto_increment,
`gender` enum('M','F') not null,
`hobby` set('running','movie','music') not null,
primary key (`id`)
)engine=InnoDB default charset=utf8mb4;

# 插入記錄: 枚舉類型只能從集合中選取單個值, SET類型能夠一次選取多個成員
insert into member(gender, hobby) values ('M', 'running,movie');

3、運算符

1.算術運算符

運算符 做用
+ 加法
- 減法
* 乘法
/, DIV 除法, 返回商
%, MOD 除法, 返回餘數

2.比較運算符

運算符 做用
= 等於
<> 或 != 不等於
<=> NULL安全的等於
< 小於
<= 小於等於
> 大於
>= 大於等於
BETWEEN 存在於指定範圍
IN 存在於指定集合
IS NULL 爲NULL
IS NOT NULL 爲NULL
LIKE 通配符匹配
REGEXP 或 RLIKE 正則匹配

3.邏輯運算符

運算符 做用
NOT 或 ! 邏輯非
AND 或 && 邏輯與
OR 或 \ \ 邏輯或
XOR 邏輯異或

4.位運算符

運算符 做用
& 位與
\ 位或
^ 位異或
~ 位取反
>> 位右移
<< 位左移

5.運算的優先級

優先級順序 運算符
1 :=
2 \ \ , OR, XOR
3 &&, AND
4 NOT
5 BETWEEN, CASE, WHEN, THEN, ELSE
6 =, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
7 \
8 &
9 <<, >>
10 -, +
11 *, /, DIV, %, MOD
12 ^
13 -, ~
14 !

4、經常使用函數

1.字符串函數

函數 功能
ASCII(char) 返回字符的ASCII碼值
BIT_LENGTH(str) 返回字符串的比特長度
CONCAT(s1,s2...,sn) 將s1,s2...,sn鏈接成字符串
CONCAT_WS(sep,s1,s2...,sn) 將s1,s2...,sn鏈接成字符串,並用sep字符間隔
INSERT(str,x,y,instr) 將字符串str從第x位置開始,y個字符長的子串替換爲字符串instr,返回結果
FIND_IN_SET(str,list) 分析逗號分隔的list列表,若是發現str,返回str在list中的位置
LCASE(str) 或 LOWER(str) 返回將字符串str中全部字符改變爲小寫後的結果
LEFT(str,x) 返回字符串str中最左邊的x個字符
LENGTH(s) 返回字符串str中的字符數
LTRIM(str) 去掉字符串str左側的空格
LPAD(str,n,pad) 用字符串pad對str最左邊進行填充,直到長度爲n個字符長度
POSITION(substr,str) 返回子串substr在字符串str中第一次出現的位置
QUOTE(str) 用反斜槓轉義str中的單引號
REPEAT(str,x) 返回字符串str重複x次的結果
REPLACE(str,a,b) 用字符串b替換字符串str中全部的字符串a
REVERSE(str) 返回顛倒字符串str的結果
RIGHT(str,x) 返回字符串str中最右邊的x個字符
RTRIM(str) 去掉字符串str尾部的空格
RPAD(str,n,pad) 用字符串pad對str最右邊進行填充,直到長度爲n個字符長度
STRCMP(s1,s2) 比較字符串s1和s2
TRIM(str) 去除字符串首部和尾部的空格
SUBSTRING(str,x,y) 返回從字符串str的x位置起y個字符長度的字符串
UCASE(str) 或 UPPER(str) 返回將字符串str中全部字符轉變爲大寫後的結果

2.數值函數

函數 功能
ABS(x) 返回x的絕對值
BIN(x) 返回x的二進制(OCT返回八進制,HEX返回十六進制)
CEIL(x) 或 CEILING(x) 返回大於x的最小整數值
EXP(x) 返回值e(天然對數的底)的x次方
FLOOR(x) 返回小於x的最大整數值
GREATEST(x1,x2,...,xn) 返回集合中最大的值
LEAST(x1,x2,...,xn) 返回集合中最小的值
LN(x) 返回x的天然對數
LOG(x,y) 返回x的以y爲底的對數
MOD(x,y) 返回x除y的模(餘數)
PI() 返回pi的值(圓周率)
RAND() 返回0~1內的隨機值
ROUND(x,y) 返回參數x的四捨五入的有y位小數的值
SIGN(x) 返回表明數字x的符號的值
SQRT(x) 返回一個數的平方根
TRUNCATE(x,y) 返回數字x截短爲y位小數的結果

3.日期和時間函數

函數 功能
CURDATE() 或 CURRENT_DATE() 返回當前日期
CURTIME() 或 CURRENT_TIME() 返回當前時間
NOW() 返回當前的日期和時間
DATE_ADD(date,INTERVAL int keyword) 返回日期date加上間隔時間int的結果
DATE_SUB(date,INTERVAL int keyword) 返回日期date減去間隔時間int的結果
DATE_FORMAT(date,fmt) 返回按fmt格式化日期date值
DATE_DIFF(date1,date2) 返回date1和date2之間的天數
YEAR(date) 返回日期date的年份(1000~9999)
QUARTER(date) 返回date在一年中的季度(1~4)
MONTH(date) 返回date的月份值(1~12)
WEEK(date) 返回日期date爲一年中第幾周(0~53)
HOUR(time) 返回time的小時值(0~23)
MINUTE(time) 返回time的分鐘值(0~59)
DAYOFYEAR(date) 返回date是一年的第幾天(1~366)
DAYOFMONTH(date) 返回date是一個月的第幾天(1~31)
DAYOFWEEK(date) 返回date所表明的一星期中的第幾天(1~7)
MONTHNAME(date) 返回date的月份名
DAYNAME(date) 返回date的星期名
FROM_UNIXTIME(ts,fmt) 返回按fmt格式化UNIX時間戳ts的值
UNIX_TIMESTAMP(date) 返回date的UNIX時間戳

時間日期格式符

格式符 說明
%Y 4位數字表示的年份(2018)
%y 2位數字表示的年份(18)
%M 月名(January, February)
%b 縮寫的月名(Jan, Feb)
%m 2位數字表示的月份(01,02,...,12)
%c 數字表示的月份(1,2,...,12)
%D 英文後綴表示的月中的天數(1st, 2nd, 3rd)
%d 2位數字表示的月中的天數(01,02,...,31)
%e 數字形式表示的月中的天數(1,2,...,31)
%H 2位數字24小時制(00,01,...,23)
%h 或 %I 2位數字12小時制(01,...,12)
%k 數字的24小時制(0,1,...,23)
%l 數字的12小時制(1,2,...,12)
%i 2位數字的分(00,01,...,59)
%S 或 %s 2位數字的秒(00,01,...,59)
%T 24小時制時間格式(hh:mm:ss)
%r 12小時制時間格式(hh:mm:ssAM 或 hh:mm:ssPM)

4.聚合函數

函數 功能
AVG(col) 返回指定列的平均值
COUNT(col) 返回指定列中非NULL值的個數
SUM(col) 返回指定列的全部值之和
MAX(col) 返回指定列的最大值
MIN(col) 返回指定列的最小值
GROUP_CONCAT(col) 返回由屬於一組的列值鏈接組合而成的結果

5.流程函數

函數 功能
IF(expr,t,f) 若是expr爲真, 則返回t, 不然返回f
IFNULL(a,b) 若是a不爲空, 則返回a, 不然返回b
CASE WHEN expr1 THEN res1 ... ELSE default END 若是expr1爲真, 則返回res1, 不然default
CASE expr WHEN val1 THEN res1 ... ELSE default END 若是expr等於val1, 則返回res1, 不然返回default

6.其餘經常使用函數

函數 功能
LAST_INSERT_ID() 當前線程最後插入記錄使用的自增ID值
MD5(str) 返回字符串str的MD5散列後的值
SHA(str) 返回字符串str的SHA散列後的值
PASSWORD(str) 返回字符串str的加密版本
INET_ATON(ip) 返回ip的數字表示
INET_NTOA(num) 返回數字表明的ip地址
DATABASE() 返回當前數據庫名
VERSION() 返回MySQL服務器的版本
USER() 或 SYSTEM_USER() 返回當前登錄用戶名
CONNECTION_ID() 返回當前客戶的鏈接ID
FOUND_ROWS() 返回最後一個SELECT查詢進行檢索的總行數
BENCHMARK(count,expr) 將表達式expr重複運行count次

5、視圖、存儲過程和觸發器

1.視圖分佈式

# 建立視圖: create view ... as ...
create or replace view order_view as
  select o.order_serial, o.product_id, p.name as product_name, o.quantity, o.amount
  from product_order o inner join product p on o.product_id = o.id;
# 修改視圖: alter view ... as ...
alter view order_view as
  select o.order_serial, o.product_id, p.name as product_name, o.quantity, o.amount
  from product_order o inner join product p on o.product_id = p.id;
# 查詢視圖: select
select * from order_view;
# 刪除視圖: drop view
drop view order_view;

2.存儲過程ide

1).建立存儲過程示例:函數

# 存儲過程
# 將結束符改成"$$"
DELIMITER $$
# 建立存儲過程: 入參: product_id, user_id, 出參: handle_result
CREATE PROCEDURE purchase_product(IN p_product_id BIGINT(20), IN p_user_id BIGINT(20), OUT p_handle_result TINYINT(1))
# 指定用建立者(DEFINER)仍是調用者(INVOKER)的許可來執行
SQL SECURITY DEFINER
# 存儲過程開始
BEGIN
    # DECLARE聲明順序: 變量, 條件, 光標, 處理程序
    # ----- 定義變量: 定義變量要在定義條件以前
    DECLARE handle_result TINYINT(1) DEFAULT 0;
    # 訂單金額
    DECLARE order_amount DECIMAL(10,2) DEFAULT 0.0;
    # ----- 定義條件: 主鍵衝突, declare cond_name condition for ...
    DECLARE duplicate_key_cond CONDITION FOR sqlstate '23000';
    # ----- 定義條件處理: declare handle_type(CONTINUE:繼續, EXIT:退出) handler for ...
    DECLARE CONTINUE HANDLER FOR duplicate_key_cond SET handle_result = -1;
    # 處理SQL異常
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET handle_result = -2;
    # 開始事務
    START TRANSACTION;
    # 查詢商品價格並設爲訂單金額
    SELECT price from product where id = p_product_id INTO order_amount;
    # 插入訂單表
    INSERT INTO product_order (order_serial, product_id, user_id, quantity, amount ,create_time)
      VALUES (REPLACE(UUID(),"-",""), p_product_id, p_user_id, 1, order_amount, now());
    # 更新庫存
    UPDATE product SET stock = stock - 1 WHERE id = p_product_id and stock > 1;
    # 事務提交或回滾
    IF handle_result < 0 THEN    
        ROLLBACK;
    ELSE
        COMMIT;
    END IF;
    # 將處理賦給輸出參數p_handle_result
    SET p_handle_result = handle_result;
END
# 流程結束
$$
# 將結束符改成";"
DELIMITER ;

2).經常使用操做ui

# 1.調用存儲過程
call purchase_product(3,1,@r);
# 查看結果@r
select @r;
# 2.查看存儲過程建立語句
show create procedure purchase_product;
# 3.刪除存儲過程
drop procedure purchase_product;

3.函數(相似存儲過程): BEGIN ... END加密

# 建立函數: 計算全部商品的價值, 只有入參, 所以不須要IN和OUT標識
CREATE FUNCTION get_product_amount(p_status TINYINT(1))
# 定義返回值類型
RETURNS DECIMAL(10,2)
# 定義模式
DETERMINISTIC
READS SQL DATA
# 函數開始
BEGIN
    # 定義總價值變量
    DECLARE v_product_amount DECIMAL(10,2);
    # 定義臨時變量v_price, v_stock用於計算
    DECLARE v_price DECIMAL(10,2);
    DECLARE v_stock INT;
    # ----- 定義光標: DECLARE cursor_name CURSOR FOR select_statement
    DECLARE product_list CURSOR FOR SELECT price, stock FROM product WHERE status = p_status;
    # ----- 定義錯誤處理器, 出錯時關閉光標
    DECLARE EXIT HANDLER FOR SQLEXCEPTION CLOSE product_list;
    # 商品總價值賦初值
    SET v_product_amount = 0;
    # 開啓光標進行計算
    OPEN product_list;
    # LOOP循環處理
    outer:LOOP
        FETCH product_list INTO v_price, v_stock;
            SET v_product_amount = v_product_amount + v_price * v_stock;
    END LOOP outer;
    # 關閉光標
    CLOSE product_list;
    # 返回結果
    RETURN v_product_amount;
END
$$

4.流程控制線程

# 1.IF語句
IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF

# 2.CASE語句
CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE
# 或
CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list]
END CASE

# 3.LOOP(循環) + LEAVE(相似break: 退出) + ITERATE(相似continue: 直接進入下一輪循環)語句示例:
outer: LOOP
    set @x = @x + 1;
    IF @x = 100 THEN
        # break
        LEAVE outer;
    ELSE
        # continue
        ITERATE outer;
    END IF;
END LOOP outer;

# 4.REPEAT: 條件知足時退出循環
[label:] REPEAT
    statement_list
UNTIL search_condition
END REPEAT[label]

# 5.WHILE: 條件知足時執行循環
[label:] WHILE search_condition DO
    statement_list
END WHILE[label]

5.事件調度器: 相似Linux下的crontab

# 建立EVENT
CREATE EVENT uuid_generate_event
    ON SCHEDULE EVERY 10 SECOND
    DO
        INSERT INTO e_mall.uuid_gen(uuid) values (REPLACE(UUID(),'-',''));
# 查看全部EVENT
SHOW EVENTS\G
# 刪除EVENT
DROP EVENT uuid_generate_event;

6.觸發器

觸發器只能建立在永久表(Permanent Table)上, 不能用於臨時表(Temporary Table)

# 建立觸發器
CREATE TRIGGER trigger_name trigger_time trigger_event
    ON table_name FOR EACH ROW trigger_statement
# trigger_time: 觸發時間, 分爲BEFORE(檢查約束前觸發)和AFTER(檢查約束後觸發)
# trigger_event: 觸發事件, INSERT, UPDATE 或 DELETE
DELIMITER $$
CREATE TRIGGER insert_user_trigger
AFTER INSERT ON user FOR EACH ROW
BEGIN
    insert into uuid_gen(uuid) values (REPLACE(UUID(),'-',''));
END
$$
DELIMITER ;

# 查看觸發器
show triggers\G
# 刪除觸發器
drop trigger insert_user_trigger;

6、事務

1.普通事務

start transaction, commit, rollback, commit and chain; (自動開啓一個新的事務)

# 開啓事務
start transaction;
# 執行SQL
delete from product_order where id = 8;
# 此時查詢時id=8的記錄已刪除
select * from product_order;
# 回滾事務
rollback;
# 回滾後能夠查詢到id=8的記錄
select * from product_order;

2.分佈式事務: XA事務

# 1.流程
# 1).啓動XA事務
XA {START|BEGIN} xid [JOIN|RESUME]
# xid爲XA事務標識符, 格式爲 xid: gtrid[, bqual[, formatID]]
# gtrid: 分佈式事務標識符, 同一個分佈式事務應使用相同的gtrid
# bqual: 分支限定符, 一個分佈式事務中的每一個分支事務, 其bqual值必須惟一
# formatID: 用於標識gtrid和bqual值使用的格式, 默認值爲1
# 2).執行業務SQL
# 3).XA事務完結
XA END xid
# 4).XA分支事務準備
XA PREPARE xid
# 5).XA分支事務詳細信息查詢(輔助功能)
XA RECOVER
# 6).提交XA分支事務
XA COMMIT xid
# 7).或者回滾分支事務
XA ROLLBACK xid

# 2.示例
# 1).啓動一個分支事務, 產品庫存減1, xid的gtrid爲'order_tran', bqual爲'product'
XA START 'order_tran'.'product';
UPDATE product SET stock = stock - 1 where id = 1;
XA END 'order_tran'.'product';
# 2).啓動另外一個分支事務, 插入訂單
XA START 'order_tran'.'order';
INSERT INTO product_order(product_id, create_time) VALUES (1, NOW());
XA END 'order_tran'.'order';
# 3).'product'分支事務準備提交
XA PREPARE 'order_tran'.'product';
# 4).'order'分支事務準備提交
XA PREPARE 'order_tran'.'order';
# 5).提交全部分支事務
XA COMMIT 'order_tran'.'product';
XA COMMIT 'order_tran'.'order';
相關文章
相關標籤/搜索