亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

1. 前言

MySQL 中支持的數據類型從整體上可以分為數值類型和日期時間類型,其中數值類型可以分為整數類型、浮點數類型、定點數類型和位類型。整數類型包含常見的 SMALLINT、MEDIUMINT、INT、BIGINT,浮點數類型主要是 FLOAT 單精度浮點數類型和 DOUBLE 雙精度浮點數類型。日期類型也有 DATE、TIME、YEAR、DATETIME、TIMESTAMP 類型。關于整數類型和浮點數類型存在一些比較常見的誤區,經常被面試官考察。

2. int (3) 和 int (11)

面試官提問: MySQL 中 int (3) 和 int (11) 這兩種用法有什么區別呢?

題目解析:

這道題非常常見,但是沒有仔細了解過 MySQL 中 int 數據類型用法的同學,很容易掉進誤區。

我們知道 varchar(m) 用于修飾變長字符,其中 m 表示能夠存儲的字符上限。

例如 username varchar(2) 在 MySQL 5.0 之后的版本表示最多接受 2 個漢字的字符作為用戶名存儲,如果長度超限會報錯:ERROR 1406 (22001): Data too long for column 'username' at row 1 。所以候選人可能會想當然的認為 int(m) 中的 m 表示存儲數字的長度,int(3)int(11) 分別表示最多存儲 3 位數和 11 位數,這種觀點是完全錯誤的!

2.1 int (3) 和 int (11) 占用的硬件存儲空間完全相同

首先,我們在申明某個字段數據類型為 int 的時候,不管是 int(3) 還是 int(11),在 MySQL 中存儲時都占用 4 個字節的長度。

1 個字節(Byte) = 8 個二進制位(bit),所以 1 個 int = 4 Byte = 4 * 8 bit = 32 bit,計算機中使用首個比特位存儲數字符號(參考補碼的定義),所以可以算出 int(m) 的存儲范圍在 [-2147483648,2147483647] 之間。

2.2 int (3) 和 int (11) 在 zerofill 關鍵詞修飾時展示不同

我們在之前創建的 mooc_demo 數據庫中創建一張測試表:

DROP TABLE IF EXISTS `test_int`;

CREATE TABLE `test_int` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '數據庫主鍵',
  `num1` int(3)  zerofill,
  `num2` int(11)  zerofill
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

再插入一條測試數據:

insert into test_int (num1, num2) values (1,1);

現在執行 select * from test_int; 查詢語句,查詢結果如圖:

圖片描述

查詢結果

如上圖所示,存儲相同的數字 1,num1 前補全了 2 個 0,num2 前補全了 10 個 0,

所以可以得出結論:int(m) 中的 m 表示在 zerofill 修飾時,數字長度不足 m 時前綴補充的 0 的個數,除此之外,兩者使用時沒有任何區別。

3. double(m,n)

面試官: MySQL 中 double (m,n) 中的 m 和 n 有什么含義?

題目解析: 這道題容易和上題一起出現,混淆視聽,但是難度相對就簡單多了。

double(m,n)、float(m,n) 以及 decimal(m,n) 中的 m 和 n 定義均相同,而且比較清晰:

  • m:數據精度,即數據的總長度;
  • n:小數點精度,即浮點數小數點后的長度。
  • 舉例說明float(6,2) 表示最多能存儲 6 位長度的浮點數,并且小數點精度為 2。

實戰驗證下上述結論, 還是在之前創建的 mooc_demo 數據庫中創建一張測試表:

DROP TABLE IF EXISTS `test_float`;

CREATE TABLE `test_float` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '數據庫主鍵',
  `num1` float(6,2)  zerofill,
  `num2` double(6,2)  zerofill
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

繼續插入測試數據:

insert into test_float (num1, num2) values (1234.5678,1234.5678); 

執行 select * from test_float; 查詢語句,查詢結果如圖:

圖片描述

查詢結果

如上圖所示,小數點 2 位之后的數據被截斷,符合 SQL 定義時的預期。

4. 小結

MySQL 基礎數據類型的知識學習可以從兩個方面入手,一點是基本語法,學習基礎語法的目的是能夠上手使用這些數據類型,另一點是如何選擇在合適的場景使用合適的數據類型,需要明確這種數據類型會占用多少的字節空間,數據類型的最小值和最大值是什么,選擇不同數據類型可能會存在什么樣的潛在問題。