Table of Contents
資料類型
數值類型
整數
整數類型 | Storage (Bytes) | Minimum Value Signed | Minimum Value Unsigned | Maximum Value Signed | Maximum Value Unsigned |
---|---|---|---|---|---|
TINYINT | 1 | -128 | 0 | 127 | 255 |
SMALLINT | 2 | -32768 | 0 | 32767 | 65535 |
MEDIUMINT | 3 | -8388608 | 0 | 8388607 | 16777215 |
INT | 4 | -2147483648 | 0 | 2147483647 | 4294967295 |
BIGINT | 8 | $-2^{63}$ | 0 | $2^{63}$-1 | $2^{64}$-1 |
浮點與定點數
當一個欄位被定義為浮點類型後,如果插入資料的精度超過該列定義的實際精度,則插入值會被四捨五入到實際定義的精度值,四捨五入的過程不會回報錯誤。在 MySQL 中 float、double( 或 real )用來表示浮點數
MySQL 浮點型和定點型可以用類型名稱后加( M, D )來表示,M 表示該值的總共長度,D 表示小數點後面的長度,M 和D 又稱為精度和標度,如 float(7, 4)
的可顯示為 -999.9999,MySQL 保存值時進行四捨五入,如果插入 999.00009,則結果為 999.0001。
FLOAT 和 DOUBLE 在不指定精度時,默認會按照實際的精度來顯示,而 DECIMAL 在不指定精度時,默認整數為 10,小數為 0。
mysql> CREATE TABLE t (f FLOAT(8, 1));
Query OK, 0 rows affected (0.00 sec)
mysql> DESC t;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| f | float(8,1) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> INSERT INTO t VALUES (1.23456);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t;
+------+
| f |
+------+
| 1.2 |
+------+
1 row in set (0.00 sec)
mysql> INSERT INTO t VALUES (1.25456);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t;
+------+
| f |
+------+
| 1.2 |
| 1.3 |
+------+
2 rows in set (0.00 sec)
浮點數與定點數的區別:
mysql> CREATE TABLE test (c1 FLOAT(10, 2), c2 DECIMAL(10, 2));
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO test VALUES (131072.32, 131072.32);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM test;
+-----------+-----------+
| c1 | c2 |
+-----------+-----------+
| 131072.31 | 131072.32 |
+-----------+-----------+
1 row in set (0.00 sec)
日期與時間型別
欄位資料型別 | 型別大小 | 語法 | Zero Value |
---|---|---|---|
DATE | 4 bytes | "0000-00-00" | |
TIME | 3 bytes | "00:00:00" | |
DATETIME | 8 bytes | "0000-00-00 00:00:00" | |
TIMESTAMP | 4 bytes | TIMESTAMP(M) | 00000000000000 |
YEAR | 1 bytes | 0000 |
運算符號 | 作用 |
---|---|
= | 等於 |
<> or != | 不等於 |
<=> | NULL 安全的等於( NULL – safe ) |
< | 小於 |
<= | 小於等於 |
> | 大於 |
>= | 大於等於 |
BETWEEN | 存在於指定範圍 |
IN | 存在於指定集合 |
IS NULL | 為 NULL |
IS NOT NULL | 不為 NULL |
LIKE | 萬用字元做匹配 |
REGEXP or RLIKE | 正則表達式來做匹配 |
運算符號 | 作用 |
---|---|
NOT or ! | 邏輯非 |
AND or && | 邏輯與 |
OR or || | 邏輯或 |
XOR | 邏輯異或 |
文字類型
CHAR 與 VARCHAR
CHAR 和 VARCHAR 的對比
值 | CHAR(4) | 儲存需求 | VARCHAR(4) | 儲存需求 |
---|---|---|---|---|
"" | " " | 4 個位元組 | "" | 1 個位元組 |
"ab" | "ab " | 4 個位元組 | "ab " | 3 個位元組 |
"abcd" | "abcd" | 4 個位元組 | abcd | 5 個位元組 |
"abcdefgh" | "abcd" | 4 個位元組 | abcd | 5 個位元組 |
注意表中最後一行的值,只適用 MySQL 運行在非『 嚴格模式 』時。
從 CHAR(4) 與 VARCHAR(4) 檢索的值並不總是相同,因為檢索 CHAR 時,刪除了尾部的空格:
mysql> CREATE TABLE vc (v VARCHAR(4), c char(4));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO vc VALUES ("ab ", "ab ");
Query OK, 1 row affected (0.00 sec)
mysql> SELECT CONCAT(v, "+"), CONCAT(c, "+") FROM vc;
+----------------+----------------+
| CONCAT(v, "+") | CONCAT(c, "+") |
+----------------+----------------+
| ab + | ab+ |
+----------------+----------------+
1 row in set (0.00 sec)
由於 CHAR 是固定長度的,所以他的速度會比 VARCHAR 快的許多,但是其缺點是浪費儲存空間
另外隨著 MySQL 的升級,VARCHAR 的性能也在不斷提升,所以被更多的使用
不同引擎對 CHAR、VARCHAR 的使用原則也不盡相同,簡單概括如下:
- MyISAM 儲存引擎:建議使用固定長度
- MEMORY 儲存引擎:目前都使用固定長度的資料來儲存,因此無論使用 CHAR 或 VARCHAR 都一樣
- InnoDB 儲存引擎:建議使用 VARCHAR 類型。對於 InnoDB 資料表,內部的行儲存格式沒有區分固定長度和可變長度列( 所有資料行都使用指向資料列值的標頭 ),因此使用固定長度的 CHAR 不一定會比 VARCHAR 性能來得好,因此主要的差異是資料所使用的儲存總量。
TEXT 與 BLOB
TEXT 只能保存字元資料,而 BLOB 可以保存二進制資料例如照片。TEXT 和 BLOB 中又分別包含 TEXT、MEDIUMTEXT、LONGTEXT 和 BLOB、MEDIUMBLOB、LONGBLOB 三種不同類型,使用者須依照情形選擇
而 BLOB 與 TEXT 存在的差異以及問題如下:
BLOB 與 TEXT 值會引起一些性能問題,特別是在執行了大量的刪除操作時。
刪除操作會在資料表中留下很大的『 空洞 』,以後填入這些『 空洞 』的紀錄在插入的性能上會有影響。為了提高性能,建議定期使用 OPTIMIZE TABLE 功能來對這類型態的表進行從組。
僅在 MyISAM 下有影響,因為 InnoDB 會自動 OPTIMIZE
mysql> CREATE TABLE m (id VARCHAR(100), context TEXT); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO m VALUES(1, REPEAT("haha", 100)); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO m VALUES(2, REPEAT("haha", 100)); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO m VALUES(3, REPEAT("haha", 100)); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO m select * FROM m; Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 .... .... mysql> INSERT INTO m select * FROM m; Query OK, 49152 rows affected (0.69 sec) Records: 49152 Duplicates: 0 Warnings: 0 mysql> INSERT INTO m select * FROM m; Query OK, 98304 rows affected (1.46 sec) Records: 98304 Duplicates: 0 Warnings: 0 mysql> INSERT INTO m select * FROM m; Query OK, 196608 rows affected (2.94 sec) Records: 196608 Duplicates: 0 Warnings: 0
[root@localhost emp]# ll -h m* -rw-rw----. 1 mysql mysql 8.4K Nov 2 14:05 m.frm -rw-rw----. 1 mysql mysql 155M Nov 2 14:08 m.MYD -rw-rw----. 1 mysql mysql 1.0K Nov 2 14:08 m.MYI
mysql> DELETE FROM m WHERE id=1; Query OK, 131072 rows affected (1.70 sec)
[root@localhost emp]# ll -h m* -rw-rw----. 1 mysql mysql 8.4K Nov 2 14:05 m.frm -rw-rw----. 1 mysql mysql 155M Nov 2 14:08 m.MYD -rw-rw----. 1 mysql mysql 1.0K Nov 2 14:08 m.MYI
mysql> OPTIMIZE TABLE m; +-------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +-------+----------+----------+----------+ | emp.m | optimize | status | OK | +-------+----------+----------+----------+ 1 row in set (0.58 sec)
[root@localhost emp]# ll -h m* -rw-rw----. 1 mysql mysql 8.4K Nov 2 14:05 m.frm -rw-rw----. 1 mysql mysql 103M Nov 2 14:10 m.MYD -rw-rw----. 1 mysql mysql 1.0K Nov 2 14:10 m.MYI
函數
字串函數
函數 | 功能 |
---|---|
CONCAT(S1, S2, ..., Sn) | 連接 S1, S2, …, Sn 為一個字串 |
INSERT(str, x, y, insert) | 將字串 str 從 x 位置開始,y 個字元長的字串替換為字串 insert |
LOWER(str) | 將字串 str 中所有字元變成小寫 |
UPER(str) | 將字串 str 中所有字元變成大寫 |
LEFT(str, x) | 回傳字串 str 最左邊的 x 個字元 |
RIGHT(str, x) | 回傳字串 str 最右邊的 y 個字元 |
LPAD(str, n, pad) | 用字串 pad 對 str 最左邊進行填充,直到長度為 n 個字元長度 |
RPAD(str, n, pad) | 用字串 pad 對 str 最右邊進行填充,直到長度為 n 個字元長度 |
LTRIM(str) | 去掉字串 str 左側的空格 |
RTRIM(str) | 去掉字串 str 右側的空格 |
REPEAT(str, x) | 回傳 str 重複 x 次的結果 |
REPLACE(str, a, b) | 用字串 b 替換字串 str 中所有出現的字串 a |
STRCMP(s1, s2) | 比較字串 s1 和 s2 |
TRIM(str) | 去掉字串行尾和行頭的空格 |
SUBSTRING(str, x, y) | 回傳從字串 str x 位置起 y 個字元長度的字串 |
數值函數
函數 | 功能 |
---|---|
ABS(x) | 回傳 x 的絕對值 |
CEIL(x) | 回傳大於 x 的最小整數值 |
FLOOR(x) | 回傳小於 x 的最大整數值 |
MOD(x, y) | 回傳 x/y 的餘數 |
RAND() | 回傳 0 ~ 1 內的隨機值 |
ROUND(x, y) | 回傳參數 x 的四捨五入的有 y 位小數的值 |
TRUNCATE(x, y) | 回傳數字 x 截斷為 y 字元小數的結果 |
日期和時間函數
函數 | 功能 |
---|---|
CURDATE() | 回傳當前日期 |
CURTIME() | 回傳當前時間 |
NOW() | 回傳當前的日期和時間 |
UNIX_TIMESTAMP(date) | 回傳日期 date 的 unix 時間戳記 |
FROM_UNIXTIME(timestamp) | 回傳 unix 時間戳記的日期值 |
WEEK(date) | 回傳日期 date 為一年中的第幾週 |
YEAR(date) | 回傳日期 date 的年份 |
HOUR(time) | 回傳 time 的小時值 |
MINUTE(time) | 回傳 time 的分鐘值 |
MONTHNAME(date) | 回傳 date 的月份名 |
DATE_FORMAT(date, fmt) | 回傳按字串 fmt 格式化日期 date 值 |
DATE_ADD(date, INTERVAL expr type) | 回傳一個日期或時間值加上一個時間間隔的時間值 |
DATEDIFF(expr, expr2) | 回傳起始時間 expr 和結束時間 expr2 之間的天數 |
MySQL 中的日期和時間格式
格式符號 | 格式說明 |
---|---|
%S or %s | 兩位數字形式的秒( 00, 01, …., 59 ) |
%i | 兩位數字形式的分( 00, 01, …., 59 ) |
%H | 兩位數字形式的小時,24 小時( 00, 01, …, 23 ) |
%h or %I | 兩位數字形式的小時,12 小時( 00, 01, …, 12 ) |
%k | 數字形式的小時,24 小時( 0, 1, …, 23 ) |
%l | 數字形式的小時,12 小時( 0, 1, …, 12 ) |
%T | 24 小時的時間形式( hh:mm:ss ) |
%r | 12 小時的時間形式( hh:mm:ss AM or hh:mm:ss PM ) |
%p | AM or PM |
%W | 一週中每一天的名稱( Sunday, Monday, …, Saturday ) |
%a | 一週中每一天的名稱的縮寫( sun, mon, …, sat ) |
%d | 兩位數字表示月中的天數( 01, 02, …., 31 ) |
%e | 數字表示月中的天數( 1, 2, …., 31 ) |
%D | 英文尾碼表示月中的天數( 1st, 2nd, 3rd, … ) |
%w | 以數字形式表示周中的天數( 0=Sunday, 1=Monday, …, 6=Saturday ) |
%j | 以 3 位數字表示年中的天數( 001, 002, …, 366 ) |
%U | 周( 0, 1, 52 ),其中 Sunday 為周中的第一天 |
%u | 周( 0, 1, 52 ),其中 Monday 為周中的第一天 |
%M | 月名( January, February, …, December ) |
%b | 縮寫的月名 |
%m | 兩位數字表示的月份( 01, 02, …, 12 ) |
%c | 數字表示的月份( 1, 2, …, 12 ) |
%Y | 4 位數字表示的年份 |
%y | 2 位數字表示的年份 |
%% | "%" |
DATE_ADD(date, INTERVAL expr type)
的 type 類型
運算式類型 | 描述 | 格式 |
---|---|---|
HOUR | 小時 | hh |
MINUTE | 分 | mm |
SECOND | 秒 | ss |
YEAR | 年 | YY |
MONTH | 月 | MM |
DAY | 日 | DD |
YEAR_MONTH | 年和月 | YY-MM |
DAY_HOUR | 日和小時 | DD hh |
DAY_MINUTE | 日和小時和分鐘 | DD hh:mm |
DAY_SECOND | 日和小時和分鐘和秒 | DD hh:mm:ss |
HOUR_MINUTE | 小時和分 | hh:mm |
HOUR_SECOND | 小時和秒 | hh:ss |
MINUTE_SECOND | 分鐘和秒 | mm:ss |
mysql> select now() current, date_add(now(), INTERVAL '01 01:01:01' DAY_SECOND);
+---------------------+----------------------------------------------------+
| current | date_add(now(), INTERVAL '01 01:01:01' DAY_SECOND) |
+---------------------+----------------------------------------------------+
| 2020-08-25 19:20:04 | 2020-08-26 20:21:05 |
+---------------------+----------------------------------------------------+
流程函數
MySQL 中的流程函數
函數 | 功能 |
---|---|
IF(Condition, t, f) | 如果 value 是真,回傳 t,否則回傳 f |
IFNULL(value1, value2) | 如果 value1 不為空,回傳 value1,否則回傳 value2 |
CASE WHEN [value1] THEN [result]... ELSE [default] END | 如果 value1 是真,回傳 value1,否則回傳 default |
CASE [expr] WHEN [value1] THEN [result1] ... ELSE [default] END | 如果 expr 等於 value1,回傳 result1,否則回傳 default |
其他常用函數
MySQL 中的其他常用函數
函數 | 功能 |
---|---|
DATABASE() | 回傳當前資料庫名稱 |
VERSION() | 回傳當前資料庫版本 |
USER() | 回傳當前登錄使用者名稱 |
INET_ATON(ip) | 回傳 IP 位址的數字使用 |
INET_NTOA(num) | 回傳數字代表的 IP 位址 |
PASSWORD(str) | 回傳字串 str 的加密版本 |
MD5() | 回傳字串 str 的 MD5 值 |