将列排序规则转换为表/数据库默认值

时间:2015-06-15 17:27:29

标签: mysql database

我见过的每一篇关于SO的帖子都表明要运行以下SQL:

ALTER TABLE <tablename> CONVERT TO CHARACTER SET utf8  COLLATE utf8_unicode_ci;

除非我弄错了,否则它的问题在于它明确指定了列排序规则,所以当你mysqldump数据库时你会得到类似的东西:

  `address` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
  `city` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `state` varchar(2) COLLATE utf8_unicode_ci DEFAULT NULL,
  `zipcode` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,

我的问题是..如果没有这样做,是否无法将列排序规则转换为表或数据库默认值?

例如,我的表格可能如下所示:

  `address` varchar(150) DEFAULT NULL,
  `city` varchar(100) DEFAULT NULL,
  `state` varchar(2) COLLATE utf8_general_ci DEFAULT NULL,
  `zipcode` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,

我想要的是将所有列转换为utf8_unicode_ci(表/数据库默认值),但不要将每列显式设置为该排序规则,这样当我mysqldump转换后的表时,它看起来就像这样:

  `address` varchar(150) DEFAULT NULL,
  `city` varchar(100) DEFAULT NULL,
  `state` varchar(2) DEFAULT NULL,
  `zipcode` varchar(10) DEFAULT NULL,

在表创建语句末尾有一行,用于定义默认字符集和排序规则:ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

3 个答案:

答案 0 :(得分:4)

如果您的表或列与MySQL默认值不同,在我的情况下为latin1_sweedish_ci,那么它将打印出与该列的排序规则。请参阅以下实验来说明这一点。

要设置默认字符集,请参阅this post

首先,让我们创建一个包含两个表的数据库。一个表具有指定的字符集和排序规则。

mysql> create database SO;
mysql> use SO;
mysql> create table test1 (col1 text, col2 text);
mysql> create table test2 (col1 text, col2 text) character set utf8 collate utf8_unicode_ci;

现在检查show create table以查看它的外观:

mysql> show create table test1;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test1 | CREATE TABLE `test1` (
      `col1` text,
      `col2` text
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    +-------+-----------------+
    1 row in set (0.00 sec)

mysql> show create table test2;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test2 | CREATE TABLE `test2` (
      `col1` text COLLATE utf8_unicode_ci,
      `col2` text COLLATE utf8_unicode_ci
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    +-------+-----------------+
    1 row in set (0.00 sec)

我们看到test2看起来已经专门指定了列,而不是使用默认值。我怀疑它是否与MySQL默认不同,它会列出它,而不是它与表默认值不同。现在让我们看看它们在information_schema数据库中的外观。

mysql> select table_schema, table_name, table_collation from information_schema.tables where table_schema = 'SO';
    +--------------+------------+-------------------+
    | table_schema | table_name | table_collation   |
    +--------------+------------+-------------------+
    | SO           | test1      | latin1_swedish_ci |
    | SO           | test2      | utf8_unicode_ci   |
    +--------------+------------+-------------------+
    2 rows in set (0.00 sec)

mysql> select table_schema, table_name, column_name, character_set_name, collation_name from information_schema.columns where table_schema = 'SO';
    +--------------+------------+-------------+--------------------+-------------------+
    | table_schema | table_name | column_name | character_set_name | collation_name    |
    +--------------+------------+-------------+--------------------+-------------------+
    | SO           | test1      | col1        | latin1             | latin1_swedish_ci |
    | SO           | test1      | col2        | latin1             | latin1_swedish_ci |
    | SO           | test2      | col1        | utf8               | utf8_unicode_ci   |
    | SO           | test2      | col2        | utf8               | utf8_unicode_ci   |
    +--------------+------------+-------------+--------------------+-------------------+
    4 rows in set (0.00 sec)

看起来这些列具有特定的字符集和排序规则,无论我们是否指定它。让我们将test1更新为首选字符集和整理,看看会发生什么。

mysql> ALTER TABLE test1 CONVERT TO CHARACTER SET utf8  COLLATE utf8_unicode_ci;
    Query OK, 0 rows affected (0.05 sec)
    Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table test1;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test1 | CREATE TABLE `test1` (
      `col1` mediumtext COLLATE utf8_unicode_ci,
      `col2` mediumtext COLLATE utf8_unicode_ci
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    +-------+-----------------+
    1 row in set (0.00 sec)

mysql> show create table test2;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test2 | CREATE TABLE `test2` (
      `col1` text COLLATE utf8_unicode_ci,
      `col2` text COLLATE utf8_unicode_ci
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    +-------+-----------------+
    1 row in set (0.00 sec)

现在他们都将整理放在show create table语句中。让我们再次检查information_schema。

mysql> select table_schema, table_name, table_collation from information_schema.tables where table_schema = 'SO';
    +--------------+------------+-----------------+
    | table_schema | table_name | table_collation |
    +--------------+------------+-----------------+
    | SO           | test1      | utf8_unicode_ci |
    | SO           | test2      | utf8_unicode_ci |
    +--------------+------------+-----------------+
    2 rows in set (0.00 sec)

mysql> select table_schema, table_name, column_name, character_set_name, collation_name from information_schema.columns where table_schema = 'SO';
    +--------------+------------+-------------+--------------------+-----------------+
    | table_schema | table_name | column_name | character_set_name | collation_name  |
    +--------------+------------+-------------+--------------------+-----------------+
    | SO           | test1      | col1        | utf8               | utf8_unicode_ci |
    | SO           | test1      | col2        | utf8               | utf8_unicode_ci |
    | SO           | test2      | col1        | utf8               | utf8_unicode_ci |
    | SO           | test2      | col2        | utf8               | utf8_unicode_ci |
    +--------------+------------+-------------+--------------------+-----------------+
    4 rows in set (0.00 sec)

看起来一切都差不多。但是当我们向两个表添加一个额外的列时会发生什么?

mysql> alter table test1 add column col3 text;
    Query OK, 0 rows affected (0.05 sec)
    Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table test2 add column col3 text;
    Query OK, 0 rows affected (0.06 sec)
    Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table test1;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test1 | CREATE TABLE `test1` (
      `col1` mediumtext COLLATE utf8_unicode_ci,
      `col2` mediumtext COLLATE utf8_unicode_ci,
      `col3` text COLLATE utf8_unicode_ci
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    +-------+-----------------+
    1 row in set (0.00 sec)

mysql> show create table test2;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test2 | CREATE TABLE `test2` (
      `col1` text COLLATE utf8_unicode_ci,
      `col2` text COLLATE utf8_unicode_ci,
      `col3` text COLLATE utf8_unicode_ci
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    +-------+-----------------+
    1 row in set (0.00 sec)

在这两种情况下,他们从表中获取了整理。因此,不应该担心以后添加的列是不合适的。让我们再次检查information_schema ......

mysql> select table_schema, table_name, table_collation from information_schema.tables where table_schema = 'SO';
    +--------------+------------+-----------------+
    | table_schema | table_name | table_collation |
    +--------------+------------+-----------------+
    | SO           | test1      | utf8_unicode_ci |
    | SO           | test2      | utf8_unicode_ci |
    +--------------+------------+-----------------+
    2 rows in set (0.00 sec)

mysql> select table_schema, table_name, column_name, character_set_name, collation_name from information_schema.columns where table_schema = 'SO';
    +--------------+------------+-------------+--------------------+-----------------+
    | table_schema | table_name | column_name | character_set_name | collation_name  |
    +--------------+------------+-------------+--------------------+-----------------+
    | SO           | test1      | col1        | utf8               | utf8_unicode_ci |
    | SO           | test1      | col2        | utf8               | utf8_unicode_ci |
    | SO           | test1      | col3        | utf8               | utf8_unicode_ci |
    | SO           | test2      | col1        | utf8               | utf8_unicode_ci |
    | SO           | test2      | col2        | utf8               | utf8_unicode_ci |
    | SO           | test2      | col3        | utf8               | utf8_unicode_ci |
    +--------------+------------+-------------+--------------------+-----------------+
    6 rows in set (0.00 sec)

呀。所有看起来都是以同样的方式工作。但是关于它的假设只是显示它是否与MySQL默认值不同而不是表默认值呢?让我们将test1设置回原来的状态。

mysql> ALTER TABLE test1 CONVERT TO CHARACTER SET latin1  COLLATE latin1_swedish_ci;
    Query OK, 0 rows affected (0.02 sec)
    Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table test1;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test1 | CREATE TABLE `test1` (
      `col1` mediumtext,
      `col2` mediumtext,
      `col3` text
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    +-------+-----------------+
    1 row in set (0.00 sec)

看起来就像我们开始时一样。现在要说明它是MySQL默认值而不仅仅是数据库默认值,让我们设置数据库的默认值。

mysql> Alter database SO default character set utf8 collate utf8_unicode_ci;
    Query OK, 1 row affected (0.00 sec)

mysql> show create table test1;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test1 | CREATE TABLE `test1` (
      `col1` mediumtext,
      `col2` mediumtext,
      `col3` text
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    +-------+-----------------+
    1 row in set (0.00 sec)

mysql> show create table test2;
    +-------+-----------------+
    | Table | Create Table
    +-------+-----------------+
    | test2 | CREATE TABLE `test2` (
      `col1` text COLLATE utf8_unicode_ci,
      `col2` text COLLATE utf8_unicode_ci,
      `col3` text COLLATE utf8_unicode_ci
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    +-------+-----------------+
    1 row in set (0.00 sec)

正如您所看到的,test1在我们第一次启动时仍然看起来像show create table不受数据库默认值的影响。

答案 1 :(得分:0)

我刚做了一些测试,在我看来,如果它与表COLLATE设置不同,那么COLLATE只包含在mysqldump文件中。因此,如果您将列和表更改为相同,则它将不会在mysqldump文件中输出。

使用不同的设置

CREATE TABLE `test` (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `code` varchar(10) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin7;

使用相同的设置(latin7)

CREATE TABLE `test` (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `code` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin7;

这些测试是在同一个表上完成的,只需更改列上的排序规则即可。

答案 2 :(得分:0)

如果将字符集重新定义为其值但未指定排序规则,则会清除排序规则,除非有其他排序规则生效。您可能必须在表格中清除字符集和整理:

select version();
+-----------+
| version() |
+-----------+
| 5.6.17    |
+-----------+


-- start with a table with collation on one column, charset on another
SHOW CREATE TABLE mytable;

CREATE TABLE `mytable` (
  `address` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
  `test` varchar(20) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- By changing charset and specifying no collation, this is cleared
ALTER TABLE mytable MODIFY address varchar(150) CHARACTER SET utf8;

CREATE TABLE `mytable` (
  `address` varchar(150) CHARACTER SET utf8 DEFAULT NULL,
  `test` varchar(20) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- By specifying nothing we get no charset but default collation
ALTER TABLE mytable MODIFY address varchar(150);

CREATE TABLE `mytable` (
  `address` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
  `test` varchar(20) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- changing all the fields at once does not help

成功!

-- So we clear the table AND the fields at the same time (a "change" which is no change at all, really)
ALTER TABLE mytable CHARACTER SET utf8, MODIFY address varchar(150), MODIFY test varchar(20);

SHOW CREATE TABLE mytable;

CREATE TABLE `mytable` (
  `address` varchar(150) DEFAULT NULL,
  `test` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

我还应该注意到我的my.cnf(Linux OpenSuSE 13.2)中有server_character_set = utf8和server_collat​​e = utf8_unicode_ci