vlambda博客
学习文章列表

MySQL模式对象名称——标识符长度限制学习笔记

英文原版快车道:https://dev.mysql.com/doc/refman/5.7/en/identifiers.html

1.2 模式对象名称(Schema Object Names)

MySQL中的特定对象,包括数据库、表、索引、列、别名、视图、存储过程、分区、表空间,以及其他对象名称都称之为标识符。

标识符可能有引号,也可能没有。如果某个标识符包含特殊字符或是一个保留字,那么无论你在何时引用它都需要用引号括起来(例外:限定名中紧跟着句点的保留字必须是标识符,因此不需要引号括起来)。

在MySQL数据库内部,标识符会被转化为Unicode(UTF-8)并进行存储。标识符中允许使用的Unicode字符就是基本多文种平面(Basic Multilingual Plane, BMP)中的字符。因此,标识符可能包含这些字符:

  • 未加引号的标识符中允许的字符:

    • ASCII:[0-9,a-z,A-Z$_] (基本拉丁字母,数字 0-9,美元符号,下划线)

    • 扩展符(Extended):U+0080 .. U+FFFF

  • 有引号的标识符中允许的的字符包括基本多文种平面(Basic Multilingual Plane, BMP)的所有Unicode字符(除U+0000外):

    • ASCII:U+0001 .. U+007F

    • 扩展符(Extended):U+0080 .. U+FFFF

  • 有引号或无引号的标识符中不允许使用 ASCII NUL(U+0000)和补充字符(U+10000以及以上)。

  • 标识符可以以数字开头,但除非引用,否则不能完全由数字组成。

  • 数据库、表以及列名不能以空格字符结尾。

标识符引号字符是反勾号(`):

SELECT * FROM `select` WHERE `select`.id > 100;

如果 ANSI_QUOTES SQL模式启用的话,也允许在双引号标记之内引用标识符:

mysql> CREATE TABLE "test" (col INT);ERROR 1064 (42000): You have an error in your SQL syntax;check the manual that corresponds to your MySQL server versionfor the right syntax to use near '"test" (col INT)' at line 1mysql> SET sql_mode = 'ANSI_QUOTES';Query OK, 0 rows affected, 1 warning (0.02 sec)mysql> CREATE TABLE "test" (col INT);Query OK, 0 rows affected (0.03 sec)

ANSI_QUOTES 模式使得服务器将双引号字符串解释为标识符。因此,当该模式启用时,字符串字面值必须使用单引号进行标记,不能再以双引号标记。

如果引用标识符,则标识符引用字符可以包含在标识符中。如果标识符中包含的字符与用于引用标识符本身的字符相同,则需要将字符加倍。下面的语句创建了一个名为 a 'b 的表,其中包含一个名为 c"d 的列:

mysql> CREATE TABLE `a``b` (`c"d` INT);

在查询语句的 select 列表中,被引用列的别名可以用标识符或字符串引用标识符指定:

mysql> SELECT 1 AS `one`, 2 AS 'two';+-----+-----+| one | two |+-----+-----+| 1 | 2 |+-----+-----+1 row in set (0.00 sec)

在语句的其他位置,对别名的引用必须使用标识符或者该引用是一个字符串字面值。

建议大家不要使用以 Me 或 MeN 开头的名称,其中 MN 是整数。比如,不要使用 1e 作为一个标识符,因为 1e+3 这样的表达式会有歧义。根据上下文,它也许会被解释为表达式 1e + 3 或者数值 1e+3。

在使用 MD5() 生成表明时必须小心,因为它可能会生成非法或具有歧义格式的名称。

另外,在SQL语句中,用户变量不能直接用作标识符或标识符的一部分。

1.2.1 标识符长度限制(Identifier Length Limits)

下面的表格描述了每类标识符的最大长度:

标识符类型 大长度(字符)
Database 64 (NDB storage engine: 63)
Table 64 (NDB storage engine: 63)
Column 64
Index 64
Constraint 64
Stored Program 64
View 64
Tablespace 64
Server 64
Log File Group 64
Alias 256 (也有例外,看下文)
Compound Statement Label 16
User-Defined Variable 64

CREATE VIEW 语句中列别名的最大长度与列一致,都为64个字符(而不是原本的256个字符)。

若约束定义时没有给约束名,则服务器内部会根据关联的表名派生一个名称。比如,服务器内部生成的外键约束名称由“表名+_ibfk_+数字”构成。若表名的长度已经接近约束名的长度限制,则再加上多出的字符就会超出约束名的长度限制,从而引发错误。

标识符使用Unicode(UTF-8)格式存储。存储在 .frm 文件中表定义中的标识符和存储在 mysql 数据库中 grant 表中的标识符都采用这种存储格式。grant 表中的标识符长度通过字符计量,可以在不减少所允许的字符数的条件下使用多字节字符。

注意:MySQL的账户名中,用户名和主机名的值是字符串而不是标识符。


关注我,和我一起邂逅MySQL的前世今生<~~~>