9.2. 数据库、表、索引、列和别名
- 9.2.1. 识别符限制条件
- 9.2.2. 识别符大小写敏感性
数据库、表、索引、列和别名是识别符。该节描述了在MySQL中识别符的允许的语法。
下面的表描述了每类识别符的最大长度和允许的字符。
识别符 | 最大长度(字节) | 允许的字符 |
数据库 | 64 | 目录名允许的任何字符,不包括‘/’、‘\’或者‘。’ |
表 | 64 | 文件名允许的任何字符,不包括‘/’、‘\’或者‘。’ |
列 | 64 | 所有字符 |
索引 | 64 | 所有字符 |
别名 | 255 | 所有字符 |
除了表内注明的限制,识别符不可以包含ASCII 0或值为255的字节。数据库、表和列名不应以空格结尾。在识别符中可以使用引号识别符,尽管应尽可能避免这样使用。
识别符用Unicode(UTF8)保存。在.frm文件中保存的表定义的识别符和在mysql数据库中的授权表保存的识别符也用Unicode(UTF8)保存。在MySQL 5.1中授权表(和其它表)的字符串列的大小等于字符个数;这说明(不象以前版本的MySQL)你可以在这些列保存的值中使用多字节字符而不需要降低字符个数。
识别符可以引起来也可以不引起来。如果识别符是一个保留字或包含特殊字符,无论何时使用,必须将它引起来。关于保留字的列表参见9.6节,“MySQL中保留字的处理”。特殊字符指那些当前字符集、‘_’和‘$’之外的文字数字字符集。
识别符的引用符是反勾号(‘`’):
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
如果SQL服务器模式包括ANSI_QUOTES模式选项,还可以用双引号将识别符引起来:
mysql> CREATE TABLE "test" (col INT);
ERROR 1064: You have an error in your SQL syntax. (...)
mysql> SET sql_mode='ANSI_QUOTES';
mysql> CREATE TABLE "test" (col INT);
Query OK, 0 rows affected (0.00 sec)
参见5.3.2节,“SQL服务器模式”。
如果你引用识别符,可以在识别符内包括识别符引用符。如果识别符内包括的字符与引用识别符的字符相同,则需要用双字符。下面的语句创建一个名为a`b包含列c"d的表:
mysql> CREATE TABLE `a``b` (`c"d` INT);
建议不要使用XeX模式的名,例如1e或2e2,因为类似1e+1的表达式比较模糊。根据上下文,它可以解释为表达式1e + 1或数字1e+1。
使用MD5产生表名时应仔细,因为它可能产生不合法的表名,如上所述。
9.2.1. 识别符限制条件
MySQL允许使用由单个识别符或多个识别符组成的名字。多部分名各组件之间应以句点(‘.’)间隔开。多部分名的开头部分作为限定词,后面的识别符被解释。
在MySQL中可以引用下面形式的列:
列参考 | 含义 |
col_name | 列col_name,查询中使用的表包含有此名字的列。 |
tbl_name.col_name | 默认数据库中的表tbl_name的列col_name。 |
db_name.tbl_name.col_name | 数据库db_name中的表tbl_name的列col_name。 |
如果多部分名的组件需要引用,应分别将它们引起来而不要将整个名引起来。例如,`my-tables`.`my-column`有效,而`my-tables.my-column`无效。
不需要在语句中为列指定tbl_name或db_name.tbl_name前缀,除非列会很模糊。假定表t1和t2各包含一个列c,你使用SELECT语句在t1和t2中搜索c。在这种情况下,c很模糊,因为它在语句中使用的表内不唯一。你必须用表名t1.c或t2.c限定它,表示指哪个表。同样,要想用同一语句搜索数据库db1中的表t和数据库db2中的表t,你必须将那些表中的列指为db1.t.col_name和db2.t.col_name。
限定名中句点后面的字必须为一个识别符,因此不需要将它引起来,即使是一个保留字。
语法.tbl_name表示当前数据库中的tbl_name。该语法与ODBC兼容,因为某些ODBC程序在表名前面加前缀‘.’字符。
9.2.2. 识别符大小写敏感性
在MySQL中,数据库对应数据目录中的目录。数据库中的每个表至少对应数据库目录中的一个文件(也可能是多个,取决于存储引擎)。因此,所使用操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。这说明在大多数Unix中数据库名和表名对大小写敏感,而在Windows中对大小写不敏感。一个显著的例外情况是Mac OS X,它基于Unix但使用默认文件系统类型(HFS+),对大小写不敏感。然而,Mac OS X也支持UFS卷,该卷对大小写敏感,就像Unix一样。参见1.8.4节,“MySQL对标准SQL的扩展”。
注释:尽管在某些平台中数据库名和表名对大小写不敏感,不应在同一查询中使用不同的大小写来引用给定的数据库或表。下面的查询不会工作,因为它同时引用了表my_tables和asMY_tables:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
列、索引、存储子程序和触发器名在任何平台上对大小写不敏感,列的别名也不敏感。
默认情况,表别名在Unix中对大小写敏感,但在Windows或Mac OS X中对大小写不敏感。下面的查询在Unix中不会工作,因为它同时引用了别名a和A:
mysql> SELECT col_name FROM tbl_name AS a
-> WHERE a.col_name = 1 OR A.col_name = 2;
然而,该查询在Windows中是可以的。要想避免出现差别,最好采用一致的转换,例如总是用小写创建并引用数据库名和表名。在大多数移植和使用中建议使用该转换。
在MySQL中如何在硬盘上保存和使用表名和数据库名由lower_case_tables_name系统变量确定,可以在启动mysqld时设置。lower_case_tables_name可以采用下面的任一值:
值 | 含义 |
0 | 使用CREATE TABLE或CREATE DATABASE语句指定的大写和小写在硬盘上保存表名和数据库名。名称比较对大小写敏感。在Unix系统中的默认设置即如此。请注意如果在大小写不敏感的文件系统上用--lower-case-table-names=0强制设为0,并且使用不同的大小写访问MyISAM表名,会导致索引破坏。 |
1 | 表名在硬盘上以小写保存,名称比较对大小写敏感。MySQL将所有表名转换为小写以便存储和查找。该行为也适合数据库名和表的别名。该值为Windows和Mac OS X系统中的默认值。 |
2 | 表名和数据库名在硬盘上使用CREATE TABLE或CREATE DATABASE语句指定的大小写进行保存,但MySQL将它们转换为小写以便查找。名称比较对大小写敏感。注释:只在对大小写不敏感的文件系统上适用!InnoDB表名以小写保存,例如lower_case_tables_name=1。 |
在Windows和Mac OS X中,lower_case_tables_name的默认值是1。
如果只在一个平台上使用MySQL,通常不需要更改lower_case_tables_name变量。然而,如果你想要在对大小写敏感不同的文件系统的平台之间转移表,会遇到困难。例如,在Unix中,my_tables和MY_tables是两个不同的表,但在Windows中,这两个表名相同。要想避免由于数据库或表名的大小写造成的数据转移问题,可使用两个选项:
·在任何系统中可以使用lower_case_tables_name=1。使用该选项的不利之处是当使用SHOW TABLES或SHOW DATABASES时,看不出名字原来是用大写还是小写。
·在Unix中使用lower_case_tables_name=0,在Windows中使用lower_case_tables_name=2。这样了可以保留数据库名和表名的大小写。不利之处是必须确保在Windows中查询总是用正确大小写引用数据库名和表名。如果将查询转移到Unix中,由于在Unix中大小写很重要,如果大小写不正确,它们不工作。
例外:如果你正使用InnoDB表,在任何平台上均应将lower_case_tables_name设置为1,以强制将名转换为小写。
请注意在Unix中将lower_case_tables_name设置为1之前,重启mysqld之前,必须先将旧的数据库名和表名转换为小写。