本节描述在使用2位数时可能出现的问题(2)
数据类型,并提供有关转换现有数据的信息(2)
列到4位年份值列,可以声明为一年
隐式显示宽度为4个字符,或等效为(4)
具有显式显示宽度。
虽然内部范围的值为一年
/(4)
和弃用(2)
类型相同(1901
来2155
,0000
)的显示宽度(2)
使该类型具有固有的模糊性,因为显示的值只指示内部值的最后两位数字,而忽略世纪数字。在某些情况下,结果可能是信息的丢失。因此,请避免使用(2)
在您的应用和使用中一年
/(4)
只要您需要年份值的数据类型。从MySQL 5.7.5开始,支持(2)
已删除和现有的2位数(2)
列必须转换为4位数字一年
列重新变得可用。
的问题(2)
数据类型包括显示值的模糊性,以及转储、重新加载或转换为字符串时可能丢失的信息。
显示
(2)
值可能是模糊的。最多可以有三个人(2)
具有不同内部值的值具有相同的显示值,如下例所示:CREATE TABLE t (y2 YEAR(2), y4 YEAR);mysql> INSERT INTO t (y2) VALUES(1912),(2012),(2112);查询OK, 3 rows affected (0.00 sec) Records: 3 duplicate: 0 Warnings: 0 mysql> UPDATE t SET y4 = y2;查询OK, 3 rows affected (0.00 sec) rows matched: 3 Changed: 3 Warnings: 0 mysql> SELECT * FROM t;+------+------+ | y2 | y4 | +------+------+ | 12 | 1912 | | 2012 | | | | 2112 | +------+------+ 3行集(0.00秒)
如果你使用, mysqldump要转储上例中创建的表,转储文件代表所有
y2
使用相同的2位数表示的值(12
).如果从转储文件重新加载表,所有结果行都有内部值2012
和显示值12
,从而失去了它们之间的区别。2位或4位数字的转换
一年
数据值以字符串形式使用数据类型显示宽度。假设一个(2)
列和一个一年
/(4)
列都包含该值1970
.将每个列分配给字符串会得到值“70”
或“1970”
,分别。也就是说,信息的丢失发生在从(2)
字符串。
在MySQL 5.7.5之前,支持(2)
是减少的。从MySQL 5.7.5开始,支持(2)
是删除。
(2)
新表的列定义会产生警告或错误:在MySQL 5.7.5之前,
(2)
转换新表的列定义(使用ER_INVALID_YEAR_COLUMN_LENGTH
警告)的四位一年
列:CREATE TABLE t1 (y YEAR(2));查询好,0行影响,1警告(0.04秒)mysql >显示警告\ G *************************** 1。行 *************************** 级别:警告代码:1818年(2)列类型信息:弃用。改为创建YEAR(4)列。1行组(0.00秒)mysql >显示创建表t1 \ G *************************** 1。Create Table ' t1 ' (' y ' year(4) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
从MySQL 5.7.5开始,
(2)
新表的列定义生成ER_INVALID_YEAR_COLUMN_LENGTH
错误:CREATE TABLE t1 (y YEAR(2));错误1818 (HY000):只支持YEAR或YEAR(4)列。
-
ALTER TABLE
导致表重新构建的语句。mysql_upgrade(它使用
修理表
).倾销与, mysqldump以及重新加载转储文件。与前面三项执行的转换不同,转储和重新加载有可能更改数据值。
MySQL升级通常至少涉及后两项中的一项。然而,关于
(2)
,mysql_upgrade比, mysqldump,如前所述,它可以更改数据值。
将便是(2)
列4位一年
列,您可以在任何时候手动这样做,而无需升级。或者,您可以升级到一个版本的MySQL,减少或删除支持(2)
(MySQL 5.6.6或更高版本),然后有MySQL转换(2)
自动列。在后一种情况下,避免通过转储和重新加载数据进行升级,因为这可能会改变数据值。此外,如果使用复制,则必须考虑一些升级注意事项。
将便是(2)
列4位一年
手动,使用ALTER TABLE
或修理表
.假设有一张表t1
有这样的定义:
CREATE TABLE t1 (ycol YEAR(2) NOT NULL DEFAULT '70');
使用以下命令修改列ALTER TABLE
如下:
修改表t1 FORCE;
的ALTER TABLE
语句在不更改的情况下转换表(2)
值。如果服务器是复制源,则ALTER TABLE
语句复制到副本,并在每个副本上进行相应的表更改。
另一种迁移方法是执行二进制升级:在不转储和重新加载数据的情况下就地升级MySQL。然后运行mysql_upgrade,它使用修理表
将便是(2)
列4位一年
列,而不更改数据值。如果服务器是复制源,则修理表
语句复制到副本,并对每个副本进行相应的表更改,除非您调用mysql_upgrade与——skip-write-binlog
选择。
对复制服务器的升级通常包括将副本升级到MySQL的新版本,然后升级源。例如,如果源和副本都运行MySQL 5.5,典型的升级顺序包括将副本升级到5.6,然后将源升级到5.6。关于不同的处理(2)
从MySQL 5.6.6开始,这个升级序列会导致一个问题:假设副本已经升级,但源还没有升级。然后创建一个包含2位数字的表(2)
列的结果是一个包含4位数字的表一年
列。因此,如果使用基于语句的复制,以下操作对源和副本的结果是不同的:
为了避免这样的问题,修改所有的2位数(2)
源上的列为4位数一年
列在升级之前。(使用ALTER TABLE
,如前所述。)这使得正常升级(首先是副本,然后是源代码)成为可能,而不引入任何东西(2)
来(4)
源和副本之间的差异。
应该避免的一种迁移方法是:不要用, mysqldump升级后重新加载转储文件。这种情况有可能改变(2)
值,如前所述。