MySQL進階
目錄
基本操作
help 幫助
help timpstampdiff;
登入 退出
- 登入 service mysqld start mysql -uroot -p123456 - 退出 quit
簡單查詢,不區分大小寫
# 檢視版本號及當前時間
select version(),user(),current_date;
# 行末 \c 表示放棄執行
資料庫的建立及使用
create database menagerie;
use menagerie
表的建立和使用
# 建立 create table pet( -> name varchar(20), -> owner varchar(20), -> species varchar(20), -> sex char(1), -> birth date, -> death date); # 檢視創表語句 show create table pet; # 查看錶結構 desc pet;
表中匯入資料
# 方法1 使用insert into insert into pet values('Fluffy','Harold','cat','f','1993-02-04'); ... 或者 pet.txt 上傳至Linux本地,注意都是製表符 Fluffy Harold cat f 1993-02-04 Claws Gwen cat m 1994-03-17 Buffy Harold dog f 1989-05-13 Fang Benny dog m 1990-08-27 Bowser Diane dog m 1979-08-31 1995-07-29 Chirpy Gwen bird f 1998-09-11 Whistler Gwen bird \N 1997-12-09 \N Slim Benny snake m 1996-04-29 # 執行 load data local infile '/opt/data/sql/pet.txt'into table pet; # 刪除所有表資料 delete from pet;
資料檢索部分
# 資料更新
update pet set death=null where death='0000-00-00';
# 查詢生日在98以後
select * from pet where birth>'1998-01-01';
# 多條件查詢,優先執行括號中的語句
SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm')
# 去除重複 distinct
# 排序 order by
select * from pet
order by birth,species desc;
按照 birth 升序,species 降序
日期計算
# 檢視寵物年齡
SELECT TIMESTAMPDIFF(YEAR,birth,curdate()) as age from pet;
# 檢視沒死的寵物年齡(null和not null 要用 is 去比較)
SELECT TIMESTAMPDIFF(YEAR,birth,curdate()) as age from pet
-> where death is null;
資料庫的備份與恢復
- 備份命令
語法:mysqldump -u 使用者名稱 -p 資料庫名> 磁碟SQL檔案路徑
由於mysqldump命令不是sql命令,需要在dos視窗下使用(即退出mysql後執行)。
mysqldump -uroot -p123456 menagerie >/opt/data/sql/menagerie.sql
- 恢復命令
語法:mysql -u 使用者名稱-p 匯入庫名< 硬碟SQL檔案絕對路徑
需求:
1、恢復資料庫,需要手動的先建立資料庫:
create database heima;
2、重新開啟一個新的dos視窗。
//恢復命令
mysql -uroot -p123456 heima </opt/data/sql/menagerie.sql
case when 語句
# 建立表
create table employee(
-> empid int ,
-> deptid int ,
-> sex varchar(20) ,
-> salary double
-> );
# 表資料上傳至 /opt/data/sql/ 下
1 10 female 5500.0
2 10 male 4500.0
3 20 female 1900.0
4 20 male 4800.0
5 40 female 6500.0
6 40 female 14500.0
7 40 male 44500.0
8 50 male 6500.0
9 50 male 7500.0
# 新增資料
load data local infile '/opt/data/sql/employee.txt' into table employee;
# 按照salary分級,5000,10000,15000之間分別表示為 低等收入,中等收入,高等收入
select *,
case
when salary < 5000 then "低等收入"
when salary>= 5000 and salary < 10000 then "中等收入"
when salary > 10000 then "高等收入"
end as level,
case sex
when "female" then 1
when "male" then 0
end as flag
from employee;
# case when then else end
select * , case when deptid<40 then "部門1" else "部門2" end as "部門" from employee;
group by 語句
# 準備表
CREATE TABLE `employee_tbl` (
`id` int(11) NOT NULL,
`name` char(10) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`singin` tinyint(4) NOT NULL DEFAULT '0' COMMENT '登入次數',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
INSERT INTO `employee_tbl` VALUES ('1', '小明', '2016-04-22 15:25:33', '1'),
('2', '小王', '2016-04-20 15:25:47', '3'),
('3', '小麗', '2016-04-19 15:26:02', '2'), ('4', '小王', '2016-04-07 15:26:14', '4'),
('5', '小明', '2016-04-11 15:26:40', '4'), ('6', '小明', '2016-04-04 15:26:54', '2');
# 使用 group by 實現簡單的去重查詢
select name from employee_tbl group by name;
# 在其後使用having 限定
MySQL 元資料
- 查詢結果資訊: SELECT, UPDATE 或 DELETE語句影響的記錄數。
- 資料庫和資料表的資訊: 包含了資料庫及資料表的結構資訊。
- MySQL伺服器資訊: 包含了資料庫伺服器的當前狀態,版本號等。
命令 | 描述 |
---|---|
SELECT VERSION( ) | 伺服器版本資訊 |
SELECT DATABASE( ) | 當前資料庫名 (或者返回空) |
SELECT USER( ) | 當前使用者名稱 |
SHOW STATUS | 伺服器狀態 |
SHOW VARIABLES | 伺服器配置變數 |
mysql 函式
MySQL 字串函式
函式 | 描述 | 例項 |
---|---|---|
ASCII(s) | 返回字串 s 的第一個字元的 ASCII 碼。 | 返回 CustomerName 欄位第一個字母的 ASCII 碼:SELECT ASCII(CustomerName) AS NumCodeOfFirstCharFROM Customers; |
CHAR_LENGTH(s) | 返回字串 s 的字元數 | 返回字串 itcast 的字元數SELECT CHAR_LENGTH("itcast") AS LengthOfString; |
CHARACTER_LENGTH(s) | 返回字串 s 的字元數 | 返回字串 itcast 的字元數SELECT CHARACTER_LENGTH("itcast") AS LengthOfString; |
CONCAT(s1,s2...sn) | 字串 s1,s2 等多個字串合併為一個字串 | 合併多個字串SELECT CONCAT("SQL ", "itcast ", "Gooogle ", "Facebook") AS ConcatenatedString; |
CONCAT_WS(x, s1,s2...sn) | 同 CONCAT(s1,s2,...) 函式,但是每個字串直接要加上 x,x 可以是分隔符 | 合併多個字串,並新增分隔符:SELECT CONCAT_WS("-", "SQL", "Tutorial", "is", "fun!")AS ConcatenatedString; |
FIELD(s,s1,s2...) | 返回第一個字串 s 在字串列表(s1,s2...)中的位置 | 返回字串 c 在列表值中的位置:SELECT FIELD("c", "a", "b", "c", "d", "e"); |
FIND_IN_SET(s1,s2) | 返回在字串s2中與s1匹配的字串的位置 | 返回字串 c 在指定字串中的位置:SELECT FIND_IN_SET("c", "a,b,c,d,e"); |
**FORMAT(x,n) ** | 函式可以將數字 x 進行格式化 "#,###.##", 將 x 保留到小數點後 n 位,最後一位四捨五入。 | 格式化數字 "#,###.##" 形式:SELECT FORMAT(250500.5634, 2); -- 輸出 250,500.56 |
INSERT(s1,x,len,s2) | 字串 s2 替換 s1 的 x 位置開始長度為 len 的字串 | 從字串第一個位置開始的 6 個字元替換為 itcast:SELECT INSERT("google.com", 1, 6, "runnob"); -- 輸出:runnob.com |
LOCATE(s1,s) | 從字串 s 中獲取 s1 的開始位置 | 獲取 b 在字串 abc 中的位置:SELECT INSTR('abc','b') -- 2 |
**LCASE(s) ** | 將字串 s 的所有字母變成小寫字母 | 字串 itcast 轉換為小寫:SELECT LOWER('itcast') -- itcast |
LEFT(s,n) | 返回字串 s 的前 n 個字元 | 返回字串 itcast 中的前兩個字元:SELECT LEFT('itcast',2) -- it |
LEFT(s,n) | 返回字串 s 的前 n 個字元 | 返回字串 abcde 的前兩個字元:SELECT LEFT('abcde',2) -- ab |
LOCATE(s1,s) | 從字串 s 中獲取 s1 的開始位置 | 返回字串 abc 中 b 的位置:SELECT LOCATE('b', 'abc') -- 2 |
**LOWER(s) ** | 將字串 s 的所有字母變成小寫字母 | 字串 itcast 轉換為小寫:SELECT LOWER('itcast') -- itcast |
LPAD(s1,len,s2) | 在字串 s1 的開始處填充字串 s2,使字串長度達到 len | 將字串 xx 填充到 abc 字串的開始處:SELECT LPAD('abc',5,'xx') -- xxabc |
LTRIM(s) | 去掉字串 s 開始處的空格 | 去掉字串 itcast開始處的空格:SELECT LTRIM(" itcast") AS LeftTrimmedString;-- itcast |
MID(s,n,len) | 從字串 s 的 start 位置擷取長度為 length 的子字串,同 SUBSTRING(s,n,len) | 從字串 itcast 中的第 2 個位置擷取 3個 字元:SELECT MID("itcast", 2, 3) AS ExtractString; -- tca |
POSITION(s1 IN s) | 從字串 s 中獲取 s1 的開始位置 | 返回字串 abc 中 b 的位置:SELECT POSITION('b' in 'abc') -- 2 |
** REPEAT(s,n) ** | 將字串 s 重複 n 次 | 將字串 itcast 重複三次:SELECT REPEAT('itcast',3) -- itcastitcastitcast |
**REPLACE(s,s1,s2) ** | 將字串 s2 替代字串 s 中的字串 s1 | 將字串 abc 中的字元 a 替換為字元 x:SELECT REPLACE('abc','a','x') --xbc |
REVERSE(s) | 將字串s的順序反過來 | 將字串 abc 的順序反過來:SELECT REVERSE('abc') -- cba |
RIGHT(s,n) | 返回字串 s 的後 n 個字元 | 返回字串 itcast 的後兩個字元:SELECT RIGHT('itcast',2) -- st |
RPAD(s1,len,s2) | 在字串 s1 的結尾處新增字串 s1,使字串的長度達到 len | 將字串 xx 填充到 abc 字串的結尾處:SELECT RPAD('abc',5,'xx') -- abcxx |
RTRIM(s) | 去掉字串 s 結尾處的空格 | 去掉字串 itcast 的末尾空格:SELECT RTRIM("itcast ") AS RightTrimmedString; -- itcast |
SPACE(n) | 返回 n 個空格 | 返回 10 個空格:SELECT SPACE(10); |
**STRCMP(s1,s2) ** | 比較字串 s1 和 s2,如果 s1 與 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1<s2 返回 -1 | 比較字串:SELECT STRCMP("itcast", "itcast"); -- 0 |
**SUBSTR(s, start, length) ** | 從字串 s 的 start 位置擷取長度為 length 的子字串 | 從字串 itcast 中的第 2 個位置擷取 3個 字元:SELECT SUBSTR("itcast", 2, 3) AS ExtractString; -- tca |
SUBSTRING(s, start, length) | 從字串 s 的 start 位置擷取長度為 length 的子字串 | 從字串 itcast 中的第 2 個位置擷取 3個 字元:SELECT SUBSTRING("itcast", 2, 3) AS ExtractString; -- tca |
SUBSTRING_INDEX(s, delimiter, number) | 返回從字串 s 的第 number 個出現的分隔符 delimiter 之後的子串。如果 number 是正數,返回第 number 個字元左邊的字串。如果 number 是負數,返回第(number 的絕對值(從右邊數))個字元右邊的字串。 | SELECT SUBSTRING_INDEX('a*b','*',1) -- aSELECT SUBSTRING_INDEX('a*b','*',-1) -- bSELECT SUBSTRING_INDEX(SUBSTRING_INDEX('a*b*c*d*e','*',3),'*',-1) -- c |
TRIM(s) | 去掉字串 s 開始和結尾處的空格 | 去掉字串 itcast 的首尾空格:SELECT TRIM(' itcast ') AS TrimmedString; |
UCASE(s) | 將字串轉換為大寫 | 將字串 itcast 轉換為大寫:SELECT UCASE("itcast"); -- itcast |
UPPER(s) | 將字串轉換為大寫 | 將字串 itcast 轉換為大寫:SELECT UPPER("itcast"); -- itcast |
MySQL 數字函式
函式名 | 描述 | 例項 |
---|---|---|
**ABS(x) ** | 返回 x 的絕對值 | 返回 -1 的絕對值:SELECT ABS(-1) -- 返回1 |
ACOS(x) | 求 x 的反餘弦值(引數是弧度) | SELECT ACOS(0.25); |
ASIN(x) | 求反正弦值(引數是弧度) | SELECT ASIN(0.25); |
ATAN(x) | 求反正切值(引數是弧度) | SELECT ATAN(2.5); |
ATAN2(n, m) | 求反正切值(引數是弧度) | SELECT ATAN2(-0.8, 2); |
AVG(expression) | 返回一個表示式的平均值,expression 是一個欄位 | 返回 Products 表中Price 欄位的平均值:SELECT AVG(Price) AS AveragePrice FROM Products; |
CEIL(x) | 向上取整 | SELECT CEIL(1.5) -- 返回2 |
CEILING(x) | 向上取整 | SELECT CEIL(1.5) -- 返回2 |
COS(x) | 求餘弦值(引數是弧度) | SELECT COS(2); |
COT(x) | 求餘切值(引數是弧度) | SELECT COT(6); |
COUNT(expression) | 返回查詢的記錄總數,expression 引數是一個欄位或者 * 號 | 返回 Products 表中 products 欄位總共有多少條記錄:SELECT COUNT(ProductID) AS NumberOfProducts FROM Products; |
DEGREES(x) | 將弧度轉換為角度 | SELECT DEGREES(3.1415926535898) -- 180 |
n DIV m | 整除,n 為被除數,m 為除數 | 計算 10 除於 5:SELECT 10 DIV 5; -- 2 |
EXP(x) | 返回 e 的 x 次方 | 計算 e 的三次方:SELECT EXP(3) -- 20.085536923188 |
**FLOOR(x) ** | 向下取整 | 小於或等於 1.5 的整數:SELECT FLOOR(1.5) -- 返回1 |
GREATEST(expr1, expr2, expr3, ...) | 返回列表中的最大值 | 返回以下數字列表中的最大值:SELECT GREATEST(3, 12, 34, 8, 25); -- 34 返回以下字串列表中的最大值:SELECT GREATEST("Google", "itcast", "Apple"); -- itcast |
LEAST(expr1, expr2, expr3, ...) | 返回列表中的最小值 | 返回以下數字列表中的最小值:SELECT LEAST(3, 12, 34, 8, 25); -- 3 返回以下字串列表中的最小值:SELECT LEAST("Google", "itcast", "Apple"); -- Apple |
LN | **返回數字的自然對數 ** | 返回 2 的自然對數:SELECT LN(2); -- 0.6931471805599453 |
LOG(x) | 返回自然對數(以 e 為底的對數) | SELECT LOG(20.085536923188) -- 3 |
LOG10(x) | 返回以 10 為底的對數 | SELECT LOG10(100) -- 2 |
**LOG2(x) ** | **返回以 2 為底的對數 ** | 返回以 2 為底 6 的對數:SELECT LOG2(6); -- 2.584962500721156 |
**MAX(expression) ** | 返回欄位 expression 中的最大值 | 返回資料表 Products 中欄位 Price 的最大值:SELECT MAX(Price) AS LargestPrice FROM Products; |
MIN(expression) | 返回欄位 expression 中的最小值 | 返回資料表 Products 中欄位 Price 的最小值:SELECT MIN(Price) AS LargestPrice FROM Products; |
MOD(x,y) | 返回 x 除以 y 以後的餘數 | 5 除於 2 的餘數:SELECT MOD(5,2) -- 1 |
PI() | 返回圓周率(3.141593) | SELECT PI() --3.141593 |
POW(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POW(2,3) -- 8 |
POWER(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POWER(2,3) -- 8 |
RADIANS(x) | 將角度轉換為弧度 | 180 度轉換為弧度:SELECT RADIANS(180) -- 3.1415926535898 |
RAND() | 返回 0 到 1 的隨機數 | SELECT RAND() --0.93099315644334 |
**ROUND(x) ** | **返回離 x 最近的整數 ** | SELECT ROUND(1.23456) --1 |
SIGN(x) | 返回 x 的符號,x 是負數、0、正數分別返回 -1、0 和 1 | SELECT SIGN(-10) -- (-1) |
SIN(x) | 求正弦值(引數是弧度) | SELECT SIN(RADIANS(30)) -- 0.5 |
SQRT(x) | 返回x的平方根 | 25 的平方根:SELECT SQRT(25) -- 5 |
SUM(expression) | 返回指定欄位的總和 | 計算 OrderDetails 表中欄位 Quantity 的總和:SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails; |
TAN(x) | 求正切值(引數是弧度) | SELECT TAN(1.75); -- -5.52037992250933 |
TRUNCATE(x,y) | 返回數值 x 保留到小數點後 y 位的值(與 ROUND 最大的區別是不會進行四捨五入) | SELECT TRUNCATE(1.23456,3) -- 1.234 |
MySQL 日期函式
函式名 | 描述 | 例項 |
---|---|---|
ADDDATE(d,n) | **計算其實日期 d 加上 n 天的日期 ** | SELECT ADDDATE("2017-06-15", INTERVAL 10 DAY);->2017-06-25 |
ADDTIME(t,n) | 時間 t 加上 n 秒的時間 | SELECT ADDTIME('2011-11-11 11:11:11', 5)->2011-11-11 11:11:16 (秒) |
CURDATE() | 返回當前日期 | SELECT CURDATE();-> 2018-09-19 |
CURRENT_DATE() | 返回當前日期 | SELECT CURRENT_DATE();-> 2018-09-19 |
CURRENT_TIME | 返回當前時間 | SELECT CURRENT_TIME();-> 19:59:02 |
CURRENT_TIMESTAMP() | 返回當前日期和時間 | SELECT CURRENT_TIMESTAMP()-> 2018-09-19 20:57:43 |
CURTIME() | 返回當前時間 | SELECT CURTIME();-> 19:59:02 |
DATE() | **從日期或日期時間表達式中提取日期值 ** | SELECT DATE("2017-06-15"); -> 2017-06-15 |
DATEDIFF(d1,d2) | 計算日期 d1->d2 之間相隔的天數 | SELECT DATEDIFF('2001-01-01','2001-02-02')-> -32 |
DATE_ADD(d,INTERVAL expr type) | 計算起始日期 d 加上一個時間段後的日期 | SELECT ADDDATE('2011-11-11 11:11:11',1)-> 2011-11-12 11:11:11 (預設是天)SELECT ADDDATE('2011-11-11 11:11:11', INTERVAL 5 MINUTE)-> 2011-11-11 11:16:11 (TYPE的取值與上面那個列出來的函式類似) |
DATE_FORMAT(d,f) | 按表示式 f的要求顯示日期 d | SELECT DATE_FORMAT('2011-11-11 11:11:11','%Y-%m-%d %r')-> 2011-11-11 11:11:11 AM |
DATE_SUB(date,INTERVAL expr type) | 函式從日期減去指定的時間間隔。 | Orders 表中 OrderDate 欄位減去 2 天:SELECT OrderId,DATE_SUB(OrderDate,INTERVAL 2 DAY) AS OrderPayDateFROM Orders |
DAY(d) | 返回日期值 d 的日期部分 | SELECT DAY("2017-06-15"); -> 15 |
DAYNAME(d) | 返回日期 d 是星期幾,如 Monday,Tuesday | SELECT DAYNAME('2011-11-11 11:11:11')->Friday |
DAYOFMONTH(d) | 計算日期 d 是本月的第幾天 | SELECT DAYOFMONTH('2011-11-11 11:11:11')->11 |
DAYOFWEEK(d) | 日期 d 今天是星期幾,1 星期日,2 星期一,以此類推 | SELECT DAYOFWEEK('2011-11-11 11:11:11')->6 |
DAYOFYEAR(d) | 計算日期 d 是本年的第幾天 | SELECT DAYOFYEAR('2011-11-11 11:11:11')->315 |
EXTRACT(type FROM d) | 從日期 d 中獲取指定的值,type 指定返回的值。 type可取值為: | SELECT EXTRACT(MINUTE FROM '2011-11-11 11:11:11') -> 11 |
ROM_DAYS(n) | 計算從 0000 年 1 月 1 日開始 n 天后的日期 | SELECT FROM_DAYS(1111)-> 0003-01-16 |
HOUR(t) | 返回 t 中的小時值 | SELECT HOUR('1:2:3')-> 1 |
LAST_DAY(d) | 返回給給定日期的那一月份的最後一天 | SELECT LAST_DAY("2017-06-20");-> 2017-06-30 |
LOCALTIME() | 返回當前日期和時間 | SELECT LOCALTIME()-> 2018-09-19 20:57:43 |
LOCALTIMESTAMP() | 返回當前日期和時間 | SELECT LOCALTIMESTAMP()-> 2018-09-19 20:57:43 |
MAKEDATE(year, day-of-year) | 基於給定引數年份 year 和所在年中的天數序號 day-of-year 返回一個日期 | SELECT MAKEDATE(2017, 3);-> 2017-01-03 |
MAKETIME(hour, minute, second) | 組合時間,引數分別為小時、分鐘、秒 | SELECT MAKETIME(11, 35, 4);-> 11:35:04 |
MICROSECOND(date) | 返回日期引數所對應的毫秒數 | SELECT MICROSECOND("2017-06-20 09:34:00.000023");-> 23 |
MINUTE(t) | 返回 t 中的分鐘值 | SELECT MINUTE('1:2:3')-> 2 |
MONTHNAME(d) | 返回日期當中的月份名稱,如 Janyary | SELECT MONTHNAME('2011-11-11 11:11:11')-> November |
MONTH(d) | 返回日期d中的月份值,1 到 12 | SELECT MONTH('2011-11-11 11:11:11')->11 |
NOW() | 返回當前日期和時間 | SELECT NOW()-> 2018-09-19 20:57:43 |
PERIOD_ADD(period, number) | 為 年-月 組合日期新增一個時段 | SELECT PERIOD_ADD(201703, 5); -> 201708 |
PERIOD_DIFF(period1, period2) | 返回兩個時段之間的月份差值 | SELECT PERIOD_DIFF(201710, 201703);-> 7 |
QUARTER(d) | 返回日期d是第幾季節,返回 1 到 4 | SELECT QUARTER('2011-11-11 11:11:11')-> 4 |
SECOND(t) | 返回 t 中的秒鐘值 | SELECT SECOND('1:2:3')-> 3 |
SEC_TO_TIME(s) | 將以秒為單位的時間 s 轉換為時分秒的格式 | SELECT SEC_TO_TIME(4320)-> 01:12:00 |
STR_TO_DATE(string, format_mask) | 將字串轉變為日期 | SELECT STR_TO_DATE("August 10 2017", "%M %d %Y");-> 2017-08-10 |
SUBDATE(d,n) | 日期 d 減去 n 天后的日期 | SELECT SUBDATE('2011-11-11 11:11:11', 1)->2011-11-10 11:11:11 (預設是天) |
SUBTIME(t,n) | 時間 t 減去 n 秒的時間 | SELECT SUBTIME('2011-11-11 11:11:11', 5)->2011-11-11 11:11:06 (秒) |
SYSDATE() | 返回當前日期和時間 | SELECT SYSDATE()-> 2018-09-19 20:57:43 |
TIME(expression) | 提取傳入表示式的時間部分 | SELECT TIME("19:30:10");-> 19:30:10 |
TIME_FORMAT(t,f) | 按表示式 f 的要求顯示時間 t | SELECT TIME_FORMAT('11:11:11','%r')11:11:11 AM |
TIME_TO_SEC(t) | 將時間 t 轉換為秒 | SELECT TIME_TO_SEC('1:12:00')-> 4320 |
TIMEDIFF(time1, time2) | 計算時間差值 | SELECT TIMEDIFF("13:10:11", "13:10:10");-> 00:00:01 |
TIMESTAMP(expression, interval) | 單個引數時,函式返回日期或日期時間表達式;有2個引數時,將引數加和 | SELECT TIMESTAMP("2017-07-23", "13:10:11");-> 2017-07-23 13:10:11 |
TO_DAYS(d) | 計算日期 d 距離 0000 年 1 月 1 日的天數 | SELECT TO_DAYS('0001-01-01 01:01:01')-> 366 |
WEEK(d) | 計算日期 d 是本年的第幾個星期,範圍是 0 到 53 | SELECT WEEK('2011-11-11 11:11:11')-> 45 |
WEEKDAY(d) | 日期 d 是星期幾,0 表示星期一,1 表示星期二 | SELECT WEEKDAY("2017-06-15");-> 3 |
WEEKOFYEAR(d) | 計算日期 d 是本年的第幾個星期,範圍是 0 到 53 | SELECT WEEKOFYEAR('2011-11-11 11:11:11')-> 45 |
YEAR(d) | 返回年份 | SELECT YEAR("2017-06-15");-> 2017 |
YEARWEEK(date, mode) | 返回年份及第幾周(0到53),mode 中 0 表示周天,1表示週一,以此類推 | SELECT YEARWEEK("2017-06-15");-> 201724 |
MySQL 高階函式
函式名 | 描述 | 例項 |
---|---|---|
BIN(x) | 返回 x 的二進位制編碼 | 15 的 2 進位制編碼:SELECT BIN(15); -- 1111 |
BINARY(s) | 將字串 s 轉換為二進位制字串 | SELECT BINARY "itcast";-> itcast |
CASE expression WHEN condition1 THEN result1 WHEN condition2 THEN result2 ... WHEN conditionN THEN resultN ELSE resultEND |
CASE 表示函式開始,END 表示函式結束。如果 condition1 成立,則返回 result1, 如果 condition2 成立,則返回 result2,當全部不成立則返回 result,而當有一個成立之後,後面的就不執行了。 | SELECT CASE WHEN 1 > 0 THEN '1 > 0' WHEN 2 > 0 THEN '2 > 0' ELSE '3 > 0' END->1 > 0 |
CAST(x AS type) | 轉換資料型別 | 字串日期轉換為日期:SELECT CAST("2017-08-29" AS DATE);-> 2017-08-29 |
COALESCE(expr1, expr2, ...., expr_n) | 返回引數中的第一個非空表示式(從左向右) | SELECT COALESCE(NULL, NULL, NULL, 'itcast.com', NULL, 'google.com');-> itcast.com |
CONNECTION_ID() | 返回伺服器的連線數 | SELECT CONNECTION_ID();-> 4292835 |
CONV(x,f1,f2) | 返回 f1 進位制數變成 f2 進位制數 | SELECT CONV(15, 10, 2);-> 1111 |
CONVERT(s USING cs) | 函式將字串 s 的字符集變成 cs | SELECT CHARSET('ABC')->utf-8 SELECT CHARSET(CONVERT('ABC' USING gbk))->gbk |
CURRENT_USER() | 返回當前使用者 | SELECT CURRENT_USER();-> guest@% |
DATABASE() | 返回當前資料庫名 | SELECT DATABASE(); -> itcast |
IF(expr,v1,v2) | 如果表示式 expr 成立,返回結果 v1;否則,返回結果 v2。 | SELECT IF(1 > 0,'正確','錯誤') ->正確 |
IFNULL(v1,v2) | 如果 v1 的值不為 NULL,則返回 v1,否則返回 v2。 | SELECT IFNULL(null,'Hello Word')->Hello Word |
ISNULL(expression) | 判斷表示式是否為空 | SELECT ISNULL(NULL);->1 |
LAST_INSERT_ID() | 返回最近生成的 AUTO_INCREMENT 值 | SELECT LAST_INSERT_ID();->6 |
NULLIF(expr1, expr2) | 比較兩個字串,如果字串 expr1 與 expr2 相等 返回 NULL,否則返回 expr1 | SELECT NULLIF(25, 25);-> |
SESSION_USER() | 返回當前使用者 | SELECT SESSION_USER();-> guest@% |
SYSTEM_USER() | 返回當前使用者 | SELECT SYSTEM_USER();-> guest@% |
USER() | 返回當前使用者 | SELECT USER();-> guest@% |
VERSION() | 返回資料庫的版本號 | SELECT VERSION()-> 5.6.34 |
MySQL 索引
# 索引可以大大提高MySQL的檢索速度。索引分單列索引和組合索引。
單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。
組合索引,即一個索引包含多個列。
建立索引時,你需要確保該索引是應用在 SQL 查詢語句的條件(一般作為 WHERE 子句的條件)。
實際上,索引也是一張表,該表儲存了主鍵與索引欄位,並指向實體表的記錄。
# 索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和DELETE。
因為更新表時,MySQL不僅要儲存資料,還要儲存一下索引檔案。
建立索引會佔用磁碟空間的索引檔案。
普通索引
# 建立索引
CREATE INDEX indexName ON mytable(username(length)); // length 表示 索引欄位的前length個欄位建索引
//建立索引
create index id on B(A_ID);
# 修改表結構時新增
ALTER table tableName ADD INDEX indexName(columnName)
# 建立表時直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length))
);
# 刪除索引
drop index [indexname] on mytable
唯一索引
在普通索引基礎上,所有建索引的索引名前 加上 unique
MySQL事務
顯示索引
SHOW INDEX FROM table_name;
mysql 事務
含義
通過一組邏輯操作單元(一組DML——sql語句),將資料從一種狀態切換到另外一種狀態
MySQL 事務主要用於處理操作量大,複雜度高的資料。
- 在 MySQL 中只有使用了 Innodb 資料庫引擎的資料庫或表才支援事務。
- 事務處理可以用來維護資料庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
- 事務用來管理 insert,update,delete 語句
特點
一般來說,事務是必須滿足4個條件(ACID)::原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、永續性(Durability)。
- 原子性:一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,在中間某個環節不會結束。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
- 一致性:在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續資料庫可以自發性地完成預定的工作。
- 隔離性:資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致資料的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(Serializable)。
- 永續性:事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失。
相關步驟:
事務的分類:
# 隱式事務,沒有明顯的開啟和結束事務的標誌
比如 insert、update、delete語句本身就是一個事務
# 顯式事務,具有明顯的開啟和結束事務的標誌
1、開啟事務
取消自動提交事務的功能
2、編寫事務的一組邏輯操作單元(多條sql語句)
insert,update,delete
3、提交事務或回滾事務
例如
#開啟事務
SET autocommit=0;
START TRANSACTION;
#編寫一組事務的語句
UPDATE account SET balance = 1000 WHERE username='張無忌';
UPDATE account SET balance = 1000 WHERE username='趙敏';
#結束事務
ROLLBACK;
#commit;
SELECT * FROM account;
MySQL 執行引擎
首先簡單瞭解下MySQL執行引擎,首先MySQL執行引擎分類比較多,InnoDB(重要)、MyIsam(重要)、Memory、Mrg_Myisam、Blackhole等,雖然看著多,不過在日常學習和使用過程中只需要掌握InnoDB和MyIsam即可。下面對比InnoDB和MyISAM的區別:
1.InnoDB(事務型資料庫引擎)
- 優點:InnoDB是一個事務型的儲存引擎,有行級鎖定和外來鍵約束,提供了對資料庫ACID事務的支援,並且實現了SQL標準的四種隔離級別,設計目標是處理大容量資料庫系統;
- 缺點:不支援全文索引,而且它沒有儲存表的行數,當SELECT COUNT(*) FROM TABLE時需要掃描全表;
- 適用場景:經常更新的表,適合處理多重併發的更新請求,需要事務、外來鍵;
2.MyISAM(分析型資料庫引擎)
- 優點:支援全文型別索引,索引和記錄分開儲存,並存儲了表的行數,所以select count(*)效率很高(不加where);
- 缺點:不支援資料庫事務,更新操作需要鎖定整個表,不支援行級鎖和外來鍵;
- 適用場景:經常讀取資料的場合,更新操作少;
MySQL 語句優化
- 那麼如何提高資料庫SQL語句執行速度呢?有人會說效能調優是資料庫管理員(DBA)的事,然而效能調優跟程式設計師們也有莫大的關係。
-
技巧1 比較運算子能用 “=”就不用“<>”
“=”增加了索引的使用機率。 -
技巧2 明知只有一條查詢結果,那請使用 “LIMIT 1”
“LIMIT 1”可以避免全表掃描,找到對應結果就不會再繼續掃描了。 -
技巧3 為列選擇合適的資料型別
能用TINYINT就不用SMALLINT,能用SMALLINT就不用INT,道理你懂的,磁碟和記憶體消耗越小越好嘛。
-
技巧4 將大的DELETE,UPDATE or INSERT 查詢變成多個小查詢
能寫一個幾十行、幾百行的SQL語句是不是顯得逼格很高?然而,為了達到更好的效能以及更好的資料控制,你可以將他們變成多個小查詢。 -
技巧5 使用UNION ALL 代替 UNION,如果結果集允許重複的話
因為 UNION ALL 不去重,效率高於 UNION。 -
技巧6 為獲得相同結果集的多次執行,請保持SQL語句前後一致
這樣做的目的是為了充分利用查詢緩衝。
比如根據地域和產品id查詢產品價格,第一次使用了:
那麼第二次同樣的查詢,請保持以上語句的一致性,比如不要將where語句裡面的id和region位置調換順序。
- 技巧7 儘量避免使用 “SELECT *”
如果不查詢表中所有的列,儘量避免使用 SELECT *,它將以磁碟掃描方式取出單條資料的末尾,而欄位方式則會直接取到資料項。
(1)SELECT *,需要資料庫先 Query Table Metadata For Columns,一定程度上為資料庫增加了負擔。
但是實際上,兩者效率差別不大。
(2)考慮到今後的擴充套件性。
因為程式裡面你需要使用到的列畢竟是確定的, SELECT * 只是減少了一句 SQL String 的長度,並不能減少其他地方的程式碼。
- 技巧8 WHERE 子句裡面的列儘量被索引
只是“儘量”哦,並不是說所有的列。因地制宜,根據實際情況進行調整,因為有時索引太多也會降低效能。
- 技巧9 JOIN 子句裡面的列儘量被索引
同樣只是“儘量”哦,並不是說所有的列。
- 技巧10 ORDER BY 的列儘量被索引
ORDER BY的列如果被索引,效能也會更好。
- 技巧11 使用 LIMIT 實現分頁邏輯
不僅提高了效能,同時減少了不必要的資料庫和應用間的網路傳輸。
- 技巧12 使用 EXPLAIN 關鍵字去檢視執行計劃
EXPLAIN 可以檢查索引使用情況以及掃描的行。