1. 程式人生 > >MySQL中的資料型別之數字型別

MySQL中的資料型別之數字型別

MySQL中的資料型別主要有:數字型別、日期/時間型別、字串型別。

數字型別

下面的M在不同的資料型別後面的含義是不同的!!!在表示int(或integer)型別時表示的是顯示寬度(display width),最大顯示寬度是255。顯示寬度和數字型別的取值範圍是無關的。例如,int(11)表示的是顯示寬度是11,int(10)表示的是顯示寬度是10,它們都是整型,整型佔用的空間是固定的4個位元組
下面的方括號[]表示其中的內容可選,即定義欄位的時候可以加上,也可以不加。

  • bit[( M)]
    位元型別,M表示每個數字佔用的位元數,M可以從1到64,不指定時預設1。
mysql> create table t_bit(
id_1 bit,id_2 bit(2),id_3 bit(3)); Query OK, 0 rows affected (0.02 sec) #4超出了2bit表示範圍,報錯 mysql> insert into t_bit(id_1,id_2,id_3)values(1,4,7); ERROR 1406 (22001): Data too long for column 'id_2' at row 1 mysql> insert into t_bit(id_1,id_2,id_3)values(1,3,7); Query OK, 1 row affected (0.00 sec) #8超出了3bit表示範圍,報錯
mysql> insert into t_bit(id_1,id_2,id_3)values(1,3,8); ERROR 1406 (22001): Data too long for column 'id_3' at row 1

從上面的可以看到id_2是2位元空間,能表示0~3,id_3是3位元空間,能表示0~7,如果超出儲存範圍會報錯。

  • tinyint[(M)] [unsigned] [zerofill]
    表示很小的整數,佔用1個位元組儲存空間,有符號的取值範圍是-128~127,無符號表示的範圍是0~255,預設欄位是有符號型別,即signedM表示的是顯示寬度,不指定的時候預設為4,貌似顯示寬度只有在有0填充的時候有用。
mysql> create table t_tinyint(id_1 tinyint,id_2 tinyint(2),id_3 tinyint(2) zerofill,id_4 tinyint(10));
Query OK, 0 rows affected (0.01 sec)
#查看了一下表的描述,可以發現定義欄位時指定了zerofill,欄位就變成了unsigned型別了。
mysql> desc t_tinyint;
+-------+------------------------------+------+-----+---------+-------+
| Field | Type                         | Null | Key | Default | Extra |
+-------+------------------------------+------+-----+---------+-------+
| id_1  | tinyint(4)                   | YES  |     | NULL    |       |
| id_2  | tinyint(2)                   | YES  |     | NULL    |       |
| id_3  | tinyint(2) unsigned zerofill | YES  |     | NULL    |       |
| id_4  | tinyint(10)                  | YES  |     | NULL    |       |
+-------+------------------------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

#因為定義id_4的時候沒有指名是否有符號,預設有符號,250超出了有符號表示的上限128,所以報錯了。
mysql> insert into t_tinyint(id_1,id_2,id_3,id_4)
    -> values(2,3,1,250);
ERROR 1264 (22003): Out of range value for column 'id_4' at row 1

mysql> insert into t_tinyint(id_1,id_2,id_3,id_4) values(2,3,1,127);
Query OK, 1 row affected (0.00 sec)

#查詢的結果可以看到定義id_3的時候指定了填充0,而顯示寬度是2,所以左邊的1位被填了0,儘管定義id_4的時候指定了顯示寬度是10,
mysql> select * from t_tinyint;
+------+------+------+------+
| id_1 | id_2 | id_3 | id_4 |
+------+------+------+------+
|    2 |    3 |   01 |  127 |
+------+------+------+------+
1 row in set (0.00 sec)

#把id_4欄位改成顯示寬度為9,zerofill
mysql> alter table t_tinyint change id_4 id_4 int(9) zerofill;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

#此時再查詢表,發現id_4欄位寬度被0填充到9位了。
mysql> select * from t_tinyint;
+------+------+------+-----------+
| id_1 | id_2 | id_3 | id_4      |
+------+------+------+-----------+
|    2 |    3 |   01 | 000000127 |
+------+------+------+-----------+
1 row in set (0.00 sec)

mysql> insert into t_tinyint(id_2,id_3)values(120,121);
Query OK, 1 row affected (0.00 sec)

#注意,當數字大小超出了顯示寬度時會顯示完整的數字,不再受顯示寬度束縛,例如下面的id_2,id_3欄位在定義時的顯示寬度都指定為2位寬度,但是插入的資料已經有3位寬度了,顯示的時候並沒有受顯示寬度束縛。
mysql> select * from t_tinyint;
+------+------+------+-----------+
| id_1 | id_2 | id_3 | id_4      |
+------+------+------+-----------+
|    2 |    3 |   01 | 000000127 |
| NULL |  120 |  121 |      NULL |
+------+------+------+-----------+
2 rows in set (0.00 sec)
  • bool,boolean
    這些型別是tinyint(1)的同義詞。0值被認為是false,非0值被認為是true。

如下內容可以看到0是false,非0的都是true:

mysql> select if(0,'true','false');
+----------------------+
| if(0,'true','false') |
+----------------------+
| false                |
+----------------------+
1 row in set (0.00 sec)

mysql> select if(1,'true','false');
+----------------------+
| if(1,'true','false') |
+----------------------+
| true                 |
+----------------------+
1 row in set (0.00 sec)

mysql> select if(2,'true','false');
+----------------------+
| if(2,'true','false') |
+----------------------+
| true                 |
+----------------------+
1 row in set (0.00 sec)

然而,反過來就不一樣了。true僅表示1,false僅表示0

mysql> select if(0=false,'true','false');
+----------------------------+
| if(0=false,'true','false') |
+----------------------------+
| true                       |
+----------------------------+
1 row in set (0.01 sec)

mysql> select if(1=true,'true','false');
+---------------------------+
| if(1=true,'true','false') |
+---------------------------+
| true                      |
+---------------------------+
1 row in set (0.01 sec)

mysql> select if(2=true,'true','false');
+---------------------------+
| if(2=true,'true','false') |
+---------------------------+
| false                     |
+---------------------------+
1 row in set (0.00 sec)

讓我們來看如下內容:

mysql> create table t_bool(b1 bool,b2 boolean);
Query OK, 0 rows affected (0.02 sec)
#可以看到定義欄位的時候bool,boolean都是tinyint(1)的別名。
mysql> desc t_bool;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| b1    | tinyint(1) | YES  |     | NULL    |       |
| b2    | tinyint(1) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

#既然是tinyint(1)就可以插入-128~127範圍內的整數
mysql> insert into t_bool values(0,1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_bool;
+------+------+
| b1   | b2   |
+------+------+
|    0 |    1 |
+------+------+
1 row in set (0.00 sec)

mysql> insert into t_bool values(1,2);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_bool;
+------+------+
| b1   | b2   |
+------+------+
|    0 |    1 |
|    1 |    2 |
+------+------+
2 rows in set (0.00 sec)

#插入的時候true被轉為數字1,false被轉為數字0。
mysql> insert into t_bool values(true,false);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_bool;
+------+------+
| b1   | b2   |
+------+------+
|    0 |    1 |
|    1 |    2 |
|    1 |    0 |
+------+------+
3 rows in set (0.00 sec)

mysql> insert into t_bool values(-1,120);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_bool;
+------+------+
| b1   | b2   |
+------+------+
|    0 |    1 |
|    1 |    2 |
|    1 |    0 |
|   -1 |  120 |
+------+------+
4 rows in set (0.00 sec)
  • smallint[(M)] [unsigned] [zerofill]
    M含義和tinyint一樣,都是表示顯示寬度,不同的是smallint儲存的時候佔用2個位元組,有符號表示範圍為-32768~32767,無符號表示範圍為0~65535。

  • mediumint[(M)] [unsigned] [zerofill]
    M含義和tinyint一樣,都是表示顯示寬度,不同的是mediumint儲存的時候佔用3個位元組,有符號表示範圍為-8388608~8388607,無符號表示範圍為0~16777215。

  • int[(M)] [unsigned] [zerofill]
    M含義和tinyint一樣,都是表示顯示寬度,不同的是int儲存的時候佔用4個位元組,有符號表示範圍為-2147483648~2147483647,無符號表示範圍為0~4294967295。

  • integer[(M)] [unsigned] [zerofill]
    是int的別名,含義一樣。

  • bigint[(M)] [unsigned] [zerofill]
    很大的整數,有符號範圍為 -9223372036854775808~9223372036854775807。無符號範圍為0~18446744073709551615。
    serial是bigint unsigned not null auto_increment unique的別名:

mysql> create table t_serial(id serial);
Query OK, 0 rows affected (0.01 sec)

mysql> desc t_serial;
+-------+---------------------+------+-----+---------+----------------+
| Field | Type                | Null | Key | Default | Extra          |
+-------+---------------------+------+-----+---------+----------------+
| id    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
+-------+---------------------+------+-----+---------+----------------+
1 row in set (0.00 sec)
  • decimal[(M[,D])] [unsigned] [zerofill]
    壓縮的嚴格定點數。M表示總共的位數,也就是精度,D是小數點後的位數,也叫做標度。對於負數中的負號-不算在M內。如果D為0,則沒有小數部分。decimal最大的位數(M)為65,如果省略M的值,則預設為10;最大的D是30,如果省略D的值,則預設為0。decimal型別佔用的空間是M+2個位元組。在MySQL中,定點數以字串的形式儲存,在對精度要求比較高的時候(比如金融相關的)推薦使用decimal。
#可以看出decimal的最大精度超過65就報錯了
mysql> create table t_decimal(d1 decimal(65,30),d2 decimal,d3 decimal(70));
ERROR 1426 (42000): Too-big precision 70 specified for 'd3'. Maximum is 65.
mysql> create table t_decimal(d1 decimal(65,30),d2 decimal,d3 decimal(10));
Query OK, 0 rows affected (0.02 sec)

mysql> desc t_decimal;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| d1    | decimal(65,30) | YES  |     | NULL    |       |
| d2    | decimal(10,0)  | YES  |     | NULL    |       |
| d3    | decimal(10,0)  | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> alter table t_decimal change d3 d3 decimal(5,2);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc t_decimal;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| d1    | decimal(65,30) | YES  |     | NULL    |       |
| d2    | decimal(10,0)  | YES  |     | NULL    |       |
| d3    | decimal(5,2)   | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

#d3的位數超出了5位,報錯了
mysql> insert into t_decimal(d1,d2,d3)values(222222222222222.44444444,3432.34,2223.45);
ERROR 1264 (22003): Out of range value for column 'd3' at row 1
mysql> mysql> insert into t_decimal(d1,d2,d3)values(222222222222222.44444444,3432.34,233.45);
Query OK, 1 row affected, 1 warning (0.01 sec)

#可以看到d1的小數部分精度不足的被0填充
mysql> select * from t_decimal;
+------------------------------------------------+------+--------+
| d1                                             | d2   | d3     |
+------------------------------------------------+------+--------+
| 222222222222222.444444440000000000000000000000 | 3432 | 223.45 |
+------------------------------------------------+------+--------+
1 row in set (0.00 sec)

mysql> insert into t_decimal(d1,d2,d3)values(222222222222222.44444444,3432.34,23.454);
Query OK, 1 row affected, 2 warnings (0.01 sec)

#上面插入的d3值的小數部分被截掉了,因為d3定義的時候小數部分是2位
mysql> select * from t_decimal;
+------------------------------------------------+------+--------+
| d1                                             | d2   | d3     |
+------------------------------------------------+------+--------+
| 222222222222222.444444440000000000000000000000 | 3432 | 223.45 |
| 222222222222222.444444440000000000000000000000 | 3432 |  23.45 |
+------------------------------------------------+------+--------+
2 rows in set (0.00 sec)
  • dec [(M[,D])] [unsigned] [zerofill], numeric[(M[,D])] [unsigned] [zerofill], fixed[(M[,D])] [usigned] [zerofill]
    上面這幾種都是decimal的同義詞,其中fixed(有定點的意思)和其他資料庫系統的命名相容。

  • float [(M,D)] [unsigned] [zerofill]
    小一點的(單精度)浮點數,佔用4個位元組。可以取值的範圍是-3.402823466E+38~-1.175494351E-38, 0, 和1.175494351E-38~3.402823466E+38,如果定義unsigned,就不能取負值。這是基於IEEE標準的理論上的限制,真實的範圍會小一些,並且取決與硬體和作業系統。
    M是總共的位數,D是小數點後的位數。如果MD被省略了,將按照硬體允許的範圍儲存。單精度浮點數可以精確到大約7位小數。
    使用float可能會有意想不到的問題,因為MySQL中所有的計算都是基於雙精度的。

  • double [(M,D)] [unsigned] [zerofill]
    正常大小的(雙精度)浮點數。可以取值的範圍是-1.7976931348623157E+308~-2.2250738585072014E-308, 0, 和2.2250738585072014E-308~1.7976931348623157E+308,如果定義unsigned,就不能取負值。同樣是理論值,真實範圍會小一些,並且取決於硬體和作業系統。
    MD的含義同float,雙精度浮點數可以精確到大約15位小數。