在一開始接觸MySQL數據庫時,對於int(M)及tinyint(M)兩者數值類型后面的M值理解是最多能夠插入數據庫中的值不能大於M;
后來工作后,也是一邊學習一邊使用,之后的理解是其中的M的意思是插入數據庫中的值的字符長度不能大於M,例如,int(4),想要插入1234,1234的字符長度是4,就正好可以插入數據庫,12341就不行,因為是5個字符長度,這也都是道聽途說,自己從來沒有驗證過;
如今,由於面試中經常會被問到有關數據庫方面的知識,今天也想着深入了解下這個M代表的含義(上述兩個理解都是錯誤的)。
首先,我們創建一個數據表test:
mysql> CREATE TABLE test( -> id1 int(1), -> id2 tinyint(1) ->);
我們給id1定義為int,並設置字符長度為1,id2定義為tinyint,也設置字符長度為1;
然后分別插入值127,127,結果發現,兩者都插入到了數據表中:
mysql> INSERT INTO test(id1,id2) values(127,127);//運行成功
結果是插入成功的,從此次測試已經可以知道,我之前的想法都是錯誤的,接下來我們再做一個實驗,插入數據128,128,即id=128,id2=128:
mysql> INSERT INTO test(id1,id2) values(128,128);//運行失敗:ERROR 1264 (22003):Out of range value for column 'id2' at row 1
出錯了,int類型的id1插入成功了,tinyint類型的id2提示超出了范圍,這是為什么呢?
首先,我們先要了解一個基礎知識點,就是下面這張表:(摘自W3C教程)
上述表格中的數值類型都是定長的,也就是說,無論你存的數值是多少,多大或者多小,占用的字節大小都是固定的。例如,之前設置的int(1),雖然M值是1個字符,但是它所占用的空間大小永遠都是4個字節的大小,換句話說就是,你可以存入有符號整型從-2 147 483 648到2 147 483 647包括這兩個數的中間任何一個數。int(1)和int(11)占用的是4個字節,可以存入上述這些數,tinyint(1)和tinyint(4)占用的是1個字節,可以存入從-128到127的數,這也是為什么之前的一次試驗,int(1)插入128成功,而tinyint(1)插入128卻提示超出長度。
那么,這個M值到底代表什么意思呢?
到這里,我們已經可以發現,M值即使設置為1,它也可以存入字符長度大於1的值,那么,如果存入的字符長度小於1會怎么樣?我們來試一試:
先將id1的類型更改為int(2),然后插入數據id1=1:
mysql> ALTER TABLE test Modify id1 int(2); mysql> INSERT INTO test(id1) values(1);//運行成功,說明值1已經插入到test表中
我們查詢一下表中的數據,看看結果具體如何:
mysql> SELECT * FROM test; +------+ | id1 | +------+ | 1 | +------+
接下來,我們再修改一下id1的填充數據類型zerofill(表示用0填充),這里先知道如何操作即可,我們再從結果得出結論:
mysql> ALTER TABLE test MODIFY id1 int(2) zerofill; mysql> SELECT * FROM test;
+------+ | id1 | +------+ | 01 | +------+
現在是不是有些清楚了。我們設置的M值是2,沒有設置zerofill用0填充時,對於操作沒有任何影響,而設置了zerofill后,我們可以清楚地看到值1字符數不足M值,左前位置補0。我們也可以將M值設置成別的大小進行多次測試,這里就不進行測試了。
需要強調的是,不同的數據類型中的M值意義是不一樣的,我們這里僅討論整型中的M值。
從上面我們可以得到如下的結論:
1、整數型的數值類型已經限制了取值范圍,有符號整型和無符號整型都有,而M值並不代表可以存儲的數值字符長度,它代表的是數據在顯示時顯示的最小長度;
2、當存儲的字符長度超過M值時,沒有任何的影響,只要不超過數值類型限制的范圍;
3、當存儲的字符長度小於M值時,只有在設置了zerofill用0來填充,才能夠看到效果,換句話就是說,沒有zerofill,M值就是無用的。
總結:int(11),tinyint(1),bigint(20),后面的數字,不代表占用空間容量。而代表最小顯示位數。這個東西基本沒有意義,除非你對字段指定zerofill。
所以我們在設計mysql數據庫時,建表時,mysql會自動分配長度:int(11)、tinyint(4)、smallint(6)、mediumint(9)、bigint(20)。
所以,就用這些默認的顯示長度就可以了。不用再去自己填長度,比如搞個int(10)、tinyint(1)之類的,基本沒用。而且導致表的字段類型多樣化。
參考博客:http://www.cnblogs.com/stringzero/p/5707467.html