mysql 整型命令行 整型 怎么显示0001

Part 1 字符集和字符编码

· 如何识别乱码的本来想要表达的文字

· 常见问题处理之Emoji

这部分将简述字符集,字符编码的概念。以及在遭遇乱码时的一些常用诊断技巧。

字符集和编码无疑是IT菜鸟甚至是各种大神的头痛问题。当遇到纷繁复杂的字符集,各种火星文和乱码时,问题的定位往往变得非常困难。我们将会从原理方面对字符集和编码做个简单的科普介绍,同时也会介绍一些通用的乱码故障定位的方法以方便读者以后能够更从容的定位相关问题。在正式介绍之前,先做个小申明:如果你希望非常精确的理解各个名词的解释,那么可以查阅wikipedia。本文是作者通过自己理解消化后并转化成易懂浅显的表述后的介绍。

在介绍字符集之前,我们先了解下为什么要有字符集。我们在计算机屏幕上看到的是实体化的文字,而在计算机存储介质中存放的实际是二进制的比特流。那么在这两者之间的转换规则就需要一个统一的标准,否则把我们的U盘插到老板的电脑上,文档就乱码了;小伙伴QQ上传过来的文件,在我们本地打开又乱码了。于是为了实现转换标准,各种字符集标准就出现了。简单的说字符集就规定了某个文字对应的二进制数字存放方式(编码)和某串二进制数值代表了哪个文字(解码)的转换关系。


那么为什么会有那么多字符集标准呢?这个问题实际非常容易回答。问问自己为什么我们的插头拿到英国就不能用了呢?为什么显示器同时有DVI,VGA,HDMI,DP这么多接口呢?很多规范和标准在最初制定时并不会意识到这将会是以后全球普适的准则,或者处于组织本身利益就想从本质上区别于现有标准。于是,就产生了那么多具有相同效果但又不相互兼容的标准了。


说了那么多我们来看一个实际例子,下面就是屌这个字在各种编码下的十六进制和二进制编码结果,怎么样有没有一种很屌的感觉?

字符集只是一个规则集合的名字,对应到真实生活中,字符集就是对某种语言的称呼。例如:英语,汉语,日语。对于一个字符集来说要正确编码转码一个字符需要三个关键元素:字库表(character repertoire)、编码字符集(coded character set)、字符编码(character encoding form)。其中字库表是一个相当于所有可读或者可显示字符的数据库,字库表决定了整个字符集能够展现表示的所有字符的范围。编码字符集,即用一个编码值code point来表示一个字符在字库中的位置。字符编码,将编码字符集和实际存储数值之间的转换关系。一般来说都会直接将code point的值作为编码后的值直接存储。例如在ASCII中A在表中排第65位,而编码后A的数值是0100 0001也即十进制的65的二进制转换结果。


看到这里,可能很多读者都会有和我当初一样的疑问:字库表和编码字符集看来是必不可少的,那既然字库表中的每一个字符都有一个自己的序号,直接把序号作为存储内容就好了。为什么还要多此一举通过字符编码把序号转换成另外一种存储格式呢?其实原因也比较容易理解:统一字库表的目的是为了能够涵盖世界上所有的字符,但实际使用过程中会发现真正用的上的字符相对整个字库表来说比例非常低。例如中文地区的程序几乎不会需要日语字符,而一些英语国家甚至简单的ASCII字库表就能满足基本需求。而如果把每个字符都用字库表中的序号来存储的话,每个字符就需要3个字节(这里以Unicode字库为例),这样对于原本用仅占一个字符的ASCII编码的英语地区国家显然是一个额外成本(存储体积是原来的三倍)。算的直接一些,同样一块硬盘,用ASCII可以存1500篇文章,而用3字节Unicode序号存储只能存500篇。于是就出现了UTF-8这样的变长编码。在UTF-8编码中原本只需要一个字节的ASCII字符,仍然只占一个字节。而像中文及日语这样的复杂字符就需要2个到3个字节来存储。

本部分将详细介绍MySQL乱码的成因和具体的解决方案

MySQL出现乱码的原因

要了解为什么会出现乱码,我们就先要理解:从客户端发起请求,到MySQL存储数据,再到下次从表取回客户端的过程中,哪些环节会有编码/解码的行为。为了更好的解释这个过程,博主制作了两张流程图,分别对应存入和取出两个阶段。

存入MySQL经历的编码转换过程

上图中有3次编码/解码的过程(红色箭头)。三个红色箭头分别对应:客户端编码,MySQL Server解码,Client编码向表编码的转换。其中Terminal可以是一个Bash,一个web页面又或者是一个APP。本文中我们假定Bash是我们的Terminal,即用户端的输入和展示界面。图中每一个框格对应的行为如下:

  • 在terminal中使用输入法输入

  • terminal根据字符编码转换成二进制流

  • 将转换后的字符编码二进制流存入文件中

从MySQL表中取出数据经历的编码转换过程


上图有3次编码/解码的过程(红色箭头)。上图中三个红色箭头分别对应:客户端解码展示,MySQL Server根据character-set-client编码,表编码向character-set-client编码的转换。

  • 从文件读出二进制数据流

  • 用表字符集编码进行解码

  • client通过bash配置的字符编码展示查询结果

造成MySQL乱码的原因

}

这几个类型之间的唯一区别是在存储文件的最大大小上不同。

BLOB列存储的是二进制字符串(字节字符串);TEXT列存储的是非二进制字符串(字符字符串)。

BLOB列没有字符集,并且排序和比较基于列值字节的数值;TEXT列有一个字符集,并且根据字符集对值进行排序和比较

BLOB是二进制字符串,TEXT是非二进制字符串,两者均可存放大容量的信息。BLOB主要存储图片、音频信息等

而TEXT只能存储文本文件。


SQLSERVER并没有BLOB数据类型,只有大型对象数据类型(BLOB):

这些数据类型的数据都存放在LOB类型的数据页面里

如有不对的地方,欢迎大家拍砖o(∩_∩)o 

MySQL支持多种列类型:数值类型、日期/时间类型和字符串(字符)类型。本章首先对这些列类型进行了概述,然后更加详细地描述了各种列的类型,以及列类型存储需求的总结。概述很简单。关于具体列类型的详细信息应查阅详细的描述,例如指定值时允许使用的格式。

MySQL支持处理空间数据的扩展名。关于空间类型的信息参见。

几种列类型描述使用了下述惯例:

表示最大显示宽度。最大有效显示宽度是255。

适用于浮点和定点类型,并表示小数点后面的位数。最大可能的值是30,但不应大于M-2。

下面为数值列类型的概述。详细信息参见。列存储需求参见。

M指示最大显示宽度。最大有效显示宽度是255。显示宽度与存储大小或类型包含的值的范围无关,相关描述见。

警告:应当清楚,当使用在整数值(其中一个是UNSIGNED类型)之间使用减号时,结果是无符号。参见。

位字段类型。M表示每个值的位数,范围为从1到64。如果M被省略, 默认为1。

很小的整数。带符号的范围是-128到127。无符号的范围是0到255。

在将来,将根据标准SQL引入完全布尔类型的处理。

小的整数。带符号的范围是-32768到32767。无符号的范围是0到65535。

中等大小的整数。带符号的范围是-8388608到8388607。无符号的范围是0到。

普通大小的整数。带符号的范围是-到。无符号的范围是0到。

大整数。带符号的范围是-4775808到4775807。无符号的范围是0到。

应清楚BIGINT列的下述内容:

小(单精度)浮点数。允许的值是-3.E+38到-1.E-38、0和1.E-38到3.E+38。这些是理论限制,基于IEEE标准。实际的范围根据硬件或操作系统的不同可能稍微小些。

M是小数纵位数,D是小数点后面的位数。如果MD被省略,根据硬件允许的限制来保存值。单精度浮点数精确到大约7位小数位。

如果指定UNSIGNED,不允许负值。

使用浮点数可能会遇到意想不到的问题,因为在MySQL中的所有计算用双精度完成。参见。

普通大小(双精度)浮点数。允许的值是-1.到-2.、0和2.到 1.。这些是理论限制,基于IEEE标准。实际的范围根据硬件或操作系统的不同可能稍微小些。

M是小数总位数,D是小数点后面的位数。如果MD被省略,根据硬件允许的限制来保存值。双精度浮点数精确到大约15位小数位。

如果指定UNSIGNED,不允许负值。

浮点数。p表示精度(以位数表示),但MySQL只使用该值来确定是否结果列的数据类型为FLOAT或DOUBLE。如果p为从0到24,数据类型变为没有MD值的FLOAT。如果p为从25到53,数据类型变为没有MD值的DOUBLE。结果列范围与本节前面描述的单精度FLOAT或双精度DOUBLE数据类型相同。

压缩的“严格”定点数。M是小数位数(精度)的总数,D是小数点(标度)后面的位数。小数点和(负数)的‘-’符号不包括在M中。如果D是0,则值没有小数点或分数部分。DECIMAL整数最大位数(M)为65。支持的十进制数的最大位数(D)是30。如果D被省略, 默认是0。如果M被省略, 默认是10。

如果指定UNSIGNED,不允许负值。

所有DECIMAL列的基本计算(+,-,*,/)用65位精度完成。

是DECIMAL的同义词。FIXED同义词适用于与其它服务器的兼容性。

本节综合讨论了临时列类型。详细信息,参见。列存储需求参见。

日期。支持的范围为''到''。MySQL以'YYYY-MM-DD'格式显示DATE值,但允许使用字符串或数字为DATE列分配值。

TIMESTAMP列用于INSERT或UPDATE操作时记录日期和时间。如果你不分配一个值,表中的第一个TIMESTAMP列自动设置为最近操作的日期和时间。也可以通过分配一个NULL值,将TIMESTAMP列设置为当前的日期和时间。

两位或四位格式的年。默认是四位格式。在四位格式中,允许的值是1901到2155和0000。在两位格式中,允许的值是70到69,表示从1970年到2069年。MySQL以YYYY 格式显示YEAR值,但允许使用字符串或数字为YEAR列分配值。

本节综合讨论了字符串列类型。详细信息参见。列存储需求参见。

在某些情况中,MySQL可以将一个字符串列更改为不同于CREATE TABLE或ALTER TABLE语句中所给出的类型。参见。

MySQL 5.1字符串数据类型包括部分在MySQL 4.1之前的版本中没有的特性:

该表定义创建了一个名为c1的列,具有一个utf8字符集和该字符集的默认 校对规则,和一个名为c2的列以及latin1字符集和该字符集的二元 校对规则。二元校对规则对大小写不敏感。

·         字符列的排序和比较基于分配给列的字符集。在以前的版本中,排序和比较基于服务器字符集的校对规则。对于CHAR和VARCHAR 列,你可以用BINARY属性声明列让排序和 校对规则使用当前的字符代码值而不是词汇顺序。

关于MySQL 5.1中字符集的支持,参见。

固定长度字符串,当保存时在右侧填充空格以达到指定的长度。M表示列长度。M的范围是0到255个字符。

注释:当检索CHAR值时尾部空格被删除。

BINARY属性是指定列字符集的二元 校对规则的简写。排序和比较基于数值字符值。

MySQL允许创建类型CHAR(0)的列。这主要用于必须有一个列但实际上不使用值的旧版本的应用程序相兼容。当你需要只能取两个值的列时也很好:没有定义为NOT NULL的一个CHAR(0)列只占用一位,只可以取值NULL和''(空字符串)。

变长字符串。M 表示最大列长度。M的范围是0到65,535。(VARCHAR的最大实际长度由最长的行的大小和使用的字符集确定。最大有效长度是65,532字节)。

注释:MySQL 5.1遵从标准SQL规范,并且不删除VARCHAR值的尾部空格。

BINARY属性是指定列的字符集的二元 校对规则的简写。排序和比较基于数值字符值。

VARCHAR保存时用一个字节或两个字节长的前缀+数据。如果VARCHAR列声明的长度大于255,长度前缀是两个字节。

BINARY类型类似于CHAR类型,但保存二进制字节字符串而不是非二进制字符串。

VARBINARY类型类似于VARCHAR类型,但保存二进制字节字符串而不是非二进制字符串。

可以给出该类型的可选长度M。如果给出,则MySQL将列创建为最小的但足以容纳M字节长的值的BLOB类型。

可以给出可选长度M。则MySQL将列创建为最小的但足以容纳M字符长的值的TEXT类型。

最大长度为4,294,967,295或4GB(232–1)字节的BLOB列。LONGBLOB列的最大有效(允许的)长度取决于客户端/服务器协议中配置最大包大小和可用的内存。

最大长度为4,294,967,295或4GB(232–1)字符的TEXT列。LONGTEXT列的最大有效(允许的)长度取决于客户端/服务器协议中配置最大包大小和可用的内存。

枚举类型。只能有一个值的字符串,从值列'value1','value2',...,NULL中或特殊 ''错误值中选出。ENUM列最多可以有65,535个截然不同的值。ENUM值在内部用整数表示。

一个设置。字符串对象可以有零个或多个值,每个值必须来自列值'value1','value2',...SET列最多可以有64个成员。SET值在内部用整数表示。

作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。

(带符号的/无符号的)

(带符号的/无符号的)

MySQL还支持选择在该类型关键字后面的括号内指定整数值的显示宽度(例如,INT(4))。该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。

显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。

当结合可选扩展属性ZEROFILL使用时, 默认补充的空格用零代替。例如,对于声明为INT(5) ZEROFILL的列,值4检索为00004。请注意如果在整数列保存超过显示宽度的一个值,当MySQL为复杂联接生成临时表时会遇到问题,因为在这些情况下MySQL相信数据适合原列宽度。

所有整数类型可以有一个可选(非标准)属性UNSIGNED。当你想要在列内只允许非负数和该列需要较大的上限数值范围时可以使用无符号值。

浮点和定点类型也可以为UNSIGNED。同数类型,该属性防止负值保存到列中。然而,与整数类型不同的是,列值的上范围保持不变。

对于浮点列类型,在MySQL中单精度值使用4个字节,双精度值使用8个字节。

FLOAT类型用于表示近似数值数据类型。SQL标准允许在关键字FLOAT后面的括号内选择用位指定精度(但不能为指数范围)。MySQL还支持可选的只用于确定存储大小的精度规定。0到23的精度对应FLOAT列的4字节单精度。24到53的精度对应DOUBLE列的8字节双精度。

为了保证最大可能的可移植性,需要使用近似数值数据值存储的代码应使用FLOAT或DOUBLE PRECISION,不规定精度或位数。

DECIMAL和NUMERIC类型在MySQL中视为相同的类型。它们用于保存必须为确切精度的值,例如货币数据。当声明该类型的列时,可以(并且通常要)指定精度和标度;例如:

在该例子中,5是精度,2是标度。精度表示保存值的主要位数,标度表示小数点后面可以保存的位数。

标准SQL要求salary列能够用5位整数位和两位小数保存任何值。因此,在这种情况下可以保存在salary列的值的范围是从-999.99到999.99。

DECIMAL或NUMERIC的最大位数是65,但具体的DECIMAL或NUMERIC列的实际范围受具体列的精度或标度约束。如果此类列分配的值小数点后面的位数超过指定的标度允许的范围,值被转换为该标度。(具体操作与操作系统有关,但一般结果均被截取到允许的位数)。

BIT数据类型可用来保存位字段值。BIT(M)类型允许存储M位值。M范围为1到64。

要指定位值,可以使用b'value'符。value是一个用0和1编写的二进制值。例如,b'111'和b''分别表示7和128。参见。

如果为BIT(M)列分配的值的长度小于M位,在值的左边用0填充。例如,为BIT(6)列分配一个值b'101',其效果与分配b'000101'相同。

当要在一个数值列内保存一个超出该列允许范围的值时,MySQL的操作取决于此时有效的SQL模式。如果模式未设置,MySQL将值裁剪到范围的相应端点,并保存裁减好的值。但是,如果模式设置为traditional(“严格模式”),超出范围的值将被拒绝并提示错误,并且根据SQL标准插入会失败。参见。

如果INT列是UNSIGNED,列范围的大小相同,但其端点会变为到0和。如果你试图保存-和,以非严格模式保存到列中的值是0和。

如果在浮点或定点列中分配的值超过指定(或默认)精度和标度规定的范围,MySQL以非严格模式保存表示范围相应端点的值。

当MySQL没有工作在严格模式时,对于ALTER TABLE、LOAD DATA INFILE、UPDATE和多行INSERT语句,由于裁剪发生的转换将报告为警告。当MySQL工作在严格模式时,这些语句将失败,并且部分或全部值不会插入或更改,取决于是否表为事务表和其它因素。详情参见。

表示时间值的DATE和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。每个时间类型有一个有效值范围和一个“零”值,当指定不合法的MySQL不能表示的值时使用“零”值。TIMESTAMP类型有专有的自动更新特性,将在后面描述。

如果试图插入一个不合法的日期,MySQL将给出警告或错误。可以使用ALLOW_INVALID_DATES SQL模式让MySQL接受某些日期,例如''。当你想要保存一个“可能错误的”用户已经在数据库中指定(例如,以web形式)用于将来处理的值时很有用。在这种模式下,MySQL只验证月范围为从0到12,日范围为从0到31。这些范围可以包括零,因为MySQL允许在DATE或DATETIME列保存日/月和日是零的日期。这在应用程序需要保存一个你不知道确切日期的生日时非常有用。在这种情况下,只需要将日期保存为''或''。如果保存此类日期,DATE_SUB()或DATE_ADD等需要完整日期的函数不会得到正确的结果。(如果你不想在日期中出现零,可以使用NO_ZERO_IN_DATE SQL模式)。

MySQL还允许将''保存为“伪日期”(如果不使用NO_ZERO_DATE SQL模式)。这在某些情况下比使用NULL值更方便(并且数据和索引占用的空间更小)。

将sql_mode系统变量设置为相应模式值,可以更确切你想让MySQL支持哪种日期。参见。

当使用日期和时间类型时应记住以下几点:

·         MySQL以标准输出格式检索给定日期或时间类型的值,但它尽力解释你指定的各种输入值格式(例如,当你指定一个分配给或与日期或时间类型进行比较的值时)。只支持下面章节中描述的格式。期望你能提供有效值。如果你使用其它格式的值会发生意想不到的结果。

·         当 MySQL遇到一个日期或时间类型的超出范围或对于该类型不合法的值时(如本节开始所描述),它将该值转换为该类的“零”值。一个例外是超出范围的TIME值被裁剪到TIME范围的相应端点。

下面的表显示了各类“零”值的格式。请注意如果启用NO_ZERO_DATE SQL模式,使用这些值会产生警告。

DATETIME、DATE和TIMESTAMP类型是相关的。该节描述了它们的特征,它们的相似点和不同点。

当你只需要日期值而不需要时间部分时应使用DATE类型。MySQL用'YYYY-MM-DD'格式检索和显示DATE值。支持的范围是''到 ''。

TIMESTAMP列类型的属性不固定,取决于MySQL版本和服务器运行的SQL模式。这些属性将在本节后面描述。

09:15:28',但''是不合法的(它有一个没有意义的分钟部分),将变为' 00:00:00'。

对于包括日期部分间割符的字符串值,如果日和月的值小于10,不需要指定两位数。''与''是相同的。同样,对于包括时间部分间割符的字符串值,如果时、分和秒的值小于10,不需要指定两位数。' 1:2:3'与' 01:02:03'相同。

数字值应为6、8、12或者14位长。如果一个数值是8或14位长,则假定为YYYYMMDD或YYYYMMDDHHMMSS格式,前4位数表示年。如果数字 是6或12位长,则假定为YYMMDD或YYMMDDHHMMSS格式,前2位数表示年。其它数字被解释为仿佛用零填充到了最近的长度。

指定为非限定符字符串的值使用给定的长度进行解释。如果字符串为8或14字符长,前4位数表示年。否则,前2位数表示年。从左向右解释字符串内出现的各部分,以发现年、月、日、小时、分和秒值。这说明不应使用少于6字符的字符串。例如,如果你指定'9903',认为它表示1999年3月,MySQL将在你的表内插入一个“零”日期值。这是因为年和月值是99和03,但日部分完全丢失,因此该值不是一个合法的日期。但是,可以明显指定一个零值来代表缺少的月或日部分。例如,可以使用'990300'来插入值''。

在一定程度上,可以将一个日期类型的值分配给一个不同的日期类型。但是,值可能会更改或丢失一些信息:

当指定日期值时请注意某些缺陷:

·         在非严格模式,MySQL服务器只对日期的合法性进行基本检查:年、月和日的范围分别是1000到9999、00到12和00到31。任何包含超出这些范围的部分的日期被转换成''。请注意仍然允许你保存非法日期,例如''。要想确保不使用严格模式时日期有效,应检查应用程序。

在严格模式,非法日期不被接受,并且不转换。

注释:在旧版本的MySQL中(4.1之前),TIMESTAMP列类型的属性在许多方面于本节所描述的大大不同。如果你需要对旧的TIMESTAMP数据进行转化以便在MySQL 5.1中工作,详情请参见MySQL 4.1 参考手册

MySQL服务器也可以以MAXDB模式运行。当服务器以该模式运行时,TIMESTAMP与DATETIME相等。也就是说,如果创建表时服务器以MAXDB模式运行,TIMESTAMP列创建为DATETIME列。结果是,该列使用DATETIME显示格式,有相同的值范围,并且没有自动对当前的日期和时间进行初始化或更新。

要想启用MAXDB模式,在启动服务器时使用--sql-mode=MAXDB服务器选项或在运行时通过设置全局sql_mode变量将SQL服务器模式设置为MAXDB:

客户端可以按照下面方法让服务器为它的连接以MAXDB模式运行:

MySQL不接受在日或月列包括一个零或包含非法日期值的时间戳值。该规则的唯一例外是特殊值' 00:00:00'。

你可以非常灵便地确定什么时候初始化和更新TIMESTAMP和对哪些列进行初始化和更新:

·         你可以将当前的时间戳指定为默认值和自动更新的值。但只能选择一个,或者两者都不选。(不可能一个列选择一个行为而另一个列选择另一个行为)。

请注意下面讨论所信息只适用于创建时未启用MAXDB模式的表的TIMESTAMP列。(如上所述,MAXDB模式使列创建为DATETIME列)。控制TIMESTAMP列的初始化和更新的规则如下所示:

换句话说,你可以为初始值和自动更新的值使用当前的时间戳,或者其中一个使用,或者两个皆不使用。(例如,你可以指定ON UPDATE来启用自动更新而不让列自动初始化)。

两个属性的顺序并不重要。如果一个TIMESTAMP列同时指定了DEFAULT和ON UPDATE,任何一个可以在另一个的前面。

例子,下面这些语句是等效的:

00:00:00')。然后,对于其它TIMESTAMP列,规则与第1个TIMESTAMP列相同,例外情况是不能忽略DEFAULT和ON UPDATE子句。如果这样做,则不会自动进行初始化或更新。

例如:下面这些语句是等效的:

可以对每个连接设置当前的时区,相关描述参见。TIMESTAMP值以UTC格式保存,存储时对当前的时区进行转换,检索时再转换回当前的时区。只要时区设定值为常量,便可以得到保存时的值。如果保存一个TIMESTAMP值,应更改时区然后检索该值,它与你保存的值不同。这是因为在两个方向的转换中没有使用相同的时区。当前的时区可以用作time_zone系统变量的值。

可以在TIMESTAMP列的定义中包括NULL属性以允许列包含NULL值。例如:

如果未指定NULL属性,将列设置为NULL设置则会将它设置为当前的时间戳。请注意允许NULL值的TIMESTAMP列不会采用当前的时间戳,除非要么其 默认值定义为CURRENT_TIMESTAMP,或者NOW()或CURRENT_TIMESTAMP被插入到该列内。换句话说,只有使用如下定义创建,定义为 NULL的TIMESTAMP列才会自动更新:

...则必须显式插入一个对应当前日期和时间的值。例如:

MySQL以'HH:MM:SS'格式检索和显示TIME值(或对于大的小时值采用'HHH:MM:SS'格式)。TIME值的范围可以从'-838:59:59'到'838:59:59'。小时部分会因此大的原因是TIME类型不仅可以用于表示一天的时间(必须小于24小时),还可能为某个事件过去的时间或两个事件之间的时间间隔(可以大于24小时,或者甚至为负)。

你可以用各种格式指定TIME值:

HH'或'SS'。这里D表示日,可以取0到34之间的值。请注意MySQL还不保存分数。

对于指定为包括时间部分间割符的字符串的TIME值,如果时、分或者秒值小于10,则不需要指定两位数。'8:3:2'与'08:03:02'相同。

YEAR类型是一个单字节类型用于表示年。

可以指定各种格式的YEAR值:

MySQL本身对于2000年(Y2K)是安全的(参见),但输入给MySQL的值可能不安全。任何包含两位年值的输入都会令人模糊,因为世纪不知道。这些值必须解释为四位形式,因为MySQL内部使用四位来保存年。

请记住这些规则只是合理猜测数据值表示什么。如果MySQL使用的启发不能产生正确的值,你应提供包含四位年值的确切输入。

字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。

CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

CHAR和VARCHAR类型声明的长度表示你想要保存的最大字符数。例如,CHAR(30)可以占用30个字符。

CHAR列的长度固定为创建表时声明的长度。长度可以为从0到255的任何值。当保存CHAR值时,在它们的右边填充空格以达到指定的长度。当检索到CHAR值时,尾部的空格被删除掉。在存储或检索过程中不进行大小写转换。

VARCHAR列中的值为可变长字符串。长度可以指定为0到65,535之间的值。(VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532字节)。

同CHAR对比,VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)。

VARCHAR值保存时不进行填充。当值保存和检索时尾部的空格仍保留,符合标准SQL。

如果分配给CHAR或VARCHAR列的值超过列的最大长度,则对值进行裁剪以使其适合。如果被裁掉的字符不是空格,则会产生一条警告。如果裁剪非空格字符,则会造成错误(而不是警告)并通过使用严格SQL模式禁用值的插入。参见。

下面的表显示了将各种字符串值保存到CHAR(4)和VARCHAR(4)列后的结果,说明了CHAR和VARCHAR之间的差别:

请注意上表中最后一行的值只适用不使用严格模式时;如果MySQL运行在严格模式,超过列长度不的值保存,并且会出现错误。

从CHAR(4)和VARCHAR(4)列检索的值并不总是相同,因为检索时从CHAR列删除了尾部的空格。通过下面的例子说明该差别:

 
 

根据分配给列的字符集校对规则对CHAR和VARCHAR列中的值进行排序和比较。

请注意所有MySQL校对规则属于PADSPACE类。这说明在MySQL中的所有CHAR和VARCHAR值比较时不需要考虑任何尾部空格。例如:

 
 

请注意所有MySQL版本均如此,并且它不受SQL服务器模式的影响。

对于尾部填充字符被裁剪掉或比较时将它们忽视掉的情形,如果列的索引需要唯一的值,在列内插入一个只是填充字符数不同的值将会造成复制键值错误。

BINARY和VARBINARY类类似于CHAR和VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。

latin1_bin,假定默认字符集是latin1。这不同于BINARY(5),它保存5字节二进制字符串,没有字符集或 校对规则。

当保存BINARY值时,在它们右边填充值以达到指定长度。填充值是0x00(零字节)。插入值时在右侧添加0x00 on,并且选择时不删除尾部的字节。比较时所有字节很重要,包括ORDER BY和DISTINCT操作。比较时0x00字节和空格是不同的,0x00<空格。

对于VARBINARY,插入时不填充字符,选择时不裁剪字节。比较时所有字节很重要,包括ORDER BY和DISTINCT操作。比较时0x00字节和空格是不同的,0x00<空格。

对于尾部填充字符被裁剪掉或比较时将它们忽视掉的情形,如果列的索引需要唯一的值,在列内插入一个只是填充字符数不同的值将会造成复制键值错误。

如果你计划使用这些数据类型来保存二进制数据并且需要检索的值与保存的值完全相同,应考虑前面所述的填充和裁剪特征。下面的例子说明了用0x00填充的BINARY值如何影响列值比较:

 
 

如果检索的值必须与指定进行存储而没有填充的值相同,最好使用BLOB数据类型。

BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。

BLOB 列被视为二进制字符串(字节字符串)。TEXT列被视为非二进制字符串(字符字符串)。BLOB列没有字符集,并且排序和比较基于列值字节的数值值。TEXT列有一个字符集,并且根据字符集的 校对规则对值进行排序和比较。

在TEXT或BLOB列的存储或检索过程中,不存在大小写转换。

当未运行在严格模式时,如果你为BLOB或TEXT列分配一个超过该列类型的最大长度的值值,值被截取以保证适合。如果截掉的字符不是空格,将会产生一条警告。使用严格SQL模式,会产生错误,并且值将被拒绝而不是截取并给出警告。参见。

请注意比较时将用空格对TEXT进行扩充以适合比较的对象,正如CHAR和VARCHAR。

LONG和LONG VARCHAR对应MEDIUMTEXT数据类型。这是为了保证兼容性。如果TEXT列类型使用BINARY属性,将为列分配列字符集的二元 校对规则。

由于BLOB和TEXT值可能会非常长,使用它们时可能遇到一些约束:

运行时增加max_sort_length的值可以在排序或组合时使更多的字节有意义。任何客户端可以更改其会话max_sort_length变量的值:

当你想要使超过max_sort_length的字节有意义,对含长值的BLOB或TEXT列使用GROUP BY或ORDER BY的另一种方式是将列值转换为固定长度的对象。标准方法是使用SUBSTRING函数。例如,下面的语句对comment列的2000个字节进行排序:

每个BLOB或TEXT值分别由内部分配的对象表示。这与其它列类型形成对比,后者是当打开表时为每1列分配存储引擎。

ENUM是一个字符串对象,其值来自表创建时在列规定中显式枚举的一列值。

在某些情况下,ENUM值也可以为空字符串('')或NULL:

·         如果你将一个非法值插入ENUM(也就是说,允许的值列之外的字符串),将插入空字符串以作为特殊错误值。该字符串与“普通”空字符串不同,该字符串有数值值0。后面有详细讨论。

每个枚举值有一个索引:

例如,定义为ENUM的列('one','two','three')可以有下面所示任何值。还显示了每个值的索引:

枚举最多可以有65,535个元素。

当创建表时,ENUM成员值的尾部空格将自动被删除。

当检索时,保存在ENUM列的值使用列定义中所使用的大小写来显示。请注意可以为ENUM列分配字符集和 校对规则。对于二进制或大小写敏感的校对规则,当为列分配值时应考虑大小写。

如果在数值上下文中检索一个ENUM值,将返回列值的索引。例如,你可以这样从ENUM列搜索数值值:

如果将一个数字保存到ENUM列,数字被视为索引,并且保存的值是该索引对应的枚举成员。(但是,这不适合LOAD DATA,它将所有输入视为字符串)。不建议使用类似数字的枚举值来定义一个ENUM列,因为这很容易引起混淆。例如,下面的列含有字符串值'0'、'1'和'2'的枚举成员,但数值索引值为1、2和3:

根据枚举成员在列定义中列出的顺序对ENUM值进行排序。(换句话说,ENUM值根据索引编号进行排序)。例如,对于ENUM('a','b'),'a'排在'b'前面,但对于ENUM('b','a'),'b'排在'a'前面。空字符串排在非空字符串前面,并且NULL值排在所有其它枚举值前面。要想防止意想不到的结果,按字母顺序规定ENUM列。还可以使用GROUP BY 

SET是一个字符串对象,可以有零或多个值,其值来自表创建时规定的允许的一列值。指定包括多个SET成员的SET列值时各成员之间用逗号(‘,’)间隔开。这样SET成员值本身不能包含逗号。

SET最多可以有64个不同的成员。

当创建表时,SET成员值的尾部空格将自动被删除。

当检索时,保存在SET列的值使用列定义中所使用的大小写来显示。请注意可以为SET列分配字符集和 校对规则。对于二进制或大小写敏感的校对规则,当为列分配值时应考虑大小写。

MySQL用数字保存SET值,所保存值的低阶位对应第1个SET成员。如果在数值上下文中检索一个SET值,检索的值的位设置对应组成列值的SET成员。例如,你可以这样从一个SET列检索数值值:

如果将一个数字保存到SET列中,数字中二进制表示中的位确定了列值中的SET成员。对于指定为SET('a','b','c','d')的列,成员有下面的十进制和二进制值:

如果你为该列分配一个值9,其二进制形式为1001,因此第1个和第4个SET值成员'a'和'd'被选择,结果值为 'a,d'。

对于包含多个SET元素的值,当插入值时元素所列的顺序并不重要。在值中一个给定的元素列了多少次也不重要。当以后检索该值时,值中的每个元素出现一次,根据表创建时指定的顺序列出元素。例如,假定某个列指定为SET('a','b','c','d'):

当检索时所有这些值显示为 'a,d':

如果将SET列设置为一个不支持的值,则该值被忽略并发出警告:

 
 

第1个语句找出SET_col包含value set成员的行。第2个类似,但有所不同:它在其它地方找出set_col包含value的行,甚至是在另一个SET成员的子字符串中。

下面的语句也是合法的:

第1个语句寻找包含第1个set成员的值。第2个语句寻找一个确切匹配的值。应注意第2类的比较。将set值与'val1,val2'比较返回的结果与同'val2,val1'比较返回的结果不同。指定值时的顺序应与在列定义中所列的顺序相同。

根据类别列出了MySQL支持的每个列类型的存储需求。

MyISAM表中行的最大大小为65,534字节。每个BLOB和TEXT列 账户只占其中的5至9个字节。

如果MyISAM表包括变长列类型,记录格式也是可变长度。当创建表时,在某些条件下,MySQL可以将一个列从变长类型改为固定长度的类型或反之亦然。详细信息参见。

使用二进制格式将9个十进制(基于10)数压缩为4个字节来表示DECIMAL列值。每个值的整数和分数部分的存储分别确定。每个9位数的倍数需要4个字节,并且“剩余的”位需要4个字节的一部分。下表给出了超出位数的存储需求:

日期和时间类型的存储需求

1或2个字节,取决于枚举值的个数(最多65,535个值)

1、2、3、4或者8个字节,取决于set成员的数目(最多64个成员)

VARCHAR、BLOB和TEXT类是变长类型。每个类型的存储需求取决于列值的实际长度(用前面的表中的L表示),而不是该类型的最大可能的大小。例如,VARCHAR(10)列可以容纳最大长度为10的字符串。实际存储需求是字符串(L)的长度,加上一个记录字符串长度的字节。对于字符串'abcd',L是4,存储需要5个字节。

对于CHAR、VARCHAR和TEXT类型,前面的表中的值LM应解释为字符数目,并且列定义中的这些类型的长度表示字符数目。例如,要想保存一个TINYTEXT值需要L字符+ 1个字节。

要想计算用于保存具体CHAR、VARCHAR或者TEXT列值的字节数,需要考虑该列使用的字符集。在具体情况中,当使用Unicode时,必须记住所有Unicode字符使用相同的字节数。为了细分用于不同类Unicode字符使用的存储,参见。

注释:VARCHAR列的有效最大长度为65,532字符。

NDBCLUSTER引擎只支持固定宽度的列。这说明MySQL簇中的表中的VARCHAR列的行为如同类型CHAR(不同的是每个记录仍然有一个额外字节空间)。例如,在Cluster表中,声明为VARCHAR(100)的列中的每个记录存储时将占用101个字节,无论实际存储的记录中的字符串的长度为多少。

BLOB和TEXT类需要 1、2、3或者4个字节来记录列值的长度,取决于该类的最大可能的长度。参见。

在NDB Cluster存储引擎中,TEXT和BLOB列的实施是不同的,其中TEXT列中的每个记录由两个单独部分组成。一个是固定大小(256字节),并且实际上保存在原表中。另一个包括超出256字节的任何数据,保存在隐含的表中。第2个表中的记录总是2,000字节长。这说明如果size<=

ENUM对象的大小由不同的枚举值的数目确定。枚举用一个字节,可以有255个可能的值。当枚举的值位于256和65,535之间时,用两个字节。参见。

SET对象的大小由不同的set成员的数量确定。如果set大小是N,对象占(N+7)/8个字节,四舍五入到1、2、3、4或者8个字节。SET最多可以有64个成员。参见。

为了优化存储,在任何情况下均应使用最精确的类型。例如,如果列的值的范围为从1到99999,若使用整数,则MEDIUMINT UNSIGNED是好的类型。在所有可以表示该列值的类型中,该类型使用的存储最少。

用精度为65位十进制数(基于10)对DECIMAL 列进行所有基本计算(+、-、*、/)。参见。

使用双精度操作对DECIMAL值进行计算。如果准确度不是太重要或如果速度为最高优先级,DOUBLE类型即足够了。为了达到高精度,可以转换到保存在BIGINT中的定点类型。这样可以用64位整数进行所有计算,根据需要将结果转换回浮点值。

为了使用由其它卖方编写的SQL执行代码,MySQL按照下表所示对列类型进行映射。通过这些映射,可以很容易地从其它数据库引擎将表定义导入到MySQL中:

在创建表时对列类型进行映射,然后原来的类型定义被丢弃。如果你使用其它卖方的类型创建一个表,然后执行DESCRIBE tbl_name语句,MySQL使用等效的MySQL类型来报告表的结构。例如:

 
}

返回一个数字或字符串值,取决于它被使用的上下文环境。

返回一个数字或字符串值,取决于它被使用的上下文。

expr1作为整数值被计算,它意味着如果你正在测试浮点或字符串值,你应该使用一个比较操作来做。

该函数对多字节是可靠的。

组成的一个字符串。如果

,返回一个空字符串。如果

返回颠倒字符顺序的字符串

该函数对多字节可靠的。

个字符长得子串由字符串

该函数对多字节是可靠的。

0

的值。一个字符串表是被

分隔的子串组成的一个字符串。如果第一个参数是一个常数字符串并且第二个参数是一种类型为

函数被优化而使用位运算!如果

0

。如果第一个参数包含一个

,该函数将工作不正常。

返回一个集合 (包含由

字符分隔的子串组成的一个字符串),由相应的位在

集合中的的字符串组成。

 
返回一个字符串,在这里对于在“bits”中设定每一位,你得到一个“on”字符串,并且对于每个复位(reset)的位,你得到一个“off”字符串。每个字符串用“separator”分隔(缺省“,”),并且只有“bits”的“number_of_bits” (缺省64)位被使用。

,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成小写。该函数对多字节是可靠的。

,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成大写。该函数对多字节是可靠的。
该函数对多字节是可靠的。
读入文件并且作为一个字符串返回文件内容。文件必须在服务器上,你必须指定到文件的完整路径名,而且你必须有
权限。文件必须所有内容都是可读的并且小于
。如果文件不存在或由于上面原因之一不能被读出,函数返回
MySQL必要时自动变换数字为字符串,并且反过来也如此:
 
如果你想要明确地变换一个数字到一个字符串,把它作为参数传递到CONCAT()
 
如果字符串函数提供一个二进制字符串作为参数,结果字符串也是一个二进制字符串。被变换到一个字符串的数字被当作是一个二进制字符串。这仅影响比较。
 
 
 
 
 
 
 
 
 
 
 
对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6 日期和时间类型
 
这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col的值是在最后30天以内:
 




=星期六)。这些索引值对应于ODBC标准。

0























对于星期天是一周的第一天的地方,有一个单个参数,返回
0


允许你指定星期是否开始于星期天或星期一。如果第二个参数是 0
,星期从星期天开始,如果第二个参数是






0



0



0


















这些功能执行日期运算。对于













是指定加到开始日期或从开始日期减去的间隔值一个表达式,
是一个字符串;它可以以一个

是一个关键词,指明表达式应该如何被解释。
函数从日期中返回“type”间隔。下表显示了

MySQLexpr格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date参数是一个DATE值并且你的计算仅仅包含YEARMONTHDAY部分(即,没有时间部分),结果是一个DATE值。否则结果是一个DATETIME值。

 
如果你指定太短的间隔值(不包括type关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。例如,如果你指定一个typeDAY_SECOND,值expr被希望有天、小时、分钟和秒部分。如果你象"1:10"这样指定值,MySQL假设日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10" MINUTE_SECOND的方式解释,这对那MySQL解释TIME值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,结果是NULL。如果你增加MONTHYEAR_MONTHYEAR并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。

,返回一个天数(从0年的天数)。
TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。



TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。


值。下列修饰符可以被用在
缩写的星期名字(Sun……Sat)
月份中的天数, 数字(00……31)
月份中的天数, 数字(0……31)
缩写的月份名字(Jan……Dec)
星期(0……52), 这里星期天是星期的第一天
星期(0……52), 这里星期一是星期的第一天

所有的其他字符不做解释被复制到结果中。

 
MySQL3.23中,在格式修饰符字符前需要%。在MySQL更早的版本中,%是可选的。


字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个
0



格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。


格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。


格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的上下文被使用。
如果没有参数调用,返回一个Unix时间戳记(从
GMT开始的秒数)。如果








格式的本地时间的一个数字。




参数所表示的值,取决于函数是在一个字符串还是或数字上下文中被使用。
 
返回表示 Unix 时间标记的一个字符串,根据


函数列出的条目同样的修饰符。

参数,变换成小时、分钟和秒,值以

格式化,取决于函数是在一个字符串还是在数字上下文中被使用。

 
 
 
 
返回当前的数据库名字。
如果没有当前的数据库,DATABASE()返回空字符串。


在MySQL 3.22.11或以后版本中,这包括用户名和客户主机名。你可以象这样只提取用户名部分(值是否包括主机名部分均可工作):

计算一个口令字符串。该函数被用于为了在



PASSWORD()加密是非可逆的。PASSWORD()不以与Unix口令加密的相同的方法执行口令加密。你不应该假定如果你的Unix 口令和你的MySQL口令是一样的,PASSWORD()将导致与在Unix口令文件存储的相同的加密值。见ENCRYPT()



参数应该是一个有2个字符的字符串。(MySQL 3.22.16中,

如果crypt()在你的系统上不可用,ENCRYPT()总是返回NULLENCRYPT()只保留str起始8个字符而忽略所有其他,至少在某些系统上是这样。这将由底层的crypt()系统调用的行为决定。



。结果是一个二进制字符串,如果你想要在列中保存它,使用一个


作为口令解密加密的字符串



对字符串计算MD5校验和。值作为一个32长的十六进制数字被返回可以,例如用作哈希(hash)键。
这是一个“RSA数据安全公司的MD5消息摘要算法”。

列的最后一个自动产生的值。见

产生的最后ID以每个连接为基础在服务器被维护,它不会被其他客户改变。如果你更新另外一个有非魔术值(即,不是NULL和不是0的一个值)的AUTO_INCREMENT列,它甚至不会被改变。如果expr作为一个参数在一个UPDATE子句的LAST_INSERT_ID()里面给出,那么参数值作为一个LAST_INSERT_ID()值被返回。这可以用来模仿顺序:首先创建表:
然后表能被用来产生顺序号,象这样:
你可以不调用LAST_INSERT_ID()而产生顺序,但是这样使用函数的实用程序在服务器上自动维护ID值作为最后自动产生的值。你可以检索新的ID值,就像你能读入正常MySQL中的任何正常的AUTO_INCREMENT值一样。例如,LAST_INSERT_ID()(没有一个参数




0
,结果将没有小数点和小数部分。
 

服务器版本的一个字符串。

给定的一个名字的锁定,第二个
为超时。如果锁定成功获得,返回
,如果尝试超时了,返回 0
,或如果发生一个错误,返回
(例如从存储器溢出或线程用


或线程终止时,一个锁定被释放。该函数可以用来实现应用锁或模拟记录锁,它阻止其他客户用同样名字的锁定请求;赞成一个给定的锁定字符串名字的客户可以使用字符串执行子协作建议的锁定。
 



获得的锁。如果锁被释放,返回
,如果锁没被这个线程锁定(在此情况下锁没被释放)返回 0
,并且如果命名的锁不存在,返回
。如果锁从来没有通过调用
获得或如果它已经被释放了,锁将不存在。

Times次执行表达式

处理表达式有多快。结果值总是 0

客户,它报告查询的执行时间。
 
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。

  
 
如果你在不包含GROUP BY子句的一个语句中使用聚合函数,它等价于聚合所有行。



COUNT(*)在它返回的检索出来的行数目上有些不同,不管他们是否包含NULL值。如果SELECT从一个表检索,或没有检索出其他列并且没有WHERE子句,COUNT(*)被优化以便快速地返回。例如:
返回一个不同值的数目。
MySQL中,你可以通过给出一个表达式列表以得到不同的表达式组合的数目。在 ANSI SQL中,你可能必须在CODE(DISTINCT ..)内进行所有表达式的连接。





可以有一个字符串参数;在这种的情况下,他们返回最小或最大的字符串值。

的和。注意,如果返回的集合没有行,它返回NULL!


是提供与Oracle的兼容性。

里所有位的位或。计算用 64 位(


里所有位的位与。计算用 64 位(

BY部分的SELECT表达式中使用列或计算,这表示这个组的任何可能值。你可以使用它是性能更好,避免在不必要的项目上排序和分组。例如,你在下列查询中不需要在customer.name上聚合:

如果你从GROUP BY部分省略的列在组中不是唯一的,不要使用这个功能。
在某些情况下,你可以使用MIN()MAX()获得一个特定的列值,即使它不是唯一的。下例给出从包含sort列中最小值的行的column值:
BY子句中使用表达式。你可以通过使用表达式的一个别名解决此限制:
MySQL3.23中,你可以这样做:
}

我要回帖

更多关于 mysql 整型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信