MySQL 支持的数据类型

1、数值类型

  • MySQL 支持所有标准 SQL 中的数值类型,其中包括严格数值类型(integer、smallint、decimal、numeric),以及近似数值数据类型(float、real、double precision),并在此基础上做了扩展,扩展后增加了 tinyint、mediumint 和 bigint 这 3 种长度不同的整型,并增加了 bit 类型,用来存放位数据。

1.1 整数类型

  • 1)分类

    • 按照取值范围和存储方式不同,分为 tinyint、smallint、mediumint、int(即 integer)和 bigint 这 5 个类型,分别为 1、2、3、4、8 字节,如果超出类型范围的操作会发生 "Out of range" 错误提示。

      整数类型 字节 最小值(有符号 无符号) 最大值(有符号 无符号) 描述
      tinyint 1 -128,0 127,255 tinyint[(m)] [unsigned] [zerofill]
      smallint 2 -32768,0 32767,65535 smallint[(m)] [unsigned] [zerofill]
      mediumint 3 -8388608,0 8388607,1677215 mediumint[(m)] [unsigned] [zerofill]
      int、integer 4 -2147483648, 0 2147483647,4294967295 int[(m)] [unsigned] [zerofill]
      bigint 8 -9223372036854775808,0 9223372036854775807,18446744073709551615 bigint[(m)] [unsigned] [zerofill]
  • 2)指定显示宽度

    • 对于整型数据,MySQL 还支持在类型名称后加 "(m)" 的方式来指定显示宽度,"(m)" 表示该值一共显示 m 位数字,m 又称为精度,如果不显示指定宽度则默认为 int(11)。

      • 一般配合 zerofill 使用,即在数字位数不够的空间用字符 "0" 填满。

      • 在设置了宽度限制后,如果插入值大于限制宽度,这时,宽度格式已经没有意义,还是按照类型的实际精度(如:int 无符号的数值范围为0-255)进行保存,左边不会再填充任何的 "0" 字符。

  • 3)属性

    • unsigned(无符号)

      • 可选属性需要在字段里面保存非负数或者需要较大的上限值时使用。
      • 如果一个列指定为 zerofill,则 MySQL 自动为该列添加 unsigned 属性。
    • auto_increment

      • 在需要产生唯一标识符或顺序值时使用,即 not null、主键 primary key 或者 unique 键的整数类型。
      • auto_increment 值初始值为 1,增加幅度为 1。
      • 一个表中最多只能有一个 auto_increment 列。

1.2 小数类型

  • 1)分类

    • 分为浮点数和定点数。浮点数包括 float(单精度)和 double(双精度),定点数为 decimal。

      扫描二维码关注公众号,回复: 1645790 查看本文章
    • 定点数 decimal 在 MySQL 内以字符串形式存放,比浮点数更精确,适合用来表示货币等精度高的数据。

      浮点数类型 字节 最小值(有符号 无符号) 最大值(有符号 无符号) 描述
      float 4 ± 1.175494351E-38 ± 3.402823466E+38 float[(m, d)] [unsigned] [zerofill]
      double 8 ± 2.2250738585072014E-308 ± 1.7976931348623157E+308 double[(m, d)] [unsigned] [zerofill]
      定点数类型 字节 最小值(有符号 无符号) 最大值(有符号 无符号) 描述
      dec(m, d)、decimal(m, d) m + 2 最大取值范围与 double 相同,给定 dec 的有效值范围由 m 和 d 决定 dec[(m, d)] [unsigned] [zerofill]
  • 2)指定显示宽度

    • 浮点数和定点数都可以用类型名称后加 "(m, d)" 的方式来进行表示,"(m, d)" 表示该值一共显示 m 位数字(整数位+小数位),其中 d 位位于小数点后面,m 和 d 又称为精度和标度。

      • 浮点数如果不写精度和标度,则会按照实际精度值显示,如果有精度和标度,则会自动将四舍五入后的结果插入,系统不会报错。

      • 定点数如果不写精度和标度,则按照默认值 decimal(10, 0) 来进行操作,并且如果数据超越了精度和标度值,系统则会报错。

1.3 位类型

  • 1)用途

    • bit(m)位类型用于存放位字段值,

    • bit(m) 可以用来存放多位二进制数,M范围从 1~64,如果不写则默认为 1 位。

  • 2)查看位类型字段

    • 对于位字段,直接使用 select 命令将不会看到结果,可以使用 bin(列名)(显示为二进制格式)或者 hex(列名)(显示为十六进制格式)函数进行读取。

      # 查看位类型字段值
      > select bin(id), hex(id) from t2;
      
          +---------+---------+
          | bin(id) | hex(id) |
          +---------+---------+
          | 1       | 1       |
          +---------+---------+
          1 rows in set (0.00 sec)
  • 3)位类型字段插入操作

    • 数据插入 bit 类型字段时,首先转换为二进制,如果位数允许,将成功插入;如果位数小于实际定义的位数,则插入失败。

      # 插入位类型字段值
      > insert into t2 values(2);
      
          Query OK, 1 row affected (0.00 sec)
      
      > select bin(id), hex(id) from t2;
      
          +---------+---------+
          | bin(id) | hex(id) |
          +---------+---------+
          | 1       | 1       |
          | 10      | 2       |
          +---------+---------+
          2 rows in set (0.00 sec)

2、日期时间类型

  • MySQL 中有多种数据类型可以用于日期和时间的表示,不同的版本可能有所差异。

1.1 日期时间类型

  • 1)分类

    • 每种日期时间类型都有一个有效值范围,如果超出这个范围,在默认的SQLMode下,系统会进行错误提示,并将以零值来进行存储。

      日期时间类型 字节 最小值 最大值 格式 描述
      date 4 1000-01-01 9999-12-31 YYYY-MM-DD date
      time 3 -838:59:59.000000 838:59:59.000000 HH:MM:SS[.fraction] time[(fsp)]
      datetime 8 1000-01-01 00:00:00.000000 9999-12-31 23:59:59.999999 YYYY-MM-DD HH:MM:SS[.fraction] datetime[(fsp)]
      timestamp 4 1970-01-01 00:00:01.000000 UTC 2038-01-19 03:14:07.999999 UTC YYYY-MM-DD HH:MM:SS[.fraction] timestamp[(fsp)]
      year 1 1000 9999 YYYY year(date)
    • timestamp:YYYY-MM-DD HH:MM:SS 格式的字符串

      • 应用场合:需要经常插入或者更新日期为当前系统时间的时候用。
      • 显示宽度固定为 19 个字符。如果想要获得数字值,应在 timestamp 列添加 "+0"。
      • MySQL 规定,timestamp 类型字段一列的默认值为 current_timestamp,如果强制修改,系统会报错。
      • MySQL 只给表中的第一个 timestamp 字段设置默认值为系统日期,如果有第二个 timestamp 类型,则默认值设置为 0 值。
      • 特点:与时区相关。当插入日期时,会先转换为本地时区后存放;而从数据库里面取出时,也同样需要将日期转换为本地时区后显示。这样,两个不同时区的用户看到的同一个日期可能是不一样的。
    • year:YYYY

      • 它比 date 占用更少的空间。
      • year 有 2 位或 4 位格式的年,默认是 4 位格式。
      • 在 4 位格式中,允许的值是 1901~2155 和 0000。
      • 在 2 位格式中,允许的值是 70~69,表示从 1970~2069 年。
      • MySQL 以 YYYY 格式显示 year 值(从 5.5.27 开始,2 位格式的 year 已经不被支持)。
  • 2)零值

    • 每种日期时间类型都有一个有效值范围,如果超出这个范围,在默认的 SQLMode 下,系统会进行错误提示,并将以零值来进行存储。

      类型 零值
      date 0000-00-00
      time 00:00:00
      datetime 0000-00-00 00:00:00
      timestamp 0000-00-00 00:00:00
      year 0000
  • 3)timestamp 和 datetime 的区别

    • 时间取值范围不同

      • timestamp:1970-01-01 08:00:01 到 2038 年的某个时间,时间取值范围较小。
      • datetime :1000-01-01 00:00:00 到 9999-12-31 23:59:59,范围较大。
    • 时间属性的不同

      • timestamp
        • 表中的第一个 timestamp 列自动设置为系统时间 current_timestamp。如果在一个 timestamp 列中插入 null 或者不明确给该列赋值时,则该列值将自动设置为当前的日期和时间。
        • 当插入的值超出取值范围时,MySQL 认为该值溢出,使用零值 "0000-00-00 00:00:00" 进行填补。
        • timestamp 插入和查询都受当地时区的影响,更能反映出实际的日期。
        • 其属性受 MySQL 版本和服务器 SQLMODE 的影响很大,本章是以 MySQL5.0 为例,具体要参照想对应的 MySQL 帮助文档。
      • datetime
        • 只能反映出插入时当地的时区,其他时区的人查看数据必然会有误差的。
  • 4)示例

    > create table t6(dt datetime);
    
        Query OK, 0 rows affected (0.03 sec)
    
    > insert into t6 values('2007-9-3 12:10:10');
    
        Query OK, 1 row affected (0.00 sec)
    
    > insert into t6 values('2007/9/3 12+10+10');
    
        Query OK, 1 row affected (0.00 sec)
    
    > insert into t6 values('20070903121010');
    
        Query OK, 1 row affected (0.01 sec)
    
    > insert into t6 values(20070903121010);
    
        Query OK, 1 row affected (0.00 sec)
    
    > select * from t6;
    
        +---------------------+
        | dt                  |
        +---------------------+
        | 2007-09-03 12:10:10 |
        | 2007-09-03 12:10:10 |
        | 2007-09-03 12:10:10 |
        | 2007-09-03 12:10:10 |
        +---------------------+
        4 rows in set (0.00 sec)

3、字符串类型

  • MySQL 包括了 char、varchar、binary、varbinary、blob、text、enum 和 set 等多种字符串类型。

    字符串类型 字节 描述及存储要求
    char(m) m 允许长度 0~255 个字节的定长字节字符串
    varchar(m) 允许长度 0~65535 个字节的变长字节字符串,值的长度为 +1 字节
    tinytext 允许长度 0~255 字节,值的长度为 +2 字节
    text 允许长度 0~65535 字节,值的长度为 +2 字节
    mediumtext 允许长度 0~167772150 字节,值的长度为 +3 字节
    longtext 允许长度 0~4294967295 字节,值的长度为 +4 字节
    binary(m) m 允许长度 0~m 个字节的定长字节字符串
    varbinary(m) 允许长度 0~m 个字节的变长字节字符串,值的长度为 +1 字节
    tinyblob 允许长度 0~255 字节,值的长度为 +1 字节
    blob 允许长度 0~65535 字节,值的长度为 +2 字节
    mediumblob 允许长度 0~167772150 字节,值的长度为 +3 字节
    longblob 允许长度 0~4294967295 字节,值的长度为 +4 字节

3.1 char 和 varchar 类型

  • 1)相同点

    • char 和 varchar 都用来保存 MySQL 中较短的字符串。
  • 2)区别

    • 存储方式的不同

      • char 列的长度固定为创建表时声明的长度,长度可以为从 0~255 的任何值;
      • varchar 列中的值为可变长字符串,长度可以指定为 0~255(MySQL 5.0.3 版本以前)或者 65535(MySQL 5.0.3 版本以后)之间的值。
    • 在检索的时的处理方式

      • char 列删除了尾部的空格,
      • varchar 保留尾部的空格。
  • 3)示例

    > create table vc ( v varchar(4), c char(4) );
    
        Query OK, 0 rows affected (0.06 sec)
    
    > insert into vc values ('ab  ', 'ab  ');
    
        Query OK, 1 row affected (0.06 sec)
    
    > select length(v),length(c) from vc;
    
        +-----------+-----------+
        | length(v) | length(c) |
        +-----------+-----------+
        |         4 |         2 |
        +-----------+-----------+
        1 row in set (0.00 sec)
    
    > SELECT concat(v, '+'), concat(c, '+') from vc;
    
        +----------------+----------------+
        | concat(v, '+') | concat(c, '+') |
        +----------------+----------------+
        | ab  +          | ab+            |
        +----------------+----------------+
        1 rows in set (0.00 sec)
    • 显然 char 列最后的空格在做操作时都已经被删除,而 varchar 依然保留空格。

3.2 binary 和 varbinary 类型

  • 1)binary 和 varbinary 类似于 char 和 varchar,不同的是它们包含二进制字符串而不包含非二进制字符串。

  • 2)示例

    > create table t ( c binary(3) );
    
        Query OK, 0 rows affected (0.03 sec)
    
    > insert into t set c = 'a';
    
        Query OK, 1 row affected (0.04 sec)
    
    > select *, hex(c), c = 'a', c = 'a\0', c = 'a\0\0' from t;
    
        +------+--------+---------+-----------+-------------+
        | c    | hex(c) | c = 'a' | c = 'a\0' | c = 'a\0\0' |
        +------+--------+---------+-----------+-------------+
        | a    | 610000 |       0 |         0 |           1 |
        +------+--------+---------+-----------+-------------+
        1 row in set (0.00 sec)
    • 可以发现,当保存 binary 值时,在值的最后通过填充 "0x00"(零字节)以达到指定的字段定义长度。从上例中看出,对于一个 binary(3) 列,当插入时 "a" 变为 "a\0\0"。

3.3 blob 类型

  • 1)MySQL 中,blob 是一个二进制字符串大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。blob 类型实际是个类型系列(tinyblob、blob、mediumblob、longblob),除了在存储的最大信息量上不同外,他们是等同的。

  • 2)存储空间

    类型 字节
    tinyblob 255B
    blob 65K
    mediumblob 16M
    longblob 4G

3.4 text 类型

  • 1)MySQL 中,text 是一个字符串大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。text 类型实际是个类型系列(tinytext、text、mediumtext、longtext),除了在存储的最大信息量上不同外,他们是等同的。

  • 2)存储空间

    类型 字节
    tinytext 255B
    text 65K
    mediumtext 16M
    longtext 4G

3.5 enum 类型

  • 1)取值范围

    • 是一个字符串对象,它的值范围需要在创建表时指定。
  • 2)存储空间

    • enum 里面可以包含 0~65535 个成员。根据成员的不同,存储上也有所不同。

      成员个数 字节
      1~255 1
      255~65535 2
  • 3)示例

    > create table t ( gender enum('M', 'F'));
    
        Query OK, 0 rows affected (0.06 sec)
    
    > insert into t values ('M'), ('1'), ('f'), (null);
    
        Query OK, 4 rows affected (0.06 sec)
        Records: 4  Duplicates: 0  Warnings: 0
    
    > select * from t;
    
        +--------+
        | gender |
        +--------+
        | M      |
        | M      |
        | F      |
        | NULL   |
        +--------+
        4 rows in set (0.00 sec)
    • 从上面的例子中,可以看出 enum 类型是忽略大小写的,在存储 “M”、“f” 时将它们都转成了大写.
    • 还可以看出对于插入不在 enum 指定范围内的值时,并没有返回警告,而是插入了 enum('M','F') 的第一个值 “M”,这点用户在使用时要特别注意。
    • 另外,enum 类型只允许从值集合中选取单个值,而不能一次取多个值。

3.6 set 类型

  • 1)取值范围

    • 是一个字符串对象,它的值范围需要在创建表时指定。
  • 2)存储空间

    • set 里面可以包含 0~64 个成员。根据成员的不同,存储上也有所不同。

      成员个数 字节
      1~8 1
      9~16 2
      17~24 3
      25~32 4
      33~64 8
  • 3)与 enum 的区别

    • 存储空间

      • set 和 enum 存储空间不同。
    • 选取成员个数

      • 最主要的区别在于 set 类型一次可以选取多个成员,而 enum 则只能选一个。
    • 插入值选取

      • set 类型可以从允许值集合中选择任意 1 个或多个元素进行组合。
      • enum 只允许从集合值中选取单个值,而不能一次取多个值。
    • 插入值超出范围处理方式

      • 对于超出定义的 set 允许值范围的值将不允许注入到设置的 set 类型列中,发出警告。
      • 对于('a,d,a')这样包含重复成员的集合将只取一次,写入后的结果为 "a,d"。
      • 对于超出定义的 enum 允许范围的值,并不返回警告,而是插入一个在 enum 指定值范围的第一个值。
      • enum 类型只允许从值集合中选取。
  • 4)示例

    > create table t (col set('a', 'b', 'c', 'd'));
    
        Query OK, 0 rows affected (0.11 sec)
    
    > insert into t values ('a,b'), ('a,d,a'), ('a,b'), ('a,c'), ('a');
    
        Query OK, 5 rows affected (0.02 sec)
        Records: 5  Duplicates: 0  Warnings: 0
    
    > select * from t;
    
        +------+
        | col  |
        +------+
        | a,b  |
        | a,d  |
        | a,b  |
        | a,c  |
        | a    |
        +------+
        5 rows in set (0.00 sec)
    • set 类型可以从允许值集合中选择任意 1 个或多个元素进行组合。
    • 对于输入的值只要是在允许值的组合范围内,都可以正确地注入到 set 类型的列中。
    • 对于超出允许值范围的值例如('a,d,f ')将不允许注入到上面例子中设置的 set 类型列中。
    • 而对于('a,d,a')这样包含重复成员的集合将只取一次,写入后的结果为 "a,d"。

猜你喜欢

转载自www.cnblogs.com/QianChia/p/9201204.html