10bet网址
MySQL 5.7参考手册
相关的文档10bet官方网站 本手册下载 本手册节选

MySQL 5.7参考手册// 2位数年份的限制和向4位数年份的迁移

11.2.5 2位年份(2)限制和向4位年份迁移

本节描述在使用2位数时可能出现的问题(2)数据类型,并提供有关转换现有数据的信息(2)列到4位年份值列,可以声明为一年隐式显示宽度为4个字符,或等效为(4)具有显式显示宽度。

虽然内部范围的值为一年/(4)和弃用(2)类型相同(19012155,0000)的显示宽度(2)使该类型具有固有的模糊性,因为显示的值只指示内部值的最后两位数字,而忽略世纪数字。在某些情况下,结果可能是信息的丢失。因此,请避免使用(2)在您的应用和使用中一年/(4)只要您需要年份值的数据类型。从MySQL 5.7.5开始,支持(2)已删除和现有的2位数(2)列必须转换为4位数字一年列重新变得可用。

(2)限制

的问题(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)字符串。

  • 范围之外的值19702069插入到(2)CSV表格例如,插入2211的显示值11的内部值2011

为了避免这些问题,请使用4位数一年(4)数据类型而不是2位数(2)数据类型。关于迁移策略的建议将在本节后面介绍。

减少/删除年(2)MySQL 5.7中的支持

在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)列。
  • (2)现有表中的列保持为(2)

    • 在MySQL 5.7.5之前,(2)和旧版本的MySQL一样在查询中处理。

    • 从MySQL 5.7.5开始,(2)查询中的列会产生警告或错误。

  • 几个程序或语句可以转换(2)列4位一年列自动:

    MySQL升级通常至少涉及后两项中的一项。然而,关于(2)mysql_upgrade, mysqldump,如前所述,它可以更改数据值。

从年份(2)迁移到4位数年份

将便是(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位数字的表一年列。因此,如果使用基于语句的复制,以下操作对源和副本的结果是不同的:

  • 插入数字0.结果值的内部值为2000在源头上0000在副本。

  • 转换(2)字符串。该操作使用的显示值(2)在源头上(4)在副本。

为了避免这样的问题,修改所有的2位数(2)源上的列为4位数一年列在升级之前。(使用ALTER TABLE,如前所述。)这使得正常升级(首先是副本,然后是源代码)成为可能,而不引入任何东西(2)(4)源和副本之间的差异。

应该避免的一种迁移方法是:不要用, mysqldump升级后重新加载转储文件。这种情况有可能改变(2)值,如前所述。

从两位数的迁移(2)列4位一年列还应该包括检查应用程序代码在以下情况下改变行为的可能性:

  • 期望选择的代码一年列生成恰好两个数字。

  • 不考虑对数字插入的不同处理的代码0:插入0(2)(4)的内部值的结果20000000,分别。