聊聊mysql中的int(1)
昨天有個讀者問了我這樣一個問題在mysql中建表的時候,我設定一個欄位為int型別,長度為1,但是我發現這個欄位卻可以儲存任意長度的數字,這是什麼情況?這個問題在我剛接觸資料庫的時候也遇到過,我覺得有必要寫一篇文章來解釋一下。
0
和 1
是計算機最基本的儲存單位。也是 CPU
採用的最基本的計算單位,也就是二進位制。int
型別佔 4
個位元組,一個位元組是 8
位,也就是說 int
型別在計算機底層是由 32
個 0
跟 1
表示,轉化為十進位制就是 2
的 32
次方,那麼儲存範圍就是 0
~2^32
,如果帶符號位的話就是 -2^31
~ 2^31-1
。
在使用SQLyog
工具建表時,除了常見的幾個屬性Field Name
DataType
,Len
,Default
,PK?
,Not Null?
,Auto Incr?
,Comment
之外,還有兩個不常用的Unsigned?
和Zerofill?
,這兩個屬性到底有什麼用呢?
Unsigned:無符號的
,意思就是隻能為正數,不能為負數。
Zerofill:零填充
,意思就是達不到指定長度後,前面用 0
來填充。
現在再來看看這個int(1)
中的1
究竟有什麼奧祕。這個1
跟這個欄位能存的資料範圍沒關係,它也不是限制這個欄位的資料長度的。這個欄位儲存的資料範圍是由int
來限制的。
這個1
只是規定了資料的寬度,如果你選擇了Zerofill
屬性,就能更好地理解這個1
了,如果我們寫入的資料達不到這個長度,那麼就會在資料前面補0
int(1)
改成int(3)
,我們再輸入1,實際上顯示的是001
。所以不管你將 int
型別的長度設為多少並不會影響資料的儲存範圍。
mysql
對於整型的資料型別,不僅給我們提供了int
,還提供了tinyint
,smallint
,mediumint
和bigint
。這些型別儲存的資料範圍都是不一樣的,具體如下表:
型別 | 位元組 | 最小值 | 最大值 |
---|---|---|---|
(帶符號的/無符號的) | (帶符號的/無符號的) | ||
TINYINT | 1 | -128 | 127 |
0 | 255 | ||
SMALLINT | 2 | -32768 | 32767 |
0 | 65535 | ||
MEDIUMINT | 3 | -8388608 | 8388607 |
0 | 16777215 | ||
INT | 4 | -2147483648 | 2147483647 |
0 | 4294967295 | ||
BIGINT | 8 | -9223372036854775808 | 9223372036854775807 |
0 | 18446744073709551615 |
看到這兒,應該已經清楚int(1)的真正含義了。根據實際需求選擇合適的資料型別來儲存就可以了。
再來聊一聊一個常見的面試題:int型別做自增主鍵有沒有可能儲存完?肯定是有的,都有資料範圍了,主鍵一直增長肯定有可能會達到這個範圍。很多小夥伴是不是心中飄過一萬匹草泥馬,忙著修改資料庫去了。這其實大可不必擔心,這個數字大概是42億。如果資料量夠夠夠夠大,你選擇bigint
做為自增主鍵肯定沒啥問題。這個數字我已經讀不出來了,交給評論區的你們來讀!