MySQL 8.0 参考手册  / 第9章语言结构  / 9.2 模式对象名称  /  9.2.4 标识符到文件名的映射

9.2.4 标识符到文件名的映射

文件系统中的数据库和表标识符和名称之间存在对应关系。对于基本结构,MySQL 将每个数据库表示为数据目录中的一个目录,而每个表由相应数据库目录中的一个或多个文件表示。对于表格式文件 ( .FRM),数据始终存储在此结构和位置中。

对于数据和索引文件,磁盘上的确切表示是特定于存储引擎的。这些文件可能存储在与FRM文件相同的位置,或者信息可能存储在单独的文件中。 InnoDB数据存储在 InnoDB 数据文件中。如果您将表空间与 一起使用 InnoDB,则会改用您创建的特定表空间文件。

X'00'除 ASCII NUL ( ) 外,任何字符在数据库或表标识符中都是合法的。MySQL 在创建数据库目录或表文件时对相应文件系统对象中有问题的任何字符进行编码:

  • 基本拉丁字母 ( a..zA..Z)、数字 ( 0..9) 和下划线 ( _) 按原样编码。因此,它们的大小写敏感性直接取决于文件系统特性。

  • 具有大写/小写映射的字母表中的所有其他国家字母的编码如下表所示。代码范围列中的值是 UCS-2 值。

    代码范围 图案 数字 用过的 没用过 积木
    00C0..017F [@][0..4][g..z] 5*20=100 97 3个 Latin-1 补充 + Latin Extended-A
    0370..03FF [@][5..9][g..z] 5*20=100 88 12 希腊语和科普特语
    0400..052F [@][g..z][0..6] 20*7=140 137 3个 西里尔字母 + 西里尔字母增补
    0530..058F [@][g..z][7..8] 20*2=40 38 2个 亚美尼亚语
    2160..217F [@][g..z][9] 20*1=20 16 4个 数字形式
    0180..02AF [@][g..z][a..k] 20*11=220 203 17 拉丁语扩展 B + IPA 扩展
    1E00..1EFF [@][g..z][l..r] 20*7=140 136 4个 拉丁扩展附加
    1F00..1FFF [@][g..z][s..z] 20*8=160 144 16 希腊扩展
    ………… [@][a..f][g..z] 6*20=120 0 120 预订的
    24B6..24E9 [@][@][a..z] 26 26 0 封闭的字母数字
    FF21..FF5A [@][a..z][@] 26 26 0 半角和全角形式

    序列中的一个字节编码字母大小写。例如:LATIN CAPITAL LETTER A WITH GRAVE被编码为@0G,而LATIN SMALL LETTER A WITH GRAVE 被编码为@0g. 这里的第三个字节(Gg)表示字母大小写。(在不区分大小写的文件系统上,两个字母被视为相同。)

    对于某些块,例如西里尔字母,第二个字节决定字母大小写。对于其他块,例如 Latin1 Supplement,第三个字节决定字母大小写。如果序列中的两个字节是字母(如 Greek Extended),则最左边的字母字符代表字母大小写。所有其他字母字节必须小写。

  • 除了下划线 ( _) 之外的所有非字母字符,以及没有大写/小写映射的字母表中的字母(例如希伯来语)都使用十六进制表示法进行编码,使用小写字母表示十六进制数字 a..f

    0x003F -> @003f
    0xFFFF -> @ffff

    十六进制值对应于 ucs2双字节字符集中的字符值。

在 Windows 上,某些名称(例如nulprn和)在服务器创建相应文件或目录时aux通过附加到名称进行编码。@@@这发生在所有平台上,以实现平台之间相应数据库对象的可移植性。

如果您的 MySQL 版本早于 5.1.6 的数据库或表包含特殊字符,并且其底层目录名或文件名尚未更新为使用新编码,则服务器会显示其名称前缀为#mysql50#inINFORMATION_SCHEMA表或 SHOW语句的输出 。例如,如果您有一个名为的表a@b并且其名称编码尚未更新,SHOW TABLES则显示如下:

mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| #mysql50#a@b   |
+----------------+

要引用尚未更新编码的此类名称,您必须提供#mysql50# 前缀:

mysql> SHOW COLUMNS FROM `a@b`;
ERROR 1146 (42S02): Table 'test.a@b' doesn't exist

mysql> SHOW COLUMNS FROM `#mysql50#a@b`;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

要更新旧名称以消除使用特殊前缀来引用它们的需要,请使用 mysqlcheck重新编码它们。以下命令将所有名称更新为新编码:

mysqlcheck --check-upgrade --all-databases
mysqlcheck --fix-db-names --fix-table-names --all-databases

要仅检查特定的数据库或表,请省略 --all-databases并提供适当的数据库或表参数。有关mysqlcheck调用语法的信息,请参阅 第 4.5.3 节,“mysqlcheck — 表维护程序”

笔记

#mysql50#前缀仅供服务器内部使用。您不应创建名称使用此前缀的数据库或表。

此外,mysqlcheck无法修复包含@ 用于编码特殊字符的字符的文字实例的名称。如果您有包含该字符的数据库或表,请在升级到 MySQL 5.1.6 或更高版本之前使用 mysqldump转储它们,然后在升级后重新加载转储文件。

笔记

不推荐将包含特殊字符的 MySQL 5.1 之前的数据库名称转换为带有 #mysql50#前缀的 5.1 格式;希望在未来的 MySQL 版本中将其删除。因为此类转换已弃用,所以 mysqlcheck--fix-db-names的和 --fix-table-names选项以及语句的子句 也已弃用。 UPGRADE DATA DIRECTORY NAMEALTER DATABASE

仅支持从一个版本系列升级到另一个版本系列(例如,5.0 到 5.1,或 5.1 到 5.5),因此几乎不需要将旧的 5.0 数据库名称转换为当前版本的 MySQL。解决方法是先将 MySQL 5.0 安装升级到 MySQL 5.1,然后再升级到更新的版本。