📄 manual_compatibility.html
字号:
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
<style type="text/css">
<!--
.p13{font-size:14.8px;font-family:宋体;}
.p14{font-size:14.8px;font-family:宋体;line-height:14pt;}
.a:hover{color:red;}
a.t1:visited{color:red;}
-->
</style>
<title>MySQL中文参考手册-5 MySQL 与标准如何兼容?</title>
</head>
<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#101090" VLINK="#7030B0" class="p3">
<h1><img src="Img/mysql-logo.gif" alt="mysql-logo.gif (3082 bytes)" WIDTH="127" HEIGHT="60"><font color="#FF0000">MySQL中文参考手册</font></h1>
<p>译者:晏子 <a href="mailto:(clyan@sohu.com">(clyan@sohu.com</a>)
主页:<a href="http://linuxdb.yeah.net">http://linuxdb.yeah.net</a></p>
<hr>
<p><a HREF="manual_Introduction.html">第一章</a>, <a HREF="manual_Installing.html">前一章</a>,
<a HREF="manual_Privilege_system.html">下一章</a>, <a HREF="manual_Concept_Index.html">最后一章</a>,<a HREF="manual_toc.html">目录</a>. </p>
<hr>
<h1><a NAME="Compatibility" HREF="manual_toc.html#Compatibility">5 MySQL与标准的兼容性?</a></h1>
<h2><a NAME="Extensions_to_ANSI" HREF="manual_toc.html#Extensions_to_ANSI">5.1
MySQL对ANSI SQL92扩充</a></h2>
<p><strong>MySQL</strong>包含了一些可能在其他SQL数据库找不到的扩充。要注意如果你使用他们,你的代码将不与其他SQL服务器兼容。在一些情况下,你可以编写包括<strong>MySQL</strong>扩展的代码,但是仍然是可移植的,通过使用<code>/*!
... */</code>形式的注释。在这种情况下,<strong>MySQL</strong>将进行词法分析并且执行在注释内的代码,好像它是任何其它<strong>MySQL</strong>语句,但是其他SQL服务器将忽略扩展。例如:
</p>
<pre>SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ... </pre>
<p>如果你在'!'后增加一个版本数字,该语法将仅在<strong>MySQL</strong>版本是等于或比使用的版本数字新时才执行:
</p>
<pre>CREATE /*!32302 TEMPORARY */ TABLE (a int);
</pre>
<p>上面的意思是如果你有3.23.02或更新,那么<strong>MySQL</strong>将使用<code>TEMPORARY</code>关键词。
</p>
<p><strong>MySQL</strong>扩展被列在下面:
<ul>
<li>字段类型<code>MEDIUMINT</code>、<code>SET</code>、<code>ENUM</code>和不同的<code>BLOB</code>和<code>TEXT</code>类型。
</li>
<li>字段属性<code>AUTO_INCREMENT</code>、<code>BINARY</code>、<code>UNSIGNED</code>和<code>ZEROFILL</code>。
</li>
<li>缺省地,所有的字符串比较是忽略大小写的,由当前的字符集决定了(缺省为ISO-8859-1
Latin1)排序顺序。如果你不喜欢这样,你应该用<code>BINARY</code>属性或使用<code>BINARY</code>强制符声明列,它导致根据<strong>MySQL</strong>服务器主机的ASCII顺序进行排序。
</li>
<li><strong>MySQL</strong>将每个数据库映射一个<strong>MySQL</strong>数据目录下面的目录,将数据库表映射到数据库目录下的数据库文件名。这有2个含意:
<ul>
<li><a NAME="IDX112"></a>在区分大小写文件名的操作系统(象大多数 Unix
系统一样)上的<strong>MySQL</strong>中数据库名字和表名是区分大小写的。如果你有困难记得表名,接受一个一致的约定,例如总是用小写名字创建数据库和表。
</li>
<li>数据库、表、索引、列或别名可以以数字开始(但是不能仅由数字组成)。
</li>
<li>你可以使用标准的系统命令备份、重命名、移动、删除和拷贝表。例如,重命名一个表,重命名<tt>“.MYD”</tt>、<tt>“.MYI”</tt>和<tt>“.frm”</tt>文件为相应的表。
</li>
</ul>
</li>
<li>在SQL语句中,你可以用<code>db_name.tbl_name</code>语法访问不同数据库中的表。一些SQL服务器提供同样的功能但是称它们为这<code>User
space</code>(用户空间)。<strong>MySQL</strong>不支持类似在<code>create
table ralph.my_table...IN my_tablespace</code>中的表空间。 </li>
<li><code>LIKE</code>在数字列上被允许。 </li>
<li>在一<code>SELECT</code>语句里面使用<code>INTO OUTFILE</code>和<code>STRAIGHT_JOIN</code>。见<a HREF="manual_Reference.html#SELECT">7.12<code> SELECT</code>句法</a>. </li>
<li>在一个<code>SELECT</code>语句<code>中SQL_SMALL_RESULT</code>选项。 </li>
<li><code>EXPLAIN SELECT</code>得到如何联结表的描述。 </li>
<li>在一个<code>CREATE TABLE</code>语句里面使用索引、在字段前缀上的索引和使用<code>INDEX</code>或<code>KEY</code>。见<a HREF="manual_Reference.html#CREATE_TABLE">7.7<code> CREATE TABLE</code> 句法</a>。 </li>
<li><code>CREATE TABLE</code>使用<code>TEMPORARY</code>或<code>IF NOT EXISTS</code>。 </li>
<li>使用<code>COUNT(DISTINCT list)</code>,这里“list”超过一个元素。 </li>
<li>在一个<code>ALTER TABLE</code>语句里面使用<code>CHANGE col_name</code>、<code>DROP
col_name</code>或<code>DROP INDEX</code>。见<a HREF="manual_Reference.html#ALTER_TABLE">7.8<code>
ALTER TABLE</code>句法</a>。 </li>
<li>在一个<code>ALTER TABLE</code>里面语句使用<code>IGNORE</code>。 </li>
<li>在一个<code>ALTER TABLE</code>语句中使用多重<code>ADD</code>、<code>ALTER</code>、<code>DROP</code>或<code>CHANGE</code>子句。
</li>
<li>使用带关键词<code>IF EXISTS</code>的<code>DROP TABLE</code>。</li>
<li>你能用单个<code>DROP TABLE</code>语句抛弃多个表。 </li>
<li><code>DELETE</code>语句的<code>LIMIT</code>子句。 </li>
<li><code>INSERT</code>和<code>REPLACE</code>语句的<code>DELAYED</code>子句。 </li>
<li><code>INSERT</code>, <code>REPLACE</code>, <code>DELETE</code>和<code>UPDATE</code>语句的<code>LOW_PRIORITY</code>子句。
<a NAME="IDX113"></a> <a NAME="IDX114"></a> </li>
<li>使用<code>LOAD DATA INFILE</code>。在多数情况下,这句法与Oracle的<code>LOAD
DATA INFILE</code>兼容。见<a HREF="manual_Reference.html#LOAD_DATA">7.16<code> LOAD
DATA INFILE</code> 句法</a>。 </li>
<li><code>OPTIMIZE TABLE</code>语句。见<a HREF="manual_Reference.html#OPTIMIZE_TABLE">7.9<code>
OPTIMIZE TABLE</code>句法</a>。 </li>
<li><code>SHOW</code>语句。见<a HREF="manual_Reference.html#SHOW">7.21<code> SHOW</code>句法(得到表、列等的信息)</a>。
</li>
<li>字符串可以被<samp>“"”</samp>或<samp>“'”</samp>包围,而不只是<samp>“'”</samp>。
</li>
<li>使用<samp>“\”</samp>转义字符。 </li>
<li><code>SET OPTION</code>语句。见<a HREF="manual_Reference.html#SET_OPTION">7.25<code>
SET OPTION</code>句法</a>。 </li>
<li>你不需要命名所有在<code>GROUP BY</code>部分的被选择的列。这为一些很特定的情况给出更好的性能,而不是一般的查询。见<a HREF="manual_Reference.html#Group_by_functions">7.4.13 用于<code>GROUP BY</code>子句的函数</a>。
</li>
<li>为了方便来自于SQL环境其他为用户,<strong>MySQL</strong>对许多函数支持别名。例如,所有的字符串功能都支持ANSI
SQL句法和 ODBC句法。 </li>
<li><strong>MySQL</strong>理解<code>||</code>和<code>&&</code>意味着逻辑的OR和AND,就像在C程序语言中。在<strong>MySQL</strong>中,<code>||</code>和<code>OR</code>是同义词,<code>&&</code>和<code>AND</code>是同义词。正因为这个好的句法,<strong>MySQL</strong>对字符串并置的不支持ANSI
SQL<code> ||</code>操作符;相反使用<code>CONCAT()</code>,因为<code>CONCAT()</code>接受任何数量的参数,很容易把<code>||</code>操作符使用变换到<strong>MySQL</strong>。</li>
<li><code>CREATE DATABASE</code>或<code>DROP DATABASE</code>。见<a HREF="manual_Reference.html#CREATE_DATABASE">7.5<code> CREATE DATABASE</code>句法</a>。
<a NAME="IDX115"></a> <a NAME="IDX116"></a> </li>
<li><code>%</code>操作符是<code>MOD()</code>一个同义词,即,<code>N % M</code>等价于<code>MOD(N,M)</code>。<code>%</code>支持C程序员并与PostgreSQL兼容。
</li>
<li><code>=</code>, <code><></code>, <code><=</code>,<code><</code>, <code>>=</code>,<code>></code>,
<code><<</code>, <code>>></code>, <code><=></code>, <code>AND</code>, <code>OR</code>或<code>LIKE</code>操作符可以放在<code>SELECT</code>语句的<code>FROM</code>左边用于比较列。例如:
<pre>mysql> SELECT col1=1 AND col2=2 FROM tbl_name;
</pre>
</li>
<li><code>LAST_INSERT_ID()</code>函数。见<a HREF="manual_Clients.html#mysql_insert_id">20.4.29<code>
mysql_insert_id()</code></a>。 </li>
<li>扩展的正则表达式操作符<code>REGEXP</code>和<code>NOT REGEXP</code>。 </li>
<li><code>CONCAT()</code>或<code>CHAR()</code>有一个参数或超过2个参数。(在<strong>MySQL</strong>中,这些函数可取任何数量的参数。)</li>
<li><code>BIT_COUNT()</code>, <code>CASE</code>, <code>ELT()</code>, <code>FROM_DAYS()</code>,
<code>FORMAT()</code>, <code>IF()</code>, <code>PASSWORD()</code>, <code>ENCRYPT()</code>,
<code>md5()</code>, <code>ENCODE()</code>, <code>DECODE()</code>, <code>PERIOD_ADD()</code>,
<code>PERIOD_DIFF()</code>, <code>TO_DAYS()</code>,或<code>WEEKDAY()</code>函数。 </li>
<li>使用<code>TRIM()</code>整修子串。ANSI SQL 只支持单个字符的删除。 </li>
<li><code>GROUP BY</code>函数<code>STD()</code>, <code>BIT_OR()</code>和<code>BIT_AND()</code>。
</li>
<li>使用<code>REPLACE</code>而不是<code>DELETE</code>+<code>INSERT</code>。见<a HREF="manual_Reference.html#REPLACE">7.15<code> REPLACE</code>句法</a>。 </li>
<li><code>FLUSH flush_option</code>语句。 </li>
<li>在一个语句用<code>:=</code>设置变量的可能性: <pre>SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS avg FROM test_table;
SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
</pre>
</li>
</ul>
<h2><a NAME="Ansi_mode" HREF="manual_toc.html#Ansi_mode">5.2 以ANSI模式运行MySQL</a></h2>
<p>如果你用<code>--ansi</code>选项启动mysqld,<strong>MySQL</strong>的下列行为改变。
<ul>
<li><code>||</code>是字符串并置而不是<code>OR</code>。</li>
<li>可在一个函数名字之间与“(”有任何数量的空格。这也使所有的功能名字成为保留词。
</li>
<li><code>"</code>将是一个标识符引号字符(象<strong>MySQL</strong> <code>`</code>引号字符一样)而不是一个字符串引号字符。
</li>
<li><code>REAL</code>将是<code>FLOAT</code>一个同义词,不是<code>DOUBLE</code>一个同义词。
</li>
</ul>
<h2><a NAME="Differences_from_ANSI" HREF="manual_toc.html#Differences_from_ANSI">5.3 MySQL相比ANSI
SQL92的差别</a></h2>
<p>我们尝试使得<strong>MySQL</strong>遵照ANSI SQL标准和ODBC SQL标准,但是在一些情况下,<strong>MySQL</strong>做一些不同的事情:
<ul>
<li><code>--</code>只是一个注释,如果后面跟一个白空字符。见<a HREF="manual_Compatibility.html#Missing_comments">5.4.7<samp> `--'</samp>作为一个注释的开始</a>。
</li>
<li>对于<code>VARCHAR</code>列,当值被存储时,拖后的空格被删除。见<a HREF="manual_Bugs.html#Bugs">E MySQL已知的错误和设计缺限</a>。 </li>
<li>在一些情况下,<code>CHAR</code>列偷偷地被改变为<code>VARCHAR</code>列。见<a HREF="manual_Reference.html#Silent_column_changes">7.7.1 平静的列指定变化</a>。 </li>
<li>当你删除一个表时,对表的权限不自动地废除。你必须明确地发出一个<code>REVOKE</code>来废除对一个表的权限。见<a HREF="manual_Reference.html#GRANT">7.26<code> GRANT</code>和<code>REVOKE</code>句法</a>。
</li>
</ul>
<h2><a NAME="Missing_functions" HREF="manual_toc.html#Missing_functions">5.4 MySQL缺乏的功能</a></h2>
<p>下列功能在当前的<strong>MySQL</strong>版本是没有的。对于一张优先级表指出何时新扩展可以加入<strong>MySQL</strong>,
你应该咨询<a HREF="manual_Todo.html">在线<strong>MySQL</strong> TODO 表</a>。这是本手册最新的TODO表版本。见<a HREF="manual_TODO.html#TODO">F 我们想要在未来加入到MySQL的事情列表(TODO)</a>。
</p>
<h3><a NAME="Missing_Sub-selects" HREF="manual_toc.html#Missing_Sub-selects">5.4.1
子选择</a></h3>
<p>在<strong>MySQL</strong>中下列语句还不能工作: </p>
<pre>SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
</pre>
<p>然而,在很多情况下,你可以重写查询,而不用子选择: </p>
<pre>SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id where table2.id IS NULL
</pre>
<p>对于更复杂的子查询,通常你可以创建临时的表保存子查询。然而在一些情况下,这种选择将行不通。最经常遇到的情形是<code>DELETE</code>语句,对于它标准SQL不支持联结(join)(除了在子选择)。对于这种情况,有2个可用选择,直到子选择被MySQL支持。
</p>
<p>第一个选择是使用一种过程化的程序语言(例如Perl或PHP)来提交一个<code>SELECT</code>查询获得要被删除记录主键,并然后使用这些值构造<code>DELETE</code>语句(<code>DELETE
FROM ... WHERE ... IN (key1, key2, ...)</code>)。 </p>
<p>第二个选择是使用交互式SQL自动构造一套<code>DELETE</code>语句,使用<strong>MySQL</strong>扩展<code>CONCAT()</code>(代替标准<code>||</code>操作符)。例如:
</p>
<pre>SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', tab1.pkid, ';')
FROM tab1, tab2
WHERE tab1.col1 = tab2.col2;
</pre>
<p>你可以把这个查询放在一个脚本文件并且从它重定向输入到<code>mysql</code>命令行解释器,将其输出作为管道返回给解释器的第2个实例:
</p>
<pre>prompt> mysql --skip-column-names mydb < myscript.sql | mysql mydb
</pre>
<p><strong>MySQL</strong>仅支持<code>INSERT ... SELECT ...</code>和<code>REPLACE ...
SELECT ...</code>,独立的子选择将可能在3.24.0得到,然而,在其他环境下,你现在可以使用函数<code>IN()</code>。
</p>
<h3><a NAME="Missing_SELECT_INTO_TABLE" HREF="manual_toc.html#Missing_SELECT_INTO_TABLE">5.4.2<code>
SELECT INTO TABLE</code></a></h3>
<p><strong>MySQL</strong>还不支持Oracle SQL的扩展:<code>SELECT ... INTO TABLE ...</code>.,相反<strong>MySQL</strong>支持ANSI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -