日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql里面integer默认宽度_MySQL中关于数据类型指定宽度之后的情况

發布時間:2025/3/12 数据库 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql里面integer默认宽度_MySQL中关于数据类型指定宽度之后的情况 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

MySQL有很多種數據類型,最常用的就是int,char,varchar,這些類型在創建表的時候都可以指定該字段的寬度,方法是在類型后面加一個括號,括號中寫寬度就可以了。

但是,在指定寬度之后,有時候,我們可以看到插入的數據有一些被截斷了;有一些并沒有截斷,而是四舍五入了,甚至什么操作都沒有,原樣插入了。

下面對于每一種數據類型單獨測試:

數字型(int、tinyint...)

mysql> create table t (id int(5));

mysql> insert into t values(1234567),(123),(12345);

mysql> select * from t;

+---------+

| id |

+---------+

| 1234567 |

| 123 |

| 12345 |

+---------+

從上面的例子中可以看到,對于int而言,雖然指定了寬度,但是當插入的數據寬度大于指定的寬度時,并不會截斷。

其實對于int而言,要指定寬度,那么就必定要指定zerofill,但同樣,zerofill只是在寬度不夠的時候用0填充,但是寬度大于指定寬度時,數據仍然不會被截取。

mysql> create table t (id int(5) zerofill);

mysql> insert into t values(1234567),(123),(12345);

mysql> select * from t;

+---------+

| id |

+---------+

| 1234567 |

| 00123 |

| 12345 |

+---------+

字符串型(char、varchar)

mysql> create table t (fields_1 char(5),fields_2 varchar(5));

Query OK, 0 rows affected (0.01 sec)

mysql> insert into t values("123","123"),("12345","12345"),("1234567","1234567");

Query OK, 3 rows affected, 2 warnings (0.00 sec)

Records: 3 Duplicates: 0 Warnings: 2

mysql> show Warnings;

+---------+------+-----------------------------------------------+

| Level | Code | Message |

+---------+------+-----------------------------------------------+

| Warning | 1265 | Data truncated for column 'fields_1' at row 3 |

| Warning | 1265 | Data truncated for column 'fields_2' at row 3 |

+---------+------+-----------------------------------------------+

2 rows in set (0.00 sec)

mysql> select fields_1,length(fields_1),fields_2,length(fields_2) from t;

+----------+------------------+----------+------------------+

| fields_1 | length(fields_1) | fields_2 | length(fields_2) |

+----------+------------------+----------+------------------+

| 123 | 3 | 123 | 3 |

| 12345 | 5 | 12345 | 5 |

| 12345 | 5 | 12345 | 5 |

+----------+------------------+----------+------------------+

可以看到,對于char和varchar,如果制定了寬度,如果要插入的字符串的寬度超過了指定的寬度,則會截取掉超出的部分。

簡單來說,varchar的可變長度,這個可變,前提是存入的字符串長度不超過定義該字段時指定的長度,如果長度超過了指定長度,即使是可變長度字符串類型,數據仍會出現截斷。

可以簡單記為:可縮不可擴。

而固定長度的char類型,在存儲效率比varchar高,但是,會存在空間浪費的情況,所以空間利用率沒有varchar高,而varchar是可變長度的,就意味著,在讀數據的時候,效率沒有char類型高,因為在讀數據的時候要判斷是否讀到結尾。

拓展1

前面已經提到,對于數值類型的字段后面的寬度來說,只有在指定zerofill的時候,后面指定的寬度才有意義,否則,既不會出現截斷,也不會出現0填充。那么,不會出現截斷,是不是說,向一個int(5)字段的插入一個值,這個值是12345678912345678912345678...(由100位數字長度),那么還能存進去嗎?

看下面示例:

mysql> create table t (id int(5) zerofill);

Query OK, 0 rows affected (0.10 sec)

mysql> insert into t values (9999999999999999999999999999999999999999999);

Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql> show warnings;

+---------+------+---------------------------------------------+

| Level | Code | Message |

+---------+------+---------------------------------------------+

| Warning | 1264 | Out of range value for column 'id' at row 1 |

| Warning | 1264 | Out of range value for column 'id' at row 1 |

+---------+------+---------------------------------------------+

2 rows in set (0.00 sec)

mysql> select * from t;

+------------+

| id |

+------------+

| 4294967295 |

+------------+

1 row in set (0.00 sec)

可以從警告信息和執行結果中看出,當嘗試向指定寬度字段插入一個很大的數據,大到遠超該數據類型的上限,執行雖然會出現警告,但是,數據確實插入了,只不過存儲的數據不是插入的數據,而是存了一個該類型的最大值。

所以可以得出結論:對一個數字類型的字段而言,其數據類型已經限定了它的數據范圍,當嘗試插入一個超過數據范圍的值時,會觸發警告,同時,存入該數據類型的最大值。

拓展2

前面也提到了字符串(char和varchar)后面指定的寬度,這個寬度就不像數字類型的寬度了,因為,如果是字符串類型,那么,一旦超過字符串后面指定的寬度,那么一定會出現截斷。

這里有個問題,字符串后面指定的寬度,比如char(5),varchar(5),這個5是指5個字符,還是指5個字節呢,或者說是5個bit(位)呢?

前面的示例中,很顯然看出,這個5不可能是bit(位),畢竟一個字節就有8位,在測試中,一個字符都插不進去。

那么,要么是5個字符,或者5個字節。可能你會疑惑,5個字符和5個字節有什么區別嗎?abc,是3個字符,同時也是3個字節,何必去區分呢?

那你想一下,咱們的漢字,一個漢字,經過不同的編碼(GBK,GB2312,lantin1,UTF-8,UTF-8mb4)之后,所占的字節數是不一定相同的呀。

mysql> create table t (field char(5));

Query OK, 0 rows affected (0.40 sec)

mysql> show create table t\G

*************************** 1. row ***************************

Table: t

Create Table: CREATE TABLE `t` (

`field` char(5) DEFAULT NULL

) ENGINE=MyISAM DEFAULT CHARSET=latin1

1 row in set (0.00 sec)

mysql> insert into t values ('abcde');

Query OK, 1 row affected (0.00 sec)

mysql> insert into t values ('中國你好啊');

Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql> show warnings;

+---------+------+-----------------------------------------------------------------------------------+

| Level | Code | Message |

+---------+------+-----------------------------------------------------------------------------------+

| Warning | 1300 | Invalid utf8 character string: 'D6D0B9' |

| Warning | 1366 | Incorrect string value: '\xD6\xD0\xB9\xFA\xC4\xE3...' for column 'field' at row 1 |

+---------+------+-----------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

從上面的實例,很明顯可以看出答案,char(5)后面的5,是指的5字節,而不是5個字符。

可以查看一下,存入的內容是什么:

mysql> select * from t;

+-------+

| field |

+-------+

| abcde |

| ????? |

+-------+

2 rows in set (0.03 sec)

mysql> set names utf8;

Query OK, 0 rows affected (0.02 sec)

mysql> select * from t;

+-------+

| field |

+-------+

| abcde |

| ????? |

+-------+

2 rows in set (0.00 sec)

可以看出,后面雖然插入的“中國你好啊”,但是存的時候,已經出現亂碼了,即使強制指定字符集,也是顯示亂碼。

咱們一般使用的都會utf8或者utf8mb4,可以在創建表格的時候,指定default charset=utf8。

拓展3

如果一個漢字使用某種編碼方式(比如utf8),在存儲的時候占3字節,那么兩個漢字,就需要6個字節來存。

那么,如果char(5)類型的字段,能存入“中國”兩個字嗎?中國兩個字編碼之后是6字節。

首先解決一個問題:

mysql> create table t ( field char(5)) default charset=utf8;

Query OK, 0 rows affected (0.11 sec)

mysql> insert into t values ('abcde');

Query OK, 1 row affected (0.00 sec)

mysql> insert into t values ('中');

Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql> show warnings;

+---------+------+----------------------------------------------------------------+

| Level | Code | Message |

+---------+------+----------------------------------------------------------------+

| Warning | 1300 | Invalid utf8 character string: 'D6D0' |

| Warning | 1366 | Incorrect string value: '\xD6\xD0' for column 'field' at row 1 |

+---------+------+----------------------------------------------------------------+

2 rows in set (0.00 sec)

mysql> select * from t;

+-------+

| field |

+-------+

| abcde |

| |

+-------+

2 rows in set (0.00 sec)

mysql> set names utf8;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t;

+-------+

| field |

+-------+

| abcde |

| |

+-------+

2 rows in set (0.00 sec)

可以看到,即使單個漢字“中”編碼之后3字節(未超過5字節范圍,仍舊未存入),這時可以看一下數據庫的字符集:

mysql> show variables like '%char%';

+--------------------------+-----------------------------------+

| Variable_name | Value |

+--------------------------+-----------------------------------+

| character_set_client | utf8 |

| character_set_connection | utf8 |

| character_set_database | latin1 |

| character_set_filesystem | binary |

| character_set_results | utf8 |

| character_set_server | utf8 |

| character_set_system | utf8 |

| character_sets_dir | E:\phpStudy\MySQL\share\charsets\ |

+--------------------------+-----------------------------------+

8 rows in set (0.00 sec)

可以看到,character_set_database設定的還是latin1字符集編碼,可以使用下面的命令修改:

set character_set_database='utf8';

接下來,測試過程中,即使插入單獨的一個漢字,也會出現警告,并且查看插入的值,只出現一個?或者一些亂碼,甚至沒有值(空的)。

我嘗試在php中執行插入和查看操作:

$mysqli = new Mysqli();

$mysqli->connect("localhost","root","root","test");

$mysqli->set_charset("utf8");

$mysqli->query("truncate table t");

$mysqli->query("insert into t values ('abcde')");

$mysqli->query("insert into t values ('你')");

$mysqli->query("insert into t values ('你好')");

$sql = "select * from t";

$mysqli_result = $mysqli->query($sql);

$res = $mysqli_result->fetch_all();//一次性去的所有數據

print_r($res);

執行之后,結果如下:

λ php index.php

Array

(

[0] => Array

(

[0] => abcde

)

[1] => Array

(

[0] => ?

)

[2] => Array

(

[0] => ???

)

)

至于為什么會這樣,現在還沒找到問題根源。之前好像也沒遇到過這種情況呀,等有時間在其他機器上試一下。

總結

以上是生活随笔為你收集整理的mysql里面integer默认宽度_MySQL中关于数据类型指定宽度之后的情况的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。