MySQL 拥有一个复杂的但直观易学的 SQL 接口。这个章节描述了各种不同的命令、类型和函数,为了高效地使用 MySQL 需要了解它们。这个章节也可以视为 MySQL 中包含的所有功能的参考。
这个章节描述了在 MySQL 中书写字符串与数字的各种不同方式。也包含有对各种不同差别和“gotchas”,当你在处理 MySQL 的基本类型时可能陷入的疑惑。
字符串是多个字符组成的一个字符序列,由单引号(“'”) 或双引号 (“"”) 字符包围。(但在 ANSI 模式中运行时只能用单引号)。
例如:
'a string' "another string"
在一个字符串中,如果某个序列具有特殊的含义,每个序列以反斜线符号 (“\”)开头,称为转义字符。 MySQL 识别下列转义字符:
\0
NUL
)
字符。
\'
\"
\b
\n
\r
\t
TAB
)。
\z
mysql database < filename
时 ASCII(26) 可能会引起问题产生。)
\\
\%
\_
注意如果在某些正文环境内使用 “\%” 或 “\_”,将返回字符串 “\%” 和 “\_” 而不是 “%” 和 “_”。
下面显示的 SELECT
演示引号和转义是如何工作:
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel'lo', '\'hello'; +-------+---------+-----------+--------+--------+ | hello | "hello" | ""hello"" | hel'lo | 'hello | +-------+---------+-----------+--------+--------+ mysql> SELECT "hello", "'hello'", "'hello'", "hel""lo", "\"hello"; +-------+---------+-----------+--------+--------+ | hello | 'hello' | 'hello' | hel"lo | "hello | +-------+---------+-----------+--------+--------+ mysql> SELECT "This\nIs\nFour\nlines"; +--------------------+ | This Is Four lines | +--------------------+
如果你想要把二进制数据插入到一个字符类型的字段中(例如BLOB
),下列字符必须由转义序列表示:
NUL
\
'
"
如果你写 C 代码,你可以使用 C API 函数mysql_real_escape_string()
来为 INSERT
语句转义字符。查看章节 8.1.2 C API 函数概述。在
Perl 中,你可以使用 DBI
包中的 quote
方法来将这些特殊字符转换成适当的转义序列。查看章节
8.5.2 DBI
接口。
你应该在任何可能包含上述特殊字符的字符串中使用转义函数!
另外,很多 MySQL API 提供了一些占位符处理能力,这允许你在查询语句中插入特殊标记,然后在执行查询时对它们绑定数据值。这样,API 会自动为你从数值中转换它们。
整数被表示为一个数字序列。浮点数使用 “.” 作为一个十进制的分隔符。这两种类型的数字可以前置 `-' 以表示一个负值。
有效整数的例子:
1221 0 -32
有效浮点数的例子:
294.42 -32032.6809e+10 148.00
一个整数可以在浮点语境中使用;它被解释为等值的浮点数。
MySQL 支持十六进制数值。在数字的语境中,它们表现类似于一个整数(64位精度)。在字符串的语境中,它们表现类似于一个二进制的字符串,每一对十六进制数字被转换为一个字符:
mysql> SELECT x'4D7953514C'; -> MySQL mysql> SELECT 0xa+0; -> 10 mysql> SELECT 0x5061756c; -> Paul
表达式 x'hexstring'
(4.0 中新加入) 是基于 ANSI SQL 的,表达式 0x
是基于 ODBC 的。十六进制的字符串通常被 ODBC 用于为 BLOB
类型字段赋值。你可以通过 HEX()
将一个字符串或一个数值转化为十六进制格式。
NULL
值 NULL
值并不意味着“无数据”,并且是不同于例如数字类型的 0
或字符串类型的空串。查看章节
A.5.3 NULL
值问题。
当使用文本文件导入与导出格式时 (LOAD DATA INFILE
,SELECT ... INTO OUTFILE
),NULL
可以用 \N
来描述。查看章节 6.4.9 LOAD
DATA INFILE
句法.
数据库、表、索引、列和别名都需遵守 MySQL 同样的规则。
注意,从 MySQL 3.23.6 开始,规则发生改变了,此时引进了用“`”引用标识符(数据库、表和字段名)。如果你以 ANSI 模式运行,“"” 也可以用于引用标识符。查看章节 1.8.2 以 ANSI 模式运行 MySQL。
标识符 | 最大长度 | 允许的字符 |
数据库 | 64 | 一个目录名中允许的任何字符,除了“/”、“\” 或 “.”。 |
表 | 64 | 一个文件名中允许的任何字符,除了 “/” 或 “.”。 |
列 | 64 | 所有的字符。 |
别名 | 255 | 所胡的字符。 |
注意,除了上面的,在一个标识符中还不能有 ASCII(0) 或 ASCII(255) 或引用字符。
注意,如果标识符是一个受限掉的词或包含特殊的字符,当使用它时,必须以一个 `
(backtick) 来引用它。
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
查看章节 6.1.7 MySQL 对保留字挑剔吗?。
在 MySQL 3.23.6 以前的版本中,命名规则如下:
mysqld
的 --default-character-set
的选项来改变。查看章节 4.6.1 用于数据和排序的字符集。
建议不要使用象 1e
这样的名字,因为一个表达式 1e+1
是存在二义性的。它可以被解释为表达式 1e + 1
或数字 1e+1
。
在 MySQL 中,你可以使用下列表格中的任一种方式引用一个列:
列引用 | 含义 |
col_name | 列 col_name
来自查询所用的任何一个表中对应字段
|
tbl_name.col_name | 列 col_name 来自当前数据库中的表
tbl_name
|
db_name.tbl_name.col_name | 列 col_name 来自数据库 db_name 中的表
tbl_name 。这个形式从 MySQL 3.22 或以后版本开始可用。 |
`column_name` | 该字段是一个关键词或包含特殊字符。 |
在一条语句中的列引用中,不需要明确指定一个 tbl_name
或 db_name.tbl_name
前缀,除非这个引用存在二义性。例如,假设表 t1
和 t2
均包含一个字段
c
,当用一个使用了 t1
和 t2
的 SELECT
检索 c
时。在这种情况下,c
存在二义性,因为它在这个语句所使用的表中不是唯一的,因而必须通过写出 t1.c
或 t2.c
来指明你所需的是哪个表。同样的,如果从数据库 db1
的表 t
和数据库 db2
的表 t
中检索,你必须用db1.t.col_name
和 db2.t.col_name
来指定引用哪个库表的列。
句法 .tbl_name
意味着表 tbl_name
在当前数据库中。这个句法是为了与 ODBC 兼容,因为一些 ODBC
程序以一个 “.” 字符作为表名的前缀。
在 MySQL 中,数据库和表对就于那些目录下的目录和文件。因而,操作系统的敏感性决定数据库和表命名的大小写敏感。这就意味着数据库和表名在 Windows 中是大小写不敏感的,而在大多数类型的 Unix 系统中是大小写敏感的。一个特例是 Mac OS X,当缺省的 HFS+ 文件系统使用时。然而 Mac OS X 还支持 UFS 卷,那些在 Mac OS X 是大小写敏感的就如他们在任一 Unix 上一样。查看章节 1.8.3 MySQL 对 ANSI SQL92 的扩展。
注意:尽管在 Windows 中数据库与表名是忽略大小写的,你不应该在同一个查询中使用不同的大小写来引用一个给定的数据库和表。下面的查询将不能工作,因为它以 my_table
和 MY_TABLE
引用一个表:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
列名与列的别名在所有的情况下均是忽略大小写的。
表的别名是区分大小写的。下面的查询将不能工作,因为它用 a
和 A
引用别名:
mysql> SELECT col_name FROM tbl_name AS a -> WHERE a.col_name = 1 OR A.col_name = 2;
如果记忆数据库和表名的字母大小写有困难,建议采用一个一致一约定,例如总是以小写字母创建数据库和表。
避免这个问题的另一个办法就是以 -O lower_case_table_names=1
参数启动 mysqld
。缺省地在 Windows 中这个选项为 1 ,在
Unix 中为 0。
如果 lower_case_table_names
为 1 ,MySQL 将在存储与查找时将所有的表名转换为小写字线。(从 MySQL 4.0.2 开始,这个选项同样适用于数据库名。) 注意,当你更改这个选项时,你必须在启动 mysqld
前首先将老的表名转换为小写字母。
如果将 MyISAM
从 Windows 移动到一个 Unix 磁盘中,在某些情况下你可能需要使用 “mysql_fix_extensions” 工具来修正指定数据库目录下的文件扩展名(小写字母 “.frm”,大写字母 “.MYI” 和 “.MYD”)。“mysql_fix_extensions” 存放在 “scripts” 子目录下。
MySQL 支持连接特定(connection-specific)的用户变量,用 @variablename
句法表示。一个变量名可以由当前字符集中包含的文字与数字字符以及 “_”、“$” 和 “.” 组成。缺少的字符集为 ISO-8859-1 Latin1;这可以通过改变 mysqld
的--default-character-set
的选项来改变。查看章节 4.6.1 用于数据和排序的字符集。
变量不必被初始化。缺省地,他们的值为 NULL 并可以存储一个整数、实数或字符串值。当连接线程退出时,这个线程的所有变量将会自动地被释放。
你可以通过 SET
句法来设置一个变量:
SET @variable= { integer expression | real expression | string expression } [,@variable= ...].
在语句中除了 SET
之外还可以直接为一个变量赋值。然而在这各情况下,赋值操作符为 :=
而不是 =
,因为 =
在非 SET
语句中是用于比较的:
mysql> SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3; +----------------------+------+------+------+ | @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 | +----------------------+------+------+------+ | 5 | 5 | 1 | 4 | +----------------------+------+------+------+
用户变量可以用于表达式所允许的任何地方。注意,这在数字必须明确指定的语境中并不适用,例如,在 SELECT
的 LIMIT
子句中或一个 LOAD DATA
语句的 IGNORE number LINES
的子句中。
注意:在一个 SELECT
语句中,各个表达式只有在它被送到客户端时才能被求值。这就意味着,在 HAVING
、GROUP BY
或 ORDER BY
子句中,你不能使用一个包含在 SELECT
部份所设置变量的表达式。例如:下面的语句将不会按预期的运作:
mysql> SELECT (@aa:=id) AS a, (@aa+3) AS b FROM table_name HAVING b=5;
原因是因为 @aa
不会是当前行的值,而是前一个符合条件的行的 id
值。
规则就是在同一语句中决不赋值 和 使用同一个变量。
从 MySQL 4.0.3 开始,我们提供了对大量的系统变量和连接变量的更好的访问方式。你可以不需要关闭服务器就可以更改其中的大部变量值。
系统变量可分为两种类型:线程特定(Thread-specific)或称为连接特定(connection-specific)变量,它们是当前连接唯一的;全局变量,它们用于设置全局事件。全局变量也同样被用于设置一个新连接的相应线程特定变量的初始值。
当 mysqld
启动时,所有的全局变量以命令行参数和选项文件内容初始化。可以通过 SET GLOBAL
命令更改这些值。当一个新的连接线程被建立时,将以全局变量值初始化线程特定变量,直到你执行一个新的 SET GLOBAL
命令时,线程特定变量才会改变。
为了设置一个 全局(GLOBAL)
变量值,可以使用下面的任一句法:(在这里,我们以 sort_buffer_size
变量作为一个示例)
SET GLOBAL sort_buffer_size=value; SET @@global.sort_buffer_size=value;
为了设置一个 会话(SESSION)
变量的值,可以使用下面任一句法:
SET SESSION sort_buffer_size=value; SET @@session.sort_buffer_size=value; SET sort_buffer_size=value;
如果你没有明确指定 GLOBAL
或 SESSION
,那么默认地将是设置 SESSION
。查看章节 5.5.6 SET
句法。
LOCAL
是 SESSION
的同义词。
通过下面的任一命令可以检索到一个 全局(GLOBAL)
变量值:
SELECT @@global.sort_buffer_size; SHOW GLOBAL VARIABLES like 'sort_buffer_size';
通过下面的任一命令可以检索到一个 会话(SESSION)
变量值:
SELECT @@session.sort_buffer_size; SHOW SESSION VARIABLES like 'sort_buffer_size';
当 检索 一个变量值时使用 @@variable_name
句法,或没有指定 GLOBAL
或 SESSION
时,如果线程特定(thread-specific)的 (SESSION
) 值存在,MySQL 将返回它。如果不存在,那么 MySQL 将返回全局变量值。
在设置 全局(GLOBAL)
变量而不是在检索他们的时候需要使用 GLOBAL
,是为了在之后引用一个同名的线程特定(thread-specific)变量或删除同名的一个线程特定(thread-specific)变量时不至发生问题。在这种情况下,你可能无意间改变整个服务器的状态而不是你自己的连接。
下面的列表是你可以使用 GLOBAL
或 SESSION
对它们进行更改和检索的所有变量。
变量名 | 变量值类型 | 变量类型 |
autocommit | bool | SESSION |
big_tables | bool | SESSION |
binlog_cache_size | num | GLOBAL |
bulk_insert_buffer_size | num | GLOBAL | SESSION |
concurrent_insert | bool | GLOBAL |
connect_timeout | num | GLOBAL |
convert_character_set | string | SESSION |
delay_key_write | OFF | ON | ALL | GLOBAL |
delayed_insert_limit | num | GLOBAL |
delayed_insert_timeout | num | GLOBAL |
delayed_queue_size | num | GLOBAL |
error_count | num | LOCAL |
flush | bool | GLOBAL |
flush_time | num | GLOBAL |
foreign_key_checks | bool | SESSION |
identity | num | SESSION |
insert_id | bool | SESSION |
interactive_timeout | num | GLOBAL | SESSION |
join_buffer_size | num | GLOBAL | SESSION |
key_buffer_size | num | GLOBAL |
last_insert_id | bool | SESSION |
local_infile | bool | GLOBAL |
log_warnings | bool | GLOBAL |
long_query_time | num | GLOBAL | SESSION |
low_priority_updates | bool | GLOBAL | SESSION |
max_allowed_packet | num | GLOBAL | SESSION |
max_binlog_cache_size | num | GLOBAL |
max_binlog_size | num | GLOBAL |
max_connect_errors | num | GLOBAL |
max_connections | num | GLOBAL |
max_error_count | num | GLOBAL | SESSION |
max_delayed_threads | num | GLOBAL |
max_heap_table_size | num | GLOBAL | SESSION |
max_join_size | num | GLOBAL | SESSION |
max_sort_length | num | GLOBAL | SESSION |
max_tmp_tables | num | GLOBAL |
max_user_connections | num | GLOBAL |
max_write_lock_count | num | GLOBAL |
myisam_max_extra_sort_file_size | num | GLOBAL | SESSION |
myisam_max_sort_file_size | num | GLOBAL | SESSION |
myisam_sort_buffer_size | num | GLOBAL | SESSION |
net_buffer_length | num | GLOBAL | SESSION |
net_read_timeout | num | GLOBAL | SESSION |
net_retry_count | num | GLOBAL | SESSION |
net_write_timeout | num | GLOBAL | SESSION |
query_cache_limit | num | GLOBAL |
query_cache_size | num | GLOBAL |
query_cache_type | enum | GLOBAL |
read_buffer_size | num | GLOBAL | SESSION |
read_rnd_buffer_size | num | GLOBAL | SESSION |
rpl_recovery_rank | num | GLOBAL |
safe_show_database | bool | GLOBAL |
server_id | num | GLOBAL |
slave_compressed_protocol | bool | GLOBAL |
slave_net_timeout | num | GLOBAL |
slow_launch_time | num | GLOBAL |
sort_buffer_size | num | GLOBAL | SESSION |
sql_auto_is_null | bool | SESSION |
sql_big_selects | bool | SESSION |
sql_big_tables | bool | SESSION |
sql_buffer_result | bool | SESSION |
sql_log_binlog | bool | SESSION |
sql_log_off | bool | SESSION |
sql_log_update | bool | SESSION |
sql_low_priority_updates | bool | GLOBAL | SESSION |
sql_max_join_size | num | GLOBAL | SESSION |
sql_quote_show_create | bool | SESSION |
sql_safe_updates | bool | SESSION |
sql_select_limit | bool | SESSION |
sql_slave_skip_counter | num | GLOBAL |
sql_warnings | bool | SESSION |
table_cache | num | GLOBAL |
table_type | enum | GLOBAL | SESSION |
thread_cache_size | num | GLOBAL |
timestamp | bool | SESSION |
tmp_table_size | enum | GLOBAL | SESSION |
tx_isolation | enum | GLOBAL | SESSION |
version | string | GLOBAL |
wait_timeout | num | GLOBAL | SESSION |
warning_count | num | LOCAL |
unique_checks | bool | SESSION |
以 num
标记的变量可以设置一个数字值。以 bool
标记的变量可以设置 0、1、ON
或 OFF
。enum
类型的变量通常是设置为该变量的某一个可用值,但也可以设置为相对应的数字。(enum 的第一个值为 0)。
下面是某些变量的描述:
变量 | 描述 |
identity | last_insert_id 的别名 (Sybase 兼容) |
sql_low_priority_updates | low_priority_updates 的别名 |
sql_max_join_size | max_join_size 的别名 |
delay_key_write_for_all_tables | 如它与 delay_key_write 一起被设置,那么所有新打开的 MyISAM 表将使用 delayed key writes. |
version | VERSION() 的别名 (Sybase (?) 兼容) |
在启动选项章节中可以找到其它的变量的描述,SHOW VARIABLES
的描述在 SET
部分。查看章节 4.1.1 mysqld
命令行选项。查看章节 4.5.6.4 SHOW VARIABLES
。查看章节 5.5.6 SET
句法。
MySQL 服务器支持 # 到该行结束
、-- 到该行结束
以及 /* 行中间或多个行 */
的注释方格:
mysql> SELECT 1+1; # 这个注释直到该行结束 mysql> SELECT 1+1; -- 这个注释直到该行结束 mysql> SELECT 1 /* 这是一个在行中间的注释 */ + 1; mysql> SELECT 1+ /* 这是一个 多行注释的形式 */ 1;
注意 -- (双长划)
注释风格要求在两个长划后至少有一个空格!
尽管服务器理解刚才描述的注释句法,但 MySQL 客户端的语法分析在 /* ... */
注释方式上还有所限止:
mysql
,你会产生困惑,因为提示符从 mysql>
变为 '>
或 ">
。
不论你是以交互式运行 mysql
还是将命令放在一个文件中,然后以 mysql < some-file
告诉 mysql
读取它的输入,这个限制均存在。
MySQL 支持 `--' ANSI SQL 注释风格,但在两个长划后必须跟有一个空格。查看章节 1.8.4.7 `--' 作为一个注释的开始。
一个常见的问题来于试图使用 MySQL 内置的数据类型或函数名作为表的字段名来创建数据表,例如 TIMESTAMP
或 GROUP
。但是,允许你这样做(例如,ABS
是一个允许的列名),当使用函数名也是列名的函数时,函数名与后面跟着的 “(” 之间不允许存在空格。
下面的词在 MySQL 中是被明确保留的。它们大多数被 ANSI SQL92 禁止作为列或表名(例如, GROUP
)。一些被保留是因为 MySQL 需要它们并且它使用的是一个 yaclearcase/" target="_blank" >cc
语法分析器:
单词 | 单词 | 单词 |
ADD
| ALL
| ALTER
|
ANALYZE
| AND
| AS
|
ASC
| AUTO_INCREMENT
| BDB
|
BEFORE
| BERKELEYDB
| BETWEEN
|
BIGINT
| BINARY
| BLOB
|
BOTH
| BTREE
| BY
|
CASCADE
| CASE
| CHANGE
|
CHAR
| CHARACTER
| CHECK
|
COLLATE
| COLUMN
| COLUMNS
|
CONSTRAINT
| CREATE
| CROSS
|
CURRENT_DATE
| CURRENT_TIME
| CURRENT_TIMESTAMP
|
DATABASE
| DATABASES
| DAY_HOUR
|
DAY_MINUTE
| DAY_SECOND
| DEC
|
DECIMAL
| DEFAULT
| DELAYED
|
DELETE
| DESC
| DESCRIBE
|
DISTINCT
| DISTINCTROW
| DIV
|
DOUBLE
| DROP
| ELSE
|
ENCLOSED
| ERRORS
| ESCAPED
|
EXISTS
| EXPLAIN
| FALSE
|
FIELDS
| FLOAT
| FOR
|
FORCE
| FOREIGN
| FROM
|
FULLTEXT
| FUNCTION
| GRANT
|
GROUP
| HASH
| HAVING
|
HIGH_PRIORITY
| HOUR_MINUTE
| HOUR_SECOND
|
IF
| IGNORE
| IN
|
INDEX
| INFILE
| INNER
|
INNODB
| INSERT
| INT
|
INTEGER
| INTERVAL
| INTO
|
IS
| JOIN
| KEY
|
KEYS
| KILL
| LEADING
|
LEFT
| LIKE
| LIMIT
|
LINES
| LOAD
| LOCALTIME
|
LOCALTIMESTAMP
| LOCK
| LONG
|
LONGBLOB
| LONGTEXT
| LOW_PRIORITY
|
MASTER_SERVER_ID
| MATCH
| MEDIUMBLOB
|
MEDIUMINT
| MEDIUMTEXT
| MIDDLEINT
|
MINUTE_SECOND
| MOD
| MRG_MYISAM
|
NATURAL
| NOT
| NULL
|
NUMERIC
| ON
| OPTIMIZE
|
OPTION
| OPTIONALLY
| OR
|
ORDER
| OUTER
| OUTFILE
|
PRECISION
| PRIMARY
| PRIVILEGES
|
PROCEDURE
| PURGE
| READ
|
REAL
| REFERENCES
| REGEXP
|
RENAME
| REPLACE
| REQUIRE
|
RESTRICT
| RETURNS
| REVOKE
|
RIGHT
| RLIKE
| RTREE
|
SELECT
| SET
| SHOW
|
SMALLINT
| SOME
| SONAME
|
SPATIAL
| SQL_BIG_RESULT
| SQL_CALC_FOUND_ROWS
|
SQL_SMALL_RESULT
| SSL
| STARTING
|
STRAIGHT_JOIN
| STRIPED
| TABLE
|
TABLES
| TERMINATED
| THEN
|
TINYBLOB
| TINYINT
| TINYTEXT
|
TO
| TRAILING
| TRUE
|
TYPES
| UNION
| UNIQUE
|
UNLOCK
| UNSIGNED
| UPDATE
|
USAGE
| USE
| USER_RESOURCES
|
USING
| VALUES
| VARBINARY
|
VARCHAR
| VARCHARACTER
| VARYING
|
WARNINGS
| WHEN
| WHERE
|
WITH
| WRITE
| XOR
|
YEAR_MONTH
| ZEROFILL
|
以下的符号(来自上表)是被 ANSI SQL 禁止的,但是可以被 MySQL 用于列/表名。这是由于用他们命名是很自然的并且有很多的人已经使用了它们。
ACTION
BIT
DATE
ENUM
NO
TEXT
TIME
TIMESTAMP