Spec-Zone .ru
спецификации, руководства, описания, API
|
Although the internal range of values for YEAR(4)
and YEAR(2)
is the same (1901
to 2155
, and 0000
), the display width for YEAR(2)
makes that type inherently ambiguous because displayed values
indicate only the last two digits of the internal values. The result can be a loss of information under certain
circumstances. For this reason, consider avoiding YEAR(2)
throughout your applications and using YEAR(4)
wherever you need a YEAR
data type. This section describes problems that can occur when using YEAR(2)
and provides information about migrating existing YEAR(2)
columns to YEAR(4)
.
Note that migration will become necessary at some point because support for YEAR
data types with display values other than 4, most notably YEAR(2)
, is reduced as of MySQL 5.6.6 and will be removed entirely in a
future release.
YEAR(2)
Limitations Issues with the YEAR(2)
data type include ambiguity of displayed values, and possible loss of information when values are dumped and
reloaded or converted to strings.
Displayed YEAR(2)
values can be ambiguous. It is possible for up to three YEAR(2)
values that have different internal values to have the same
displayed value, as the following example demonstrates:
mysql>CREATE TABLE t (y2 YEAR(2), y4 YEAR(4));
Query OK, 0 rows affected (0.01 sec)mysql>INSERT INTO t (y2) VALUES(1912),(2012),(2112);
Query OK, 3 rows affected (0.00 sec)Records: 3 Duplicates: 0 Warnings: 0mysql>UPDATE t SET y4 = y2;
Query OK, 3 rows affected (0.00 sec)Rows matched: 3 Changed: 3 Warnings: 0mysql>SELECT * FROM t;
+------+------+| y2 | y4 |+------+------+| 12 | 1912 || 12 | 2012 || 12 | 2112 |+------+------+3 rows in set (0.00 sec)
If you use mysqldump to dump the table created in the preceding
item, the dump file represents all y2
values using the same 2-digit
representation (12
). If you reload the table from the dump file, all
resulting rows have internal value 2012
and display value 12
, thus losing the distinctions among them.
Conversion of a YEAR(2)
or YEAR(4)
data value to string form uses the display width of the YEAR
type. Suppose that YEAR(2)
and YEAR(4)
columns both contain the value 1970
. Assigning each column to a string
results in a value of '70'
or '1970'
,
respectively. That is, loss of information occurs for conversion from YEAR(2)
to string.
Values outside the range from 1970
to 2069
are stored incorrectly when inserted into a YEAR(2)
column in a CSV
table. For example, inserting 2111
results in a display value of 11
but an internal value of 2011
.
To avoid these problems, use YEAR(4)
rather than YEAR(2)
.
Suggestions regarding migration strategies appear later in this section.
YEAR(2)
Support in MySQL 5.6 As of MySQL 5.6.6, support for YEAR(2)
is diminished:
YEAR(2)
in column definitions for new tables is converted (with a
warning) to YEAR(4)
:
mysql>CREATE TABLE t1 (y YEAR(2));
Query OK, 0 rows affected, 1 warning (0.03 sec)mysql>SHOW WARNINGS\G
*************************** 1. row *************************** Level: Warning Code: 1818Message: YEAR(2) column type is deprecated. Creating YEAR(4) column instead.1 row in set (0.00 sec)mysql>SHOW CREATE TABLE t1\G
*************************** 1. row *************************** Table: t1Create Table: CREATE TABLE `t1` ( `y` year(4) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin11 row in set (0.00 sec)
YEAR(2)
in existing tables remains as YEAR(2)
and is processed in queries as in older versions of MySQL.
However, several programs or statements convert YEAR(2)
to YEAR(4)
automatically:
ALTER
TABLE
statements that result in a table rebuild.
REPAIR
TABLE
(which CHECK
TABLE
recommends you use if it finds that a table contains YEAR(2)
columns).
mysql_upgrade (which uses REPAIR TABLE
).
Dumping with mysqldump and reloading the dump file. Unlike the conversions performed by the preceding three items, a dump and reload has the potential to change values.
A MySQL upgrade usually involves at least one of the last two items. However, with respect to YEAR(2)
,
you should avoid dumping and reloading; as noted, that can change values.
YEAR(2)
to YEAR(4)
Should you decide to convert YEAR(2)
columns to YEAR(4)
, you can do so manually at any time without upgrading. Alternatively, you
can upgrade to a version of MySQL with reduced support for YEAR(2)
(MySQL 5.6.6 or later), then have MySQL convert YEAR(2)
columns automatically. In the latter case, avoid upgrading by dumping
and reloading your data because that can change data values. In addition, if you use replication, there are
upgrade considerations you must take into account.
To convert YEAR(2)
columns to YEAR(4)
manually, use ALTER TABLE
. Suppose that a table t1
has this
definition:
CREATE TABLE t1 (ycol YEAR(2) NOT NULL DEFAULT '70');
Modify the column using ALTER TABLE
as follows. Remember to include any column
attributes such as NOT NULL
or DEFAULT
:
ALTER TABLE t1 MODIFY ycol YEAR(4) NOT NULL DEFAULT '1970';
The ALTER
TABLE
statement converts the table without changing YEAR(2)
values. If the server is a replication master, the ALTER TABLE
statement replicates to slaves and makes the corresponding table
change on each one.
Another migration method is to perform a binary upgrade: Install MySQL 5.6.6 or later without dumping and
reloading your data. Then run mysql_upgrade, which uses REPAIR TABLE
to convert YEAR(2)
columns to YEAR(4)
without changing data values. If the server is a replication master, the REPAIR TABLE
statements replicate to slaves and make the corresponding table
changes on each one, unless you invoke mysql_upgrade with the --skip-write-binlog
option.
Upgrades to replication servers usually involve upgrading slaves to a newer version of MySQL, then upgrading the
master. For example, if a master and slave both run MySQL 5.5, a typical upgrade sequence involves upgrading the
slave to 5.6, then upgrading the master to 5.6. With regard to the different treatment of YEAR(2)
as of MySQL 5.6.6, that upgrade sequence results in a problem:
Suppose that the slave has been upgraded but not yet the master. Then creating a table containing a YEAR(2)
column on the master results in a table containing a YEAR(4)
column on the slave. Consequently, these operations will have a
different result on the master and slave, if you use statement-based replication:
To avoid such problems, use one of these strategies:
Use row-based replication instead of statement-based replication.
Modify all YEAR(2)
columns on the master to YEAR(4)
before upgrading. (Use ALTER TABLE
, as described previously.) Then you can upgrade normally
(slave first, then master) without introducing any YEAR(2)
to YEAR(4)
differences between the master and slave).
One migration method should be avoided: Do not dump your data with mysqldump and reload the dump file after upgrading. This has the
potential to change YEAR(2)
values, as described previously.
A migration from YEAR(2)
to YEAR(4)
should also involve examining application code for the possibility of changed behavior under conditions such as
these: