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: 0 mysql>UPDATE t SET y4 = y2;Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql>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: 1818 Message: 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: t1 Create Table: CREATE TABLE `t1` ( `y` year(4) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 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:

User Comments
Add your own comment.