聊聊Mysql中的int(1)
昨天有個讀者問了我這樣一個問題在mysql中建表的時候,我設置一個字段為int類型,長度為1,但是我發(fā)現(xiàn)這個字段卻可以存儲任意長度的數(shù)字,這是什么情況?這個問題在我剛接觸數(shù)據(jù)庫的時候也遇到過,我覺得有必要寫一篇文章來解釋一下。
0?和?1?是計算機最基本的存儲單位。也是?CPU?采用的最基本的計算單位,也就是二進制。int?類型占?4?個字節(jié),一個字節(jié)是?8?位,也就是說?int?類型在計算機底層是由?32?個?0?跟?1?表示,轉(zhuǎn)化為十進制就是?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:無符號的,意思就是只能為正數(shù),不能為負數(shù)。
Zerofill:零填充,意思就是達不到指定長度后,前面用?0?來填充。
現(xiàn)在再來看看這個int(1)中的1究竟有什么奧秘。這個1跟這個字段能存的數(shù)據(jù)范圍沒關系,它也不是限制這個字段的數(shù)據(jù)長度的。這個字段存儲的數(shù)據(jù)范圍是由int來限制的。
這個1只是規(guī)定了數(shù)據(jù)的寬度,如果你選擇了Zerofill屬性,就能更好地理解這個1了,如果我們寫入的數(shù)據(jù)達不到這個長度,那么就會在數(shù)據(jù)前面補0來達到這個長度。比如我們將int(1)改成int(3),我們再輸入1,實際上顯示的是001。所以無論你將?int?類型的長度設為多少并不會影響數(shù)據(jù)的存儲范圍。
mysql對于整型的數(shù)據(jù)類型,不僅給我們提供了int,還提供了tinyint,smallint,mediumint和bigint。這些類型存儲的數(shù)據(jù)范圍都是不一樣的,具體如下表:
| 類型 | 字節(jié) | 最小值 | 最大值 |
|---|---|---|---|
| (帶符號的/無符號的) | (帶符號的/無符號的) | ||
| 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 |
看到這兒,應該已經(jīng)清楚int(1)的真正含義了。根據(jù)實際需求選擇合適的數(shù)據(jù)類型來存儲就可以了。
再來聊一聊一個常見的面試題:int類型做自增主鍵有沒有可能存儲完?
肯定是有的,都有數(shù)據(jù)范圍了,主鍵一直增長肯定有可能會達到這個范圍。
很多小伙伴是不是心中飄過一萬匹草泥馬,忙著修改數(shù)據(jù)庫去了。這其實大可不必擔心,這個數(shù)字大概是42億。如果數(shù)據(jù)量夠夠夠夠大,你選擇bigint做為自增主鍵肯定沒啥問題。這個數(shù)字我已經(jīng)讀不出來了,交給評論區(qū)的你們來讀!
