9.2.4 标识符到文件名的 Map

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

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

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

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

  • 下 table 中显示了来自其他具有大写/小写字母 Map 的其他国家字母的编码。 “代码范围”列中的值为 UCS-2 值。

Code RangePatternNumberUsedUnusedBlocks
00C0..017F[@][0..4][g..z]5*20= 100973拉丁文 1 补充拉丁文 Extended-A
0370..03FF[@][5..9][g..z]5*20= 1008812希腊和科普特人
0400..052F[@][g..z][0..6]20*7= 1401373西里尔文西里尔文补充
0530..058F[@][g..z][7..8]20*2= 40382Armenian
2160..217F[@][g..z][9]20*1= 20164Number Forms
0180..02AF[@][g..z][a..k]20*11=22020317拉丁扩展 B IPA 扩展
1E00..1EFF[@][g..z][l..r]20*7= 1401364拉丁文扩展附加
1F00..1FFF[@][g..z][s..z]20*8= 16014416Greek Extended
.... ....[@][a..f][g..z]6*20= 1200120RESERVED
24B6..24E9[@][@][a..z]26260Enclosed Alphanumerics
FF21..FF5A[@][a..z][@]26260半角和全角形式

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

对于某些块(例如西里尔字母),第二个字节确定字母大小写。对于其他块,例如 Latin1 Supplement,第三个字节确定字母大小写。如果序列中的两个字节为字母(如希腊扩展),则最左边的字母字符代 table 字母大写。所有其他字母字节必须为小写。

  • 除下划线(_)以外的所有非字母字符,以及不具有大写/小写 Map 的字母(例如希伯来语)均使用十六进制 table 示形式编码,十六进制数字a..f则使用小写字母:
0x003F -> @003f
0xFFFF -> @ffff

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

在 Windows 上,当服务器创建相应的文件或目录时,通过在名称后附加@@@来对诸如nulprnaux之类的一些名称进行编码。在所有平台上都会发生这种情况,以实现平台之间相应数据库对象的可移植性。

如果您的 MySQL 或数据库版本早于 5.1.6,但包含特殊字符且其基础目录名称或文件名尚未更新为使用新编码,则服务器将显示其名称,前缀为#mysql50#INFORMATION_SCHEMAtable 或SHOW语句的输出中。例如,如果您有一个名为a@b的 table,并且其名称编码尚未更新,则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

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

Note

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

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

Note

不建议将包含特殊字符的 MySQL 5.1 之前的数据库名称转换为 5.1 格式并添加#mysql50#前缀,并将在 MySQL 的 Future 版本中将其删除。因为不建议使用此类转换,所以不建议mysqlcheck--fix-db-names--fix-table-names选项以及ALTER DATABASE语句的UPGRADE DATA DIRECTORY NAME子句。

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