MySQL中ALTER DATABASE语句的使用

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 SCHEMAALTER DATABASE的同义词。这意味着,当使用 ALTER SCHEMA 语句时,实际上是在执行与 ALTER DATABASE 相同的操作。

如果在ALTER DATABASE语句中省略了数据库名,并且当前会话有默认数据库,则该语句将应用于默认数据库。但是,如果会话中没有设置默认数据库,并且您尝试省略数据库名执行 ALTER DATABASE 语句,数据库管理系统将无法确定您想要修改哪个数据库,并会返回一个错误。

1 字符集和校对选项

要查看可用的字符集和校对规则,可以使用 SHOW CHARACTER SETSHOW 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。

相关推荐
做梦敲代码11 分钟前
达梦数据库-读写分离集群部署
数据库·达梦数据库
苹果醋31 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
hanbarger1 小时前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
微服务 spring cloud1 小时前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡1 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷1 小时前
Redis
数据库·redis·缓存
仰望大佬0072 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
学不透java不改名2 小时前
sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示
数据库