1. 前言
MySQL 中支持的數(shù)據(jù)類型從整體上可以分為數(shù)值類型和日期時(shí)間類型,其中數(shù)值類型可以分為整數(shù)類型、浮點(diǎn)數(shù)類型、定點(diǎn)數(shù)類型和位類型。整數(shù)類型包含常見的 SMALLINT、MEDIUMINT、INT、BIGINT,浮點(diǎn)數(shù)類型主要是 FLOAT 單精度浮點(diǎn)數(shù)類型和 DOUBLE 雙精度浮點(diǎn)數(shù)類型。日期類型也有 DATE、TIME、YEAR、DATETIME、TIMESTAMP 類型。關(guān)于整數(shù)類型和浮點(diǎn)數(shù)類型存在一些比較常見的誤區(qū),經(jīng)常被面試官考察。
2. int (3) 和 int (11)
面試官提問: MySQL 中 int (3) 和 int (11) 這兩種用法有什么區(qū)別呢?
題目解析:
這道題非常常見,但是沒有仔細(xì)了解過 MySQL 中 int 數(shù)據(jù)類型用法的同學(xué),很容易掉進(jìn)誤區(qū)。
我們知道 varchar(m) 用于修飾變長字符,其中 m 表示能夠存儲的字符上限。
例如 username varchar(2) 在 MySQL 5.0 之后的版本表示最多接受 2 個(gè)漢字的字符作為用戶名存儲,如果長度超限會報(bào)錯(cuò):ERROR 1406 (22001): Data too long for column 'username' at row 1 。所以候選人可能會想當(dāng)然的認(rèn)為 int(m) 中的 m 表示存儲數(shù)字的長度,int(3) 和 int(11) 分別表示最多存儲 3 位數(shù)和 11 位數(shù),這種觀點(diǎn)是完全錯(cuò)誤的!
2.1 int (3) 和 int (11) 占用的硬件存儲空間完全相同
首先,我們在申明某個(gè)字段數(shù)據(jù)類型為 int 的時(shí)候,不管是 int(3) 還是 int(11),在 MySQL 中存儲時(shí)都占用 4 個(gè)字節(jié)的長度。
1 個(gè)字節(jié)(Byte) = 8 個(gè)二進(jìn)制位(bit),所以 1 個(gè) int = 4 Byte = 4 * 8 bit = 32 bit,計(jì)算機(jī)中使用首個(gè)比特位存儲數(shù)字符號(參考補(bǔ)碼的定義),所以可以算出 int(m) 的存儲范圍在 [-2147483648,2147483647] 之間。
2.2 int (3) 和 int (11) 在 zerofill 關(guān)鍵詞修飾時(shí)展示不同
我們在之前創(chuàng)建的 mooc_demo 數(shù)據(jù)庫中創(chuàng)建一張測試表:
DROP TABLE IF EXISTS `test_int`;
CREATE TABLE `test_int` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '數(shù)據(jù)庫主鍵',
`num1` int(3) zerofill,
`num2` int(11) zerofill
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
再插入一條測試數(shù)據(jù):
insert into test_int (num1, num2) values (1,1);
現(xiàn)在執(zhí)行 select * from test_int; 查詢語句,查詢結(jié)果如圖:

如上圖所示,存儲相同的數(shù)字 1,num1 前補(bǔ)全了 2 個(gè) 0,num2 前補(bǔ)全了 10 個(gè) 0,
所以可以得出結(jié)論:int(m) 中的 m 表示在 zerofill 修飾時(shí),數(shù)字長度不足 m 時(shí)前綴補(bǔ)充的 0 的個(gè)數(shù),除此之外,兩者使用時(shí)沒有任何區(qū)別。
3. double(m,n)
面試官: MySQL 中 double (m,n) 中的 m 和 n 有什么含義?
題目解析: 這道題容易和上題一起出現(xiàn),混淆視聽,但是難度相對就簡單多了。
double(m,n)、float(m,n) 以及 decimal(m,n) 中的 m 和 n 定義均相同,而且比較清晰:
- m:數(shù)據(jù)精度,即數(shù)據(jù)的總長度;
- n:小數(shù)點(diǎn)精度,即浮點(diǎn)數(shù)小數(shù)點(diǎn)后的長度。
- 舉例說明:
float(6,2)表示最多能存儲 6 位長度的浮點(diǎn)數(shù),并且小數(shù)點(diǎn)精度為 2。
實(shí)戰(zhàn)驗(yàn)證下上述結(jié)論, 還是在之前創(chuàng)建的 mooc_demo 數(shù)據(jù)庫中創(chuàng)建一張測試表:
DROP TABLE IF EXISTS `test_float`;
CREATE TABLE `test_float` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '數(shù)據(jù)庫主鍵',
`num1` float(6,2) zerofill,
`num2` double(6,2) zerofill
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
繼續(xù)插入測試數(shù)據(jù):
insert into test_float (num1, num2) values (1234.5678,1234.5678);
執(zhí)行 select * from test_float; 查詢語句,查詢結(jié)果如圖:

如上圖所示,小數(shù)點(diǎn) 2 位之后的數(shù)據(jù)被截?cái)?,符?SQL 定義時(shí)的預(yù)期。
4. 小結(jié)
MySQL 基礎(chǔ)數(shù)據(jù)類型的知識學(xué)習(xí)可以從兩個(gè)方面入手,一點(diǎn)是基本語法,學(xué)習(xí)基礎(chǔ)語法的目的是能夠上手使用這些數(shù)據(jù)類型,另一點(diǎn)是如何選擇在合適的場景使用合適的數(shù)據(jù)類型,需要明確這種數(shù)據(jù)類型會占用多少的字節(jié)空間,數(shù)據(jù)類型的最小值和最大值是什么,選擇不同數(shù)據(jù)類型可能會存在什么樣的潛在問題。
阿竺 ·
2025 imooc.com All Rights Reserved |