ALTER DATABASE 是一个数据库管理命令,主要用于修改或更改已存在数据库的各种属性和配置。
ALTER {DATABASE | SCHEMA} [db_name]
alter_option ...
ALTER {DATABASE | SCHEMA} db_name
UPGRADE DATA DIRECTORY NAME
alter_option: {
[DEFAULT] CHARACTER SET [=] charset_name
| [DEFAULT] COLLATE [=] collation_name
}
ALTER DATABASE
允许您修改数据库的整体特性。这些特性被保存在数据库目录中的db.opt
文件里。这意味着,当您使用ALTER DATABASE
命令更改某些设置时,这些更改会被记录在db.opt
文件中,以便数据库系统能够在后续启动时恢复这些设置。
执行ALTER DATABASE
语句需要对数据库拥有ALTER
权限。ALTER SCHEMA
是ALTER DATABASE
的同义词。这意味着,当使用 ALTER SCHEMA
语句时,实际上是在执行与 ALTER DATABASE
相同的操作。
如果在ALTER DATABASE
语句中省略了数据库名,并且当前会话有默认数据库,则该语句将应用于默认数据库。但是,如果会话中没有设置默认数据库,并且您尝试省略数据库名执行 ALTER DATABASE
语句,数据库管理系统将无法确定您想要修改哪个数据库,并会返回一个错误。
1 字符集和校对选项
要查看可用的字符集和校对规则,可以使用 SHOW CHARACTER SET
和 SHOW COLLATION
语句。这些语句会列出数据库管理系统支持的所有字符集和相应的校对规则。
CHARACTER SET (字符集)子句
用于更改数据库的默认字符集。字符集是一组字符的编码,它决定了如何将文本数据转换为二进制数据以存储在数据库中。
SHOW {CHARACTER SET | CHARSET}
[LIKE 'pattern' | WHERE expr]
SHOW CHARACTER SET
语句用于显示所有可用的字符集。如果存在 LIKE
子句,它将指示要匹配的字符集名称。WHERE
子句可用于根据更一般的条件选择行,例如:
mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |
+---------+-----------------------------+-------------------+--------+
SHOW CHARACTER SET
命令的输出包含以下列:
-
Charset:字符集名称。
-
Description:字符集的描述。
-
Default collation:该字符集的默认校对规则。
-
Maxlen:存储一个字符所需的最大字节数。
"文件名字符集"是仅供内部使用的,因此 SHOW CHARACTER SET
命令不会显示它。
字符集信息也可以从 INFORMATION_SCHEMA
数据库中的 CHARACTER_SETS
表获取。这个表提供了与 SHOW CHARACTER SET
类似的信息,但可以通过 SQL 查询进行更复杂的分析和操作。
COLLATE(校对) 子句
用于更改数据库的默认校对规则。校对规则决定了如何比较和排序字符串。不同的校对规则可能会对相同的字符集有不同的排序和比较行为。
SHOW COLLATION
[LIKE 'pattern' | WHERE expr]
SHOW COLLATION
语句列出了服务器支持的所有校对规则(collation)。默认情况下,SHOW COLLATION
的输出包括所有可用的校对规则。可以使用 LIKE
子句来指定要匹配的校对规则名称模式。此外,也可以使用 WHERE
子句来根据更一般的条件选择行。例如:
mysql> SHOW COLLATION WHERE Charset = 'latin1';
+-------------------+---------+----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1 | 5 | | Yes | 1 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 |
| latin1_danish_ci | latin1 | 15 | | Yes | 1 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 1 |
| latin1_general_ci | latin1 | 48 | | Yes | 1 |
| latin1_general_cs | latin1 | 49 | | Yes | 1 |
| latin1_spanish_ci | latin1 | 94 | | Yes | 1 |
+-------------------+---------+----+---------+----------+---------+
SHOW COLLATION
的输出包含以下列:
-
Collation:校对规则(collation)的名称。
-
Charset:与该校对规则关联的字符集(character set)的名称。
-
Id:校对规则的 ID。
-
Default:指示该校对规则是否是其字符集的默认校对规则。这通常是一个字符串,如 "Yes" 或 "No",但在某些数据库系统中可能是一个布尔值或数字。
-
Compiled:指示字符集是否已编译到服务器中。这通常是一个表示"是"或"否"的字符串,表明字符集是否是预编译的,或者是否在运行时动态加载。
-
Sortlen:这与使用该字符集表达的字符串排序所需的内存量有关。它通常表示排序算法在内部处理字符串时所需的最大字节数。
要查看每个字符集的默认校对规则,你可以使用以下 SQL 语句。
请注意,由于 Default
是一个保留字,所以当你将其作为标识符使用时,需要用反引号(`)将其括起来。如下所示:
mysql> SHOW COLLATION WHERE `Default` = 'Yes';
+---------------------+----------+----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+---------------------+----------+----+---------+----------+---------+
| big5_chinese_ci | big5 | 1 | Yes | Yes | 1 |
| dec8_swedish_ci | dec8 | 3 | Yes | Yes | 1 |
| cp850_general_ci | cp850 | 4 | Yes | Yes | 1 |
| hp8_english_ci | hp8 | 6 | Yes | Yes | 1 |
| koi8r_general_ci | koi8r | 7 | Yes | Yes | 1 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 |
...
当创建存储过程或函数时,如果这些存储例程中使用了数据库的默认字符集和校对规则,那么这些默认值会成为存储例程定义的一部分。在存储例程中,如果字符变量没有明确指定字符集或校对规则,那么它们会使用数据库的默认值。
重要的一点是,如果更改了数据库的默认字符集或校对规则,任何想要使用新默认值的存储例程都必须被删除并重新创建。这是因为存储例程在创建时已经固定了其使用的字符集和校对规则,不会自动跟随数据库默认值的更改而更新。因此,为了确保存储例程使用新的字符集和校对规则,需要重新创建这些例程。
2 Upgrading from Versions Older than MySQL 5.1
UPGRADE DATA DIRECTORY NAME
是 MySQL 中的一个特殊语法,它用于在特定的升级场景下更新与数据库关联的目录名,以确保数据库名到数据库目录名的映射使用 MySQL 5.1 及以后版本中引入的编码。这个语法通常在从较旧的 MySQL 版本升级到 MySQL 5.1 或更高版本时使用,以确保文件系统的兼容性。
具体来说,这个子句在以下条件下使用:
- 当从 MySQL 的旧版本升级到 5.1 或更高版本时,
UPGRADE DATA DIRECTORY NAME
子句用于更新数据库目录名到当前的编码格式,特别是当目录名包含需要编码的特殊字符时。 - 这个子句通常不由用户直接调用,而是由
mysql_upgrade
工具自动使用,该工具在升级过程中调用mysqlcheck
来检查并修复表、更新权限和转换数据库目录名(如果需要)。 - 在升级过程中,
mysql_upgrade
会检查数据目录中的每个数据库,并确定是否需要更新其目录名。如果需要,它会使用UPGRADE DATA DIRECTORY NAME
语句来执行此操作。
例如,MySQL 5.0 中的数据库名为 a-b-c
,对应的数据库目录也是 a-b-c
。此时,数据库名称包含特殊字符(如破折号 -
),那么数据库目录将直接使用这个名称,这可能在某些文件系统中引发问题,因为不是所有文件系统都支持在文件名中使用这些特殊字符。然而,在 MySQL 5.1 及更高版本中,为了提高兼容性和安全性,数据库名称中的特殊字符会被转换成一种编码形式,这样生成的目录名对所有文件系统都是中立的。因此,在 MySQL 5.1 及之后的版本中,数据库名 a-b-c
会被编码为 a@002db@002dc
,其中 @002d
是破折号 -
的十六进制 Unicode 编码。
在 MySQL 升级过程中,从旧版本升级到 5.1 或更高版本时,为了保持向后兼容性,服务器会将旧格式的数据库名(如 a-b-c
)显示为带有 #mysql50#
前缀的名称(如 #mysql50#a-b-c
)。这是为了确保在升级过程中,旧的应用程序或工具可以继续访问和引用这些数据库,尽管它们使用的是旧的命名格式。
然而,一旦升级完成,并且你确信所有的应用程序和工具都已经更新为使用新的 MySQL 版本,那么你可能希望将数据库目录名从带有 #mysql50#
前缀的旧格式转换为新的编码格式。这时,你可以使用 UPGRADE DATA DIRECTORY NAME
语句来显式地告诉服务器重新编码数据库目录名到当前的编码格式。
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
执行此语句后,您可以将数据库引用为a-b-c,而不需要特殊的#mysql50#前缀。
注意:
UPGRADE DATA DIRECTORY NAME子句在MySQL 5.7中被弃用,在MySQL 8.0中被删除。如果需要转换MySQL 5.0数据库或表名,解决方法是在升级到MySQL 8.0之前将MySQL 5.0安装升级到MySQL 5.1。