You are currently viewing 資料類型及常用函數

資料類型及常用函數

資料類型

數值類型

整數

整數類型Storage (Bytes)Minimum Value SignedMinimum Value UnsignedMaximum Value SignedMaximum Value Unsigned
TINYINT1-1280127255
SMALLINT2-3276803276765535
MEDIUMINT3-83886080838860716777215
INT4-2147483648021474836474294967295
BIGINT8$-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
DATE4 bytes"0000-00-00"
TIME3 bytes"00:00:00"
DATETIME8 bytes"0000-00-00 00:00:00"
TIMESTAMP4 bytesTIMESTAMP(M)00000000000000
YEAR1 bytes0000
運算符號作用
=等於
<> 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 個位元組abcd5 個位元組
"abcdefgh""abcd"4 個位元組abcd5 個位元組

注意表中最後一行的值,只適用 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 存在的差異以及問題如下:

  1. 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 )
%T24 小時的時間形式( hh:mm:ss
%r12 小時的時間形式( hh:mm:ss AM or hh:mm:ss PM
%pAM 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 )
%Y4 位數字表示的年份
%y2 位數字表示的年份
%%"%"

DATE_ADD(date, INTERVAL expr type) 的 type 類型

運算式類型描述格式
HOUR小時hh
MINUTEmm
SECONDss
YEARYY
MONTHMM
DAYDD
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 值

Beck Yeh

熱愛學習於 Linux 與 程式設計 在網站中分享各式各樣學習到的新知識

發佈留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料