注:表名和列名儘可能避免使用MySQL關鍵字
sql
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;
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);
grant
服務器
# 用戶受權 grant select,insert on e_mall.* to 'test_user'@'%' identified by 'Dev!@#123' with grant option; # 幫助使用: ? Xxx # 查看全部的show命令 ? show
整數類型 | 字節數 |
---|---|
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) |
類型 | 字節數 | 描述 |
---|---|---|
DATETIME | 8 | YYYY-MM-DD HH:MM:SS |
DATE | 4 | YYYY-MM-DD |
TIME | 3 | HH:MM:SS |
TIMESTAMP | 4 | 時間戳 |
類型 | 字節數 | 描述 |
---|---|---|
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 |
# 建立表 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');
運算符 | 做用 |
---|---|
+ | 加法 |
- | 減法 |
* | 乘法 |
/, DIV | 除法, 返回商 |
%, MOD | 除法, 返回餘數 |
運算符 | 做用 |
---|---|
= | 等於 |
<> 或 != | 不等於 |
<=> | NULL安全的等於 |
< | 小於 |
<= | 小於等於 |
> | 大於 |
>= | 大於等於 |
BETWEEN | 存在於指定範圍 |
IN | 存在於指定集合 |
IS NULL | 爲NULL |
IS NOT NULL | 爲NULL |
LIKE | 通配符匹配 |
REGEXP 或 RLIKE | 正則匹配 |
運算符 | 做用 | ||
---|---|---|---|
NOT 或 ! | 邏輯非 | ||
AND 或 && | 邏輯與 | ||
OR 或 \ | \ | 邏輯或 | |
XOR | 邏輯異或 |
運算符 | 做用 | |
---|---|---|
& | 位與 | |
\ | 位或 | |
^ | 位異或 | |
~ | 位取反 | |
>> | 位右移 | |
<< | 位左移 |
優先級順序 | 運算符 | ||
---|---|---|---|
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 | ! |
函數 | 功能 |
---|---|
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中全部字符轉變爲大寫後的結果 |
函數 | 功能 |
---|---|
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位小數的結果 |
函數 | 功能 |
---|---|
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) |
函數 | 功能 |
---|---|
AVG(col) | 返回指定列的平均值 |
COUNT(col) | 返回指定列中非NULL值的個數 |
SUM(col) | 返回指定列的全部值之和 |
MAX(col) | 返回指定列的最大值 |
MIN(col) | 返回指定列的最小值 |
GROUP_CONCAT(col) | 返回由屬於一組的列值鏈接組合而成的結果 |
函數 | 功能 |
---|---|
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 |
函數 | 功能 |
---|---|
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次 |
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;
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';