MySQL 8.4 Reference Manual  /  ...  /  Identifier Qualifiers

11.2.2 标识符限定符

对象名称可以是未限定或限定形式。未限定名称在解释上下文无歧义的环境中被允许。限定名称至少包含一个限定符,以override默认上下文或提供缺失上下文。

例如,这个语句创建了一个使用未限定名称t1的表:

CREATE TABLE t1 (i INT);

因为t1没有指定数据库的限定符,所以语句将在默认数据库中创建该表。如果没有默认数据库,则发生错误。

这个语句创建了一个使用限定名称db1.t1的表:

CREATE TABLE db1.t1 (i INT);

因为db1.t1包含了数据库限定符db1db1的数据库中创建t1,无论默认数据库是什么。限定符必须指定,如果没有默认数据库。限定符可以指定,如果有默认数据库,以指定不同的数据库或使数据库显式,如果默认数据库与指定的相同。

限定符具有以下特征:

  • 未限定名称由单个标识符组成。限定名称由多个标识符组成。

  • 多部分名称的组件必须以点(.)字符分隔。多部分名称的初始部分作为限定符,影响解释最后一个标识符的上下文。

  • 限定符字符是一个单独的标记,不需要与关联标识符连续。例如,tbl_名.col_名tbl_名 . col_名 是等价的。

  • 如果多部分名称中的某些组件需要引号,请单独引号它们,而不是将整个名称引起来。例如,写作 `my-表`。`my-列`,而不是 `my-表.my-列`

  • 在qualified name中,如果保留字紧随一个句点,则它必须是一个标识符,因此不需要引号。

对象名称的允许限定符取决于对象类型:

  • 数据库名称是完全合格的,不需要限定符:

    CREATE DATABASE db1;
  • 表、视图或存储程序名称可能带有数据库名称限定符。以下是在 CREATE 语句中的未qualified 和 qualified 名称示例:

    CREATE TABLE mytable ...;
    CREATE VIEW myview ...;
    CREATE PROCEDURE myproc ...;
    CREATE FUNCTION myfunc ...;
    CREATE EVENT myevent ...;
    
    CREATE TABLE mydb.mytable ...;
    CREATE VIEW mydb.myview ...;
    CREATE PROCEDURE mydb.myproc ...;
    CREATE FUNCTION mydb.myfunc ...;
    CREATE EVENT mydb.myevent ...;
  • 触发器与表相关,因此任何限定符都应用于表名称:

    CREATE TRIGGER mytrigger ... ON mytable ...;
    
    CREATE TRIGGER mytrigger ... ON mydb.mytable ...;
  • 列名称可能带有多个限定符以在引用它时指明上下文,如以下表所示。

    Column Reference Meaning
    col_名 来自语句中使用的表中的列 col_名
    tbl_名. col_名 默认数据库中的表 tbl_名 的列 col_名
    db_名.tbl_名.col_名 数据库 db_名 中的表 tbl_名 的列 col_名

    换言之,一个列名可能被给定一个表名限定符,该限定符本身可能被给定一个数据库名限定符。以下是SELECT语句中的未限定和限定列引用示例:

    SELECT c1 FROM mytable
    WHERE c2 > 100;
    
    SELECT mytable.c1 FROM mytable
    WHERE mytable.c2 > 100;
    
    SELECT mydb.mytable.c1 FROM mydb.mytable
    WHERE mydb.mytable.c2 > 100;

你不需要在语句中指定对象引用限定符,除非未限定引用是模糊的。假设列c1只出现在表t1中,c2只出现在表t2中,而c在botht1t2中。任何未限定引用到c都是语句中对两个表的模糊引用,必须被限定为t1.ct2.c以指明你所指的是哪个表:

SELECT c1, c2, t1.c FROM t1 INNER JOIN t2
WHERE t2.c > 100;

类似地,在同一个语句中从数据库db1中的表t和从数据库db2中的表t中检索,你必须限定表引用:对于那些在两个表中出现的列名,限定符只需要在那些出现在both表中的列名上。假设列c1只出现在表db1.t中,c2只出现在表db2.t中,而c在bothdb1.tdb2.t中。在这种情况下,c是模糊的必须被限定,但c1c2不需要:

SELECT c1, c2, db1.t.c FROM db1.t INNER JOIN db2.t
WHERE db2.t.c > 100;

表别名使得可以更简单地编写限定列引用:

SELECT c1, c2, t1.c FROM db1.t AS t1 INNER JOIN db2.t AS t2
WHERE t2.c > 100;