《MySQL技術內幕:SQL程式設計》讀書筆記 -- 資料型別
一、資料屬性
1.1 UNSIGNED
UNSIGNED是將數字型別無符號化,例如:INT類型範圍為 -2147483648 ~ 2147483647,INT UNSIGNED表示的範圍為 0 ~ 4294967295。
注意:UNSIGNED會有以下問題:
mysql> create table test ( a int unsigned, b int unsigned); Query OK, 0 rows affected (0.05 sec) mysql> insert into test values(1, 2); Query OK, 1 row affected (0.04 sec) mysql> select a-b from test; ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(`test`.`test`.`a` - `test`.`test`.`b`)'
可以發現,a-b 並不是我們預想中的 -1,這是為什麼呢,因為:-1 的 FFFFFFFF,而FFFFFFFF所代表的無符號數為:4294967295,有符號數為:首位為符號位,1表示負數,取反加1結果為-1;
所以這個值不一定,可能是-1,可能是很大的正值,在mac系統中會報上面的錯誤。
1.2 ZEROFILL
作用是用0填充空白位,請看下面例子:
mysql> create table test (a int(4) unsigned zerofill); Query OK, 0 rows affected (0.06 sec) mysql> insert into test values(1); Query OK, 1 row affected (0.01 sec) mysql> select * from test; +------+ | a | +------+ | 0001 | +------+ 1 row in set (0.00 sec)
二、日期和時間型別
MySQL有五種日期和時間相關的型別,具體佔用空間情況如下:
型別 | 所佔用空間 |
DATETIME | 8位元組 |
DATE | 3位元組 |
TIMESTAMP | 4位元組 |
YEAR | 1位元組 |
TIME | 3位元組 |
DATETIME:
日期範圍 1000-01-01 00:00:00 ~ 9999-12-23 23:59:59;
DATE:
日期範圍 1000-01-01 ~ 9999-12-23;
TIMESTAMP:
日期範圍 1970-01-01 00:00:00 ~ 2038-01-19 03:14:07;
YEAR:
可用DEFAULT CURRENT_TIMESTAMP 設初始值,用ON UPDATE CURRENT_TIMESTAMP自動更新修改時間;
可以指定寬度為YEAR(4)或YEAR(2),YEAR(4)對應的年份範圍 1901 ~ 2155;YEAR(2)對應的年份範圍 1970 ~ 2070,在YEAR(2)下,00~69表示 2000 ~ 2069年
TIME:
表示範圍為 -838:59:59 ~ 838:59:59;
三、數字型別
3.1 整型
型別 | 佔用空間(位元組) | 最小值(signed/unsigned) | 最大值(signed/unsigned) |
TINYINT | 1 |
-128 0 |
127 255 |
SMALLINT | 2 |
-32768 0 |
32767 65535 |
MEDIUMINT | 3 |
-8388608 0 |
8388607 16777215 |
INT | 4 |
-2147483648 0 |
2147483648 4294967295 |
BIGINT | 8 |
-9223372036854775808 0 |
9223372036854775808 18446744073709551615 |
3.2 浮點型(非精確型別)
有 FLOAT 和 DOUBLE PRECISION,非精度型別不能保證計算的正確性,例如M*G/G不一定等於M。
3.3 高精度型別
有DECIMAL和NUMBER兩種型別,最大位數為65位。
3.4 位型別
BIT(m)表示儲存m位數值,m範圍1~64,所佔用空間 (m+7)/8位元組,如果插入值位數小於m,左邊補0;
四、字元型別
4.1 CHAR、VARCHAR
CHAR(N)用來儲存固定長度的字串,N的範圍為 0 ~ 255 、VARCHAR(N)用來儲存變長字串,N的範圍為 0 ~ 65535;其中N代表字元長度,而非位元組長度。
CHAR(10)佔位10位毫無疑問,但是VARCHAR(10)的最大佔用空間為11位,因為需要1位來儲存字元長度,當n > 255時,需要用2位的空間來儲存字元長度。
4.3 BINARY、VARBINARY
BINARY、VARBINARY和CHAR、VARCHAR型別,不同的是,BINARY、VARBINARY儲存的是二進位制的字串,另外不同的一點是做比較時,CHAR、VARCHAR會忽略填充字元,而BINARY、VARBINARY因為儲存的填充字元的二進位制數值,所以在做比較的時候結果會不同:
mysql> select hex(binary('a')), hex(binary('a ')), binary('a') = binary('a ');
+------------------+-------------------+----------------------------+
| hex(binary('a')) | hex(binary('a ')) | binary('a') = binary('a ') |
+------------------+-------------------+----------------------------+
| 61 | 6120 | 0 |
+------------------+-------------------+----------------------------+
1 row in set (0.00 sec)
mysql> select hex(char('a')), hex(char('a ')), char('a') = char('a ');
+----------------+-----------------+------------------------+
| hex(char('a')) | hex(char('a ')) | char('a') = char('a ') |
+----------------+-----------------+------------------------+
| 00 | 00 | 1 |
+----------------+-----------------+------------------------+
1 row in set, 4 warnings (0.00 sec)
4.4 BLOB、TEXT
BLOB和TEXT是用來儲存二級制大資料型別,根據儲存長度不同,可以分為以下幾種型別:
BLOB型別 | TEXT型別 |
TINYBLOB() | TINYTEXT() |
BLOB() | TEXT() |
MEDIUMBLOB() | MEDIUMTEXT() |
LONGBLOB() | LONGTEXT() |
4.5 ENUM、SET
ENUM和SET都是列舉型別,不同的是ENUM最多可列舉 65536個元素,二SET最多可列舉64個元素,通常可配合sql_mode進行約束,如果插入不存在的列舉值,報錯:
mysql> set sql_mode = 'STRICT_TRANS_TABLES';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> create table `person`(name varchar(50) not null, sex enum('Man', 'WMan'));
Query OK, 0 rows affected (0.10 sec)
mysql> insert into person values('Bob', 'M');
ERROR 1265 (01000): Data truncated for column 'sex' at row 1
mysql> insert into person values('Bob', 'Man');
Query OK, 1 row affected (0.09 sec)
mysql> select * from person;
+------+------+
| name | sex |
+------+------+
| Bob | Man |
+------+------+
1 row in set (0.00 sec)