MySQL支持的数据类型

jopen 10年前

数值类型


MySQL中包括严格数据类型(INTEGER,SAMLLINT,DECIMAL,NUMERIC),以及近似数据类型(FLOAT,REAL,DOUBLE),扩展后增加了TINYINT,MEDIUMINT和BIGINT这三种长度不同的整形,并增加了BIT类型,用来存放位数据。

在整数类型中,按照取值范围和存储方式不同,可以分为tinyint,smallint,mediumint,int和bigint这5个类型。

对于整形数据,MySQL支持在类型名称后面的小括号内指定显示宽度,例如int(5)表示当数值宽度小于5位的时候在数字前面填满宽度,如果不显示指定宽度则默认为int(11)。但是,对大多数应用来说这是没有意义的,它不会限制值的合法范围,只是规定了MySQL的一些交互工具用来显示字符的个数。对于存储和计算来说,INT(1)和INT(20)是相同的。zerofill是用‘0’填充的意思,在数字位数不够的空间用字符‘0’填满。

浮点数存在误差问题;对货币等对精度敏感的数据,应该用定点数表示或存储;在编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较;要注意浮点数中一些特殊值的处理。

日期时间类型


Mysql中有多种数据类型可以用于日期和时间的表示。
这些数据类型的主要区别如下:
(1)如果要用来表示年月日,通常用DATE来表示;
(2)如果要用来表示年月日时分秒,通常用DATETIME表示;
(3)如果只用来表示时分秒,通常用TIME来表示;
(4)如果需要进场插入或者更新日期为当前系统时间,则通常使用TIMESTAMP来表示。
(5)如果只是年份,可以使用YEAR来表示。

不同日期类型零值的表示如下所示:
数据类型 零值表示
DATETIME 0000-00-00 00:00:00
TIME 00:00:00
DATE 0000-00-00
TIMESTAMP 00000000000000
YEAR 0000

MySQL提供了FROM_UNIXTIME()函数把Unix时间戳转换为日期,并提供了UNIX_TIMESTAMP()函数把日期转换为Unix时间戳。

在存储数据的时候将整个时间存在一个字段中,采用datetime类型;也可能采用将日期和时间分离,即一个字段存储date,一个字段存储时间time。无论怎么存储,在实际应用中,很可能会出现包含“时间段”类型的查询,比如一个访问记录数据库,需要统计每天的访问数量,这个每天就是一个时间段。

下面介绍MySql查询时间段的两种常见方法,其他数据库也可以类似实现。
方法一:传统方式,即指定开始时间和结束时间,用"between”或者"<",">"来建立条件。
比如查询2010年3月1日到2010年3月2日的数据条数,则可以使用
 
    select count(*) from sometable where datetimecolumn>='2010-03-01 00:00:00' and datetimecolumn<'2010-03-02 00:00:00  
但是,这种方法由于时间不是整数型数据,所以在比较的时候效率较低,所以如果数据量较大,可以将时间转换为整数型的UNIX时间戳。
</div>

方法二:UNIX时间戳,每个时间对应了一个唯一的UNIX时间戳,该时间戳是从'1970-01-01 00:00:00' 为0开始计时,每秒增加1。MySql内置了传统时间和UNIX时间的互换函数,分别为UNIX_TIMESTAMP(datetime)和 FROM_UNIXTIME(unixtime)。
比如运行
 
    SELECT UNIX_TIMESTAMP('2010-03-01 00:00:00')  
返回1267372800。</div>

运行
 
    SELECT FROM_UNIXTIME(1267372800)  
返回'2010-03-01 00:00:00'</div>
于是,我们可以将时间字段里的数据替换为整型的UNIX时间,这样,比较时间就成为整数比较了,建立索引后能大大提高效率。

在查询的时候,需要把起点时间和结尾时间分别转换为UNIX时间再进行比较,如
 
</div> </div>
    select count(*) from sometable where datetimecolumn>=UNIX_TIMESTAMP('2010-03-01 00:00:00') anddatetimecolumn<UNIX_TIMESTAMP('2010-03-02 00:00:00')  
也可以在调用程序中先转换为UNIX时间再传入MySql,总之这种方式有利于快速查询时间段,不过显示时间则需要再反转一次。</div>

字符串类型


CHAR和VARCHAR很类似,都用来保存MySQL中较短的字符串。二者的主要区别在于存储方式的不同:CHAR列的长度固定为创建表时声明的长度,长度可以是从0~255的任意值,而VARCHAR列中的值为可变长字符串,长度可以指定为0~255之间的值。在检索的时候,CHAR删除了尾部的空格,而VARCHAR则保留了这些空格。
由于CHAR是固定长度的,所以它的处理速度比VARCHAR快得多,但是它的缺点是浪费存储空间,程序需要对行尾空格进行处理,所以对于那些长度变化不大并且对查询速度有较高要求的数据可以考虑使用CHAR类型。定长的CHAR类型不容易产生碎片。

如果需要保存大文本时,一般使用TEXT或者BLOB,二者之间的区别主要是BLOB能用来保存二进制数据,比如照片,而TEXT只能保存字符数据,比如一篇文章或者日记。
大文本查询可以使用合成索引。合成索引是根据大文本字段的内容建立一个散列值,并把这个值存储在单独的数据列中,接下来就可以通过检索散列值找到数据行了。对含有TEXT和BLOB字段的表,如果经常做删除和修改记录的操作要定时执行OPTIMIZE TABLE功能对表进行碎片整理。
与其他类型不同,MySQL把每个BLOG和TEXT当做一个独立的对象处理。存储引擎在存储时通常会做特殊处理。当BLOG和TEXT值太大时,InnoDB会使用专门的“外部”存储区域来进行存储,此时每个值在行内需要1~4个字节存储一个指针,然后再外部存储区域存储实际的值。

BINARY和VAEBINARY类似于CHAR和VAECHAR,不同的是它们包含了二进制字符串。当保存BINARY值时,在值的最后通过填充“0x00”以达到指定的字段定义长度。

ENUM是枚举类型,它的值范围需要在创建表时通过枚举方式显示指定。但是ENUM只允许从值集合中选取单个值,而不能一次取多个值。
SET类型可以从允许值中选取任意1个或者多个元素进行组合。如果集合中包含重复的单元,那么我们将会只取一次。