Will the following table behave or perform any differently
CREATE TABLE t1 (
foo char(60) COLLATE utf8_bin,
bar char(64) COLLATE utf8_bin,
baz char(80) COLLATE utf8_bin
) DEFAULT CHARSET=utf8;
than this table
CREATE TABLE t2 (
foo char(60),
bar char(64),
baz char(80)
) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
I ask this because when I run SHOW CREATE TABLE mysql.db
it shows up with the marker on every column (as in t1
), and on the table (as in t2
). I don't ever add DEFAULT COLLATE
when I create tables. I'm wondering why the system tables have this option set.
-
Hi Evan. If you haven't seen, I expanded my answer a little.Solomon Rutzky– Solomon Rutzky2019年06月10日 16:33:43 +00:00Commented Jun 10, 2019 at 16:33
2 Answers 2
In their current form: the behavior and performance of
t1
andt2
should be identical,and:
IF a string column is added that does not specify either
CHARSET
orCOLLATE
clauses: the behavior and performance will be different. This is due to:new columns in
t2
will beCHARSET=utf8
andCOLLATE=utf8_bin
(because they were specified as defaults for the table), butnew columns in
t1
will beCHARSET=utf8
(because that was specified as default for the table), but will also beCOLLATE=utf8_general_ci
(because this should be the default for theutf8
character set)
Now, I created the two tables as you have them in the question, and that resulted in the following:
SHOW CREATE TABLE t1;
CREATE TABLE `t1` (
`foo` char(60) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`bar` char(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`baz` char(80) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
and:
SHOW CREATE TABLE t2;
CREATE TABLE `t2` (
`foo` char(60) COLLATE utf8_bin DEFAULT NULL,
`bar` char(64) COLLATE utf8_bin DEFAULT NULL,
`baz` char(80) COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
I'm not sure why CHARACTER SET
became explicitly stated in the stored version of the CREATE TABLE t1
statement, but I think I know why COLLATE
did for CREATE TABLE t2
: once you submit the statement, that's what it gets translated into as it's being processed. Why just the COLLATE
statement and not also CHARACTER SET
? That is most likely due to character sets working with 1 or more collations, so specifying the character set does not imply the collation. On the other hand, a collation works with only 1 character set, so specifying the collation does imply the character set. Yes, character sets have default collations, but defaults can change over time or between contexts. Yes, there are defaults explicitly declared for the table, but what if a) the table defaults aren't respected, and/or b) whatever is reading the DDL wants to know everything about a column as it parses the column, as opposed to needing to read the full table DDL first and potentially go back to apply defaults. Adding the COLLATE
clauses makes the operation very clear and unambiguous.
Also, the documentation for CREATE TABLE Statement Retention states:
The original
CREATE TABLE
statement, including all specifications and table options are stored by MySQL when the table is created. The information is retained so that if you change storage engines, collations or other settings using anALTER TABLE
statement, the original table options specified are retained. This enables you to change betweenInnoDB
andMyISAM
table types even though the row formats supported by the two engines are different.
I tested this on db<>fiddle against MariaDB 10.2 and 10.3. and MySQL 5.6, 5.7, and 8.0, and the behavior was the same across all of them.
No, I believe it's the same (assuming no one else answers differently). From the docs
The table character set and collation are used as default values for column definitions if the column character set and collation are not specified in individual column definitions. The table character set and collation are MySQL extensions; there are no such things in standard SQL.
Explore related questions
See similar questions with these tags.