MySQL包含了一些可能在其他SQL数据库找不到的扩充要注意如果你使用他们你的代码把不与其他SQL服务器兼容在一些情况下你可以编写包括MySQL扩展的代码但是仍然是可移植的通过使用/*! */形式的注释在这种情况下MySQL把进行词法分析并且执行在注释内的代码好像它是任何其它MySQL语句但是其他SQL服务器把忽略扩展例如
SELECT /*! STRAIGHT_JOIN */ col_name FROM tabletable WHERE
如果你在!后增加一个版本数字该语法把仅在MySQL版本是等于或比使用的版本数字新时才执行
CREATE /*! TEMPORARY */ TABLE (a int);
上面的意思是如果你有或更新那么MySQL把使用TEMPORARY关键词
MySQL扩展被列在下面
字段类型MEDIUMINTSETENUM和不同的BLOB和TEXT类型
字段属性AUTO_INCREMENTBINARYUNSIGNED和ZEROFILL
缺省地所有的字符串比较是忽略大小写的由当前的字符集决定了(缺省为ISO Latin)排序顺序如果你不喜欢这样你应该用BINARY属性或使用BINARY强制符声明列它导致根据MySQL服务器主机的ASCII顺序进行排序
MySQL把每个数据库映射一个MySQL数据目录下面的目录把数据库表映射到数据库目录下的数据库文件名这有个含意
在区分大小写文件名的操作系统(象大多数 Unix 系统一样)上的MySQL中数据库名字和表名是区分大小写的如果你有困难记得表名接受一个一致的约定例如总是用小写名字创建数据库和表
数据库表索引列或别名可以以数字开始(但是不能仅由数字组成)
你可以使用标准的系统命令备份重命名移动删除和拷贝表例如重命名一个表重命名MYDMYI和frm文件为相应的表
在SQL语句中你可以用db_nametbl_name语法访问不同数据库中的表一些SQL服务器提供同样的功能但是称它们为这User space(用户空间)MySQL不支持类似在create table ralphmy_tableIN my_tablespace中的表空间
LIKE在数字列上被允许
在一SELECT语句里面使用INTO OUTFILE和STRAIGHT_JOIN见 SELECT句法
在一个SELECT语句中SQL_SMALL_RESULT选项
EXPLAIN SELECT得到怎么样联结表的描述
在一个CREATE TABLE语句里面使用索引在字段前缀上的索引和使用INDEX或KEY见 CREATE TABLE 句法
CREATE TABLE使用TEMPORARY或IF NOT EXISTS
使用COUNT(DISTINCT list)这里list超过一个元素
在一个ALTER TABLE语句里面使用CHANGE col_nameDROP col_name或DROP INDEX见 ALTER TABLE句法
在一个ALTER TABLE里面语句使用IGNORE
在一个ALTER TABLE语句中使用多重ADDALTERDROP或CHANGE子句
使用带关键词IF EXISTS的DROP TABLE
你能用单个DROP TABLE语句抛弃多个表
DELETE语句的LIMIT子句
INSERT和REPLACE语句的DELAYED子句
INSERT REPLACE DELETE和UPDATE语句的LOW_PRIORITY子句
使用LOAD DATA INFILE在多数情况下这句法与Oracle的LOAD DATA INFILE兼容见 LOAD DATA INFILE 句法
OPTIMIZE TABLE语句
SHOW语句见 SHOW句法(得到表列等的信息)
字符串可以被或包围而不只是
使用\转义字符
SET OPTION语句见 SET OPTION句法
你不需要命名所有在GROUP BY部分的被选择的列这为一些很特定的情况给出更好的性能而不是一般的查询
为了方便来自于SQL环境其他为用户MySQL对许多函数支持别名例如所有的字符串功能都支持ANSI SQL句法和 ODBC句法
MySQL理解||和&&意味着逻辑的OR和AND就像在C程序语言中在MySQL中||和OR是同义词&&和AND是同义词正因为这个好的句法MySQL对字符串并置的不支持ANSI SQL ||操作符相反使用CONCAT()因为CONCAT()接受任何数量的参数很容易把||操作符使用变换到MySQL
CREATE DATABASE或DROP DATABASE见 CREATE DATABASE句法
%操作符是MOD()一个同义词即N % M等价于MOD(NM)%支持C程序员并与PostgreSQL兼容
= <> <=< >=> << >> <=> AND OR或LIKE操作符可以放在SELECT语句的FROM左边用于比较列例如
mysql> SELECT col= AND col= FROM tbl_name;
LAST_INSERT_ID()函数见 mysql_insert_id()
扩展的正则表达式操作符REGEXP和NOT REGEXP
CONCAT()或CHAR()有一个参数或超过个参数(在MySQL中这些函数可取任何数量的参数)
BIT_COUNT() CASE ELT() FROM_DAYS() FORMAT() IF() PASSWORD() ENCRYPT() md() ENCODE() DECODE() PERIOD_ADD() PERIOD_DIFF() TO_DAYS()或WEEKDAY()函数
使用TRIM()整修子串ANSI SQL 只支持单个字符的删除
GROUP BY函数STD() BIT_OR()和BIT_AND()
使用REPLACE而不是DELETE+INSERT见 REPLACE句法
FLUSH flush_option语句
在一个语句用:=设置变量的可能性
SELECT @a:=SUM(total)@b=COUNT(*)@a/@b AS avg FROM test_table;
SELECT @t:=(@t:=)+@t:=@t@t@t;
以ANSI模式运行MySQL
如果你用ansi选项启动mysqldMySQL的下列行为改变
||是字符串并置而不是OR
可在一个函数名字之间与(有任何数量的空格这也使所有的功能名字成为保留词
把是一个标识符引号字符(象MySQL `引号字符一样)而不是一个字符串引号字符
REAL把是FLOAT一个同义词不是DOUBLE一个同义词
MySQL相比ANSI SQL的差别
我们尝试使得MySQL遵照ANSI SQL标准和ODBC SQL标准但是在一些情况下MySQL做一些不同的事情
只是一个注释如果后面跟一个白空字符`作为一个注释的开始
对于VARCHAR列当值被存储时拖后的空格被删除见E MySQL已知的错误和设计缺限
在一些情况下CHAR列偷偷地被改变为VARCHAR列平静的列指定变化
当你删除一个表时对表的权限不自动地废除你必须明确地发出一个REVOKE来废除对一个表的权限见 GRANT和REVOKE句法
MySQL缺乏的功能
下列功能在当前的MySQL版本是没有的对于一张优先级表指出何时新扩展可以加入MySQL 你应该咨询在线MySQL TODO 表这是本手册最新的TODO表版本见F 我们想要在未来加入到MySQL的事情列表(TODO)
子选择
在MySQL中下列语句还不能工作
SELECT * FROM table WHERE id IN (SELECT id FROM table);
SELECT * FROM table WHERE id NOT IN (SELECT id FROM table);
然而在很多情况下你可以重写查询而不用子选择
SELECT table* FROM tabletable WHERE tableid=tableid;
SELECT table* FROM table LEFT JOIN table ON tableid=tableid where tableid IS NULL
对于更复杂的子查询通常你可以创建临时的表保存子查询然而在一些情况下这种选择把行不通最经常遇到的情形是DELETE语句对于它标准SQL不支持联结(join)(除了在子选择)对于这种情况有个可用选择直到子选择被MySQL支持
第一个选择是使用一种过程化的程序语言(例如Perl或PHP)来提交一个SELECT查询获得要被删除记录主键并然后使用这些值构造DELETE语句(DELETE FROM WHERE IN (key key ))
第二个选择是使用交互式SQL自动构造一套DELETE语句使用MySQL扩展CONCAT()(代替标准||操作符)例如
SELECT CONCAT(DELETE FROM tab WHERE pkid = tabpkid ;)
FROM tab tab
WHERE tabl;
你可以把这个查询放在一个脚本文件并且从它重定向输入到mysql命令行解释器把其输出作为管道返回给解释器的第个实例
prompt> mysql skipcolumnnames mydb < myscriptsql | mysql mydb
MySQL仅支持INSERT SELECT 和REPLACE SELECT 独立的子选择把可能在得到然而在其他环境下你现在可以使用函数IN()
SELECT INTO TABLE
MySQL还不支持Oracle SQL的扩展SELECT INTO TABLE 相反MySQL支持ANSI SQL句法INSERT INTO SELECT 基本上他们是一样的
另外你可使用SELECT INTO OUTFILE或CREATE TABLE SELECT解决你的问题
事务处理
不支持事务处理MySQL把在短时间内支持原子(atomic)操作它象没有回卷的事务用原子操作你能执行一组INSERT/SELECT/whatever 命令并且保证没有其他线程介入在本文中你通常不会需要回卷目前你可通过使用LOCK TABLES和UNLOCK TABLES命令阻止其他线程的干扰见 LOCK TABLES/UNLOCK TABLES句法
存储过程和触发器
一个存储过程是能在服务器中编译并存储的一套SQL命令一旦这样做了顾客不需要一直重新发出全部查询而可以参考存储过程因为查询仅需一次词法分析并且较少的信息需要在服务器和客户之间传送因此这提供了更好的性能你与可以通过拥有在服务器中的函数库提升概念上的层次