MySQL 中數據類型經常使用的就三大類:php
另外還包含兩個沒那麼經常使用的大類:html
繼續以前,先來看一些單位上的約定和概念,mysql
存儲字符串時指定的類型
展現寬度/Display Width那麼什麼是展現寬度。展現寬度這個參數具備迷惑性,它不像 CREATE TABLE test_zero_fill
(
with_fill INT(5) UNSIGNED ZEROFILL NOT NULL PRIMARY KEY,
without_fill INT(5) UNSIGNED NOT NULL
);
mysql> INSERT INTO test_zero_fill (with_fill, without_fill) VALUES (5, 5),(123456, 123456);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from test_zero_fill;
+-----------+--------------+
| with_fill | without_fill |
+-----------+--------------+
| 00005 | 5 |
| 123456 | 123456 |
+-----------+--------------+
2 rows in set (0.00 sec)
另外,若是使用了 mysql> ALTER TABLE test_zero_fill ADD signed_num INT(5) signed ZEROFILL NOT NULL after without_fill;
mysql> describe test_zero_fill;
+--------------+--------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------------------+------+-----+---------+-------+
| with_fill | int(5) unsigned zerofill | NO | PRI | NULL | |
| without_fill | int(5) unsigned | NO | | NULL | |
| signed_num | int(5) unsigned zerofill | NO | | NULL | |
+--------------+--------------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
因此對於數據存儲層面來講,展現寬度其實沒什麼用途。若是真的須要格式化,程序中可以請求 MySQL 的 meta 信息以獲取到相應的展現寬度。shell 假如在 Node.js 中使用 mysqljs/mysql 做爲數據庫鏈接的模塊,在執行請求時,其回調中返回的 connection.query("SELECT * from test_zero_fill", function(
error,
results,
fields
) {
if (error) throw error;
console.log(fields);
});
FieldPacket {
catalog: 'def',
db: 'data_type',
table: 'test_zero_fill',
orgTable: 'test_zero_fill',
name: 'with_fill',
orgName: 'with_fill',
charsetNr: 63,
length: 5,
type: 3,
flags: 20579,
decimals: 0,
default: undefined,
zeroFill: true,
protocol41: true
},
FieldPacket {
catalog: 'def',
db: 'data_type',
table: 'test_zero_fill',
orgTable: 'test_zero_fill',
name: 'without_fill',
orgName: 'without_fill',
charsetNr: 63,
length: 5,
type: 3,
flags: 4129,
decimals: 0,
default: undefined,
zeroFill: false,
protocol41: true
},
FieldPacket {
catalog: 'def',
db: 'data_type',
table: 'test_zero_fill',
orgTable: 'test_zero_fill',
name: 'signed_num',
orgName: 'signed_num',
charsetNr: 63,
length: 5,
type: 3,
flags: 4193,
decimals: 0,
default: undefined,
zeroFill: true,
protocol41: true
}
]
所以,在設計表時,應該關注使用哪一種具體的數據類型可以知足數據存儲的須要,而不要被展現寬度所迷惑。ui 數字類型數字類型分爲有符號 整型MySQL 中支持標準的 SQL 整型,
而且擴展了一些類型:
如下是 MySQL 中支持的整型,及其對應所需存儲空間和取值範圍。
具體到每種類型:
mysql> SELECT IF(0, 'true', 'false');
+------------------------+
| IF(0, 'true', 'false') |
+------------------------+
| false |
+------------------------+
mysql> SELECT IF(1, 'true', 'false');
+------------------------+
| IF(1, 'true', 'false') |
+------------------------+
| true |
+------------------------+
mysql> SELECT IF(2, 'true', 'false');
+------------------------+
| IF(2, 'true', 'false') |
+------------------------+
| true |
+------------------------+
mysql> SELECT IF(0 = FALSE, 'true', 'false');
+--------------------------------+
| IF(0 = FALSE, 'true', 'false') |
+--------------------------------+
| true |
+--------------------------------+
mysql> SELECT IF(1 = TRUE, 'true', 'false');
+-------------------------------+
| IF(1 = TRUE, 'true', 'false') |
+-------------------------------+
| true |
+-------------------------------+
mysql> SELECT IF(2 = TRUE, 'true', 'false');
+-------------------------------+
| IF(2 = TRUE, 'true', 'false') |
+-------------------------------+
| false |
+-------------------------------+
mysql> SELECT IF(2 = FALSE, 'true', 'false');
+--------------------------------+
| IF(2 = FALSE, 'true', 'false') |
+--------------------------------+
| false |
+--------------------------------+
關於大整型,關鍵字 還記得建立表時通常須要指定一個自增的整形 ID 字段麼, CREATE TABLE table_name (id INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT)
CREATE TABLE table_name (id SERIAL PRIMARY KEY)
若是你不想要 BIGINT, CREATE TABLE table_name (id INT SERIAL DEFAULT VALUE PRIMARY KEY)
定點型DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL] 定點型數字,其中 M 表示總的位數(不包含正負號及小數點),D 表示小數位數。D 爲 0 則表示沒有小數部分。M 最大取值 65,默認 10;D 最大支持到 30,默認 0。全部的算術運算( DEC[(M[,D])] [UNSIGNED] [ZEROFILL], NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL], FIXED[(M[,D])] [UNSIGNED] [ZEROFILL] 同 定點型數字存儲精確的數字,用於準確性要求高的場合,好比涉及金錢。底層實現上,MySQL 使用二進制形式存儲該類型的值。 一般的用法以下: salary DECIMAL(5,2)
上面示例中,salary 爲一個 5 位精度兩位小數的定點型。取值範圍 -999.99 ~ 999.99。 由於 D 缺省時默認爲 0,因此 當實際存儲的值其小數大於指定的位數時,其精度會自動轉換成所存儲的值的精度。 浮點型區別於 DECIMAL,浮點型存儲的數字是個近似值。內部存儲時,MySQL 爲單精度使用 4 字節(bytes),雙精度使用 8 字節。 浮點型包含如下這些類型:
因此實際使用時,爲了最大限度的兼容性,直接使用 BIT 類型BIT[(M)] 類型用於存儲單個狀態值,M 表示包含幾位。默認爲1,最大可取 64。 該類型的值可經過 若是賦值到該類型上的值小於 M 指定的位數,值左邊會補零,好比將 b'101' 存儲到類型爲 BIT(6) 的列,實際會是 b'000101'。 存儲的值溢出的狀況將要存儲的值超出數字類型的範圍時,其表現跟當前設置的 SQL 模式有關。具體來講,
考察一個經過以下語句建立的表 CREATE TABLE t1 (i1 TINYINT, i2 TINYINT UNSIGNED);
SQL 嚴格模式下,嘗試寫入一個超出範圍的值時拋錯: mysql> SET sql_mode = 'TRADITIONAL';
mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
ERROR 1264 (22003): Out of range value for column 'i1' at row 1
mysql> SELECT * FROM t1;
Empty set (0.00 sec)
如下是非嚴格模式下進行裁剪存儲的狀況: mysql> SET sql_mode = '';
mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
mysql> SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'i1' at row 1 |
| Warning | 1264 | Out of range value for column 'i2' at row 1 |
+---------+------+---------------------------------------------+
mysql> SELECT * FROM t1;
+------+------+
| i1 | i2 |
+------+------+
| 127 | 255 |
+------+------+
上述表現一樣會出如今涉及到對列進行轉換修改的一些操做上,好比 進行數字計算時若是有溢出,也會拋錯,好比對於 BIGINT 其最大值爲 9223372036854775807,由於 MySQL 中默認對數字類型是有符號類型,以下操做會拋錯, mysql> SELECT 9223372036854775807 + 1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
對於上述狀況,可顯式將 被操做數進行類型轉換,轉成無符號的 BIGINT: mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1;
+-------------------------------------------+
| CAST(9223372036854775807 AS UNSIGNED) + 1 |
+-------------------------------------------+
| 9223372036854775808 |
+-------------------------------------------+
經過帶上小數後,轉成 DECIMAL 也能修正上面的錯誤,由於 DECIMAL 比整形要大, mysql> SELECT 9223372036854775807.0 + 1;
+---------------------------+
| 9223372036854775807.0 + 1 |
+---------------------------+
| 9223372036854775808.0 |
+---------------------------+
兩數相減時,其中一個爲無符號數,得出的結果默認爲也爲無符號。因此若是想減以後結果是負數,則會拋錯。 mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
除非開啓了 mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+
| CAST(0 AS UNSIGNED) - 1 |
+-------------------------+
| -1 |
+-------------------------+
總結對於整型或浮點型,可指定 對於須要精確數值的場合,使用 DECIMAL,好比涉及金錢的狀況。 對於整形,展現寬度不是其存儲的值範圍,只用來格式化。 相關資源 |