MySQL中int(M)和tinyint(M)數值類型中M值的意義

在一開始接觸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)之類的,基本沒用。而且導致表的字段類型多樣化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章