﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-seaairland-随笔分类-数据库</title><link>http://www.blogjava.net/seaairland/category/8856.html</link><description>&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-6825418521341757";
google_ad_width = 120;
google_ad_height = 240;
google_ad_format = "120x240_as";
google_ad_type = "text_image";
google_ad_channel ="6369214374";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "008000";
google_color_text = "000000";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:57:22 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:57:22 GMT</pubDate><ttl>60</ttl><item><title>MySQL常见错误问答</title><link>http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Sat, 06 May 2006 08:57:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/44773.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/44773.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/44773.html</trackback:ping><description><![CDATA[
		<h3>18.2.1<code><font face="新宋体"> MySQL server has gone away</font></code>错误</h3>
		<p>本小节也涉及有关<code><font face="新宋体">Lost connection to server during query</font></code>的错误。</p>
		<p>对<code><font face="新宋体">MySQL server has gone away</font></code>错误最常见的原因是服务器超时了并且关闭了连接。缺省地，如果没有事情发生，服务器在 8个小时后关闭连接。你可在启动mysqld时通过设置<code><font face="新宋体">wait_timeout</font></code>变量改变时间限制。</p>
		<p>你可以通过执行<code><font face="新宋体">mysqladmin version</font></code>并且检验正常运行的时间来检查<strong>MySQL</strong>还没死掉。</p>
		<p>如果你有一个脚本，你只须再发出查询让客护进行一次自动的重新连接。</p>
		<p>在这种请下，你通常能获得下列错误代码(你得到的是OS相关的)：</p>
		<table class="p4" width="100%" border="1" nosave="#101090">
				<tbody>
						<tr>
								<td>
										<code>
												<font face="新宋体">CR_SERVER_GONE_ERROR</font>
										</code>
								</td>
								<td>客户不能发送一个问题给服务器。 </td>
						</tr>
						<tr>
								<td>
										<code>
												<font face="新宋体">CR_SERVER_LOST</font>
										</code>
								</td>
								<td>当写服务器时，客户没有出错，但是它没有得到对问题的一个完整的答案(或任何答案)。 </td>
						</tr>
				</tbody>
		</table>
		<p>如果你向服务器发送不正确的或太大的查询，你也可能得到这些错误。如果<code><font face="新宋体">mysqld</font></code>得到一个太大或不正常的包，它认为客户出错了并关闭连接。如果你需要较大的查询(例如，如果你正在处理较大的<code><font face="新宋体">BLOB</font></code>列)，你可以使用<code><font face="新宋体">-O max_allowed_packet=#</font></code>选项(缺省1M)启动<code><font face="新宋体">mysqld</font></code>以增加查询限制。多余的内存按需分配，这样<code><font face="新宋体">mysqld</font></code>只有在你发出较大差询时或<code><font face="新宋体">mysqld</font></code>必须返回较大的结果行时，才使用更多的内存！</p>
		<h3>18.2.2<code><font face="新宋体"> Can't connect to [local] MySQL server</font></code>错误</h3>
		<p>一个<strong>MySQL</strong>客户可以两种不同的方式连接<code><font face="新宋体">mysqld</font></code>服务器：Unix套接字，它通过在文件系统中的一个文件(缺省<tt><font face="新宋体">“/tmp/mysqld.sock”</font></tt>)进行连接；或TCP/IP，它通过一个端口号连接。Unix套接字比TCP/IP更快，但是只有用在连接同一台计算机上的服务器。如果你不指定主机名或如果你指定特殊的主机名<code><font face="新宋体">localhost</font></code>，使用Unix套接字。</p>
		<p>错误(2002）<code><font face="新宋体">Can't connect to ...</font></code>通常意味着没有一个<strong>MySQL</strong>服务器运行在系统上或当试图连接<code><font face="新宋体">mysqld</font></code>服务器时，你正在使用一个错误的套接字文件或TCP/IP端口。 </p>
		<p>由检查(使用<code><font face="新宋体">ps</font></code>)在你的服务器上有一个名为<code><font face="新宋体">mysqld</font></code>的进程启动！如果没有任何<code><font face="新宋体">mysqld</font></code>过程，你应该启动一个。见4.15.2 启动MySQL服务器的问题。</p>
		<p>如果一个<code><font face="新宋体">mysqld</font></code>过程正在运行，你可以通过尝试这些不同的连接来检查服务器(当然，端口号和套接字路径名可能在你的安装中是不同的)：</p>
		<pre>shell&gt; mysqladmin version
shell&gt; mysqladmin variables
shell&gt; mysqladmin -h `hostname` version variables
shell&gt; mysqladmin -h `hostname` --port=3306 version
shell&gt; mysqladmin -h 'ip for your host' version
shell&gt; mysqladmin --socket=/tmp/mysql.sock version
</pre>
		<p>注意<code><font face="新宋体">hostname</font></code>命令使用反引号“`”而非正引号“'”；这些导致<code><font face="新宋体">hostname</font></code>输出（即，当前主机名)被代替进<code><font face="新宋体">mysqladmin</font></code>命令中。</p>
		<p>这是可能造成<code><font face="新宋体">Can't connect to local MySQL server</font></code>错误的一些原因： 
</p>
		<ul>
				<li>
						<code>
								<font face="新宋体">mysqld</font>
						</code>不在运行。 
</li>
				<li>你正在使用MIT-pthreads的一个系统上运行。如果正在运行在一个没有原生线程的系统上，<code><font face="新宋体">mysqld</font></code>使用 MIT-pthreads 软件包。见4.2 由MySQL支持的操作系统。然而，MIT-pthreads不支持Unix套接字，因此当与服务器连接时，在这样一个系统上，你总是必须明确地指定主机名。试试使用这个命令检查到服务器的连接：<pre>shell&gt; mysqladmin -h `hostname` version
</pre></li>
				<li>某人删除了<code><font face="新宋体">mysqld</font></code>使用的Unix套接字(缺省<tt><font face="新宋体">“/tmp/mysqld.sock”</font></tt>)。你可能有一个<code><font face="新宋体">cron</font></code>任务删除了<strong>MySQL</strong>套接字(例如，一个把旧文件从<tt><font face="新宋体">“/tmp”</font></tt>目录中删除的任务)。你总是可以运行<code><font face="新宋体">mysqladmin version</font></code>并且检查<code><font face="新宋体">mysqladmin</font></code>正在试图使用的套接字确实存在。在这种情况下，修复方法是删除<code><font face="新宋体">cron</font></code>任务而不删除<tt><font face="新宋体">“mysqld.sock </font></tt>或将套接字放在其他地方。你能用这个命令在<strong>MySQL</strong>配置时指定一个不同的套接字地点：<pre>shell&gt; ./configure --with-unix-socket-path=/path/to/socket
</pre><p>你也可以使用<code><font face="新宋体">--socket=/path/to/socket</font></code>选项启动<code><font face="新宋体">safe_mysqld</font></code>和在启动你的<strong>MySQL</strong>客户前设置环境变量<code><font face="新宋体">MYSQL_UNIX_PORT</font></code>为套接字路径名。你可用<code><font face="新宋体">--socket=/path/to/socket</font></code>选项启动<code><font face="新宋体">mysqld</font></code>服务器。如果你改变了服务器的套接字路径名，你也必须通知<strong>MySQL</strong>客户关于新路径的情况。你可以通过设置环境变量<code><font face="新宋体">MYSQL_UNIX_PORT</font></code>为套接字路径名或由提供套接字路径名作为客户的参数做到。你可用这个命令测试套接字：</p><pre>shell&gt; mysqladmin --socket=/path/to/socket version
</pre></li>
				<li>你正在使用 Linux和线程已经死了(核心倾倒了)。在这种情况中，你必须杀死其它<code><font face="新宋体">mysqld</font></code>线程(例如在启动一个新的<strong>MySQL</strong>服务器之前，可以用<code><font face="新宋体">mysql_zap</font></code>脚本）。见18.1 如果MySQL总是崩溃怎么办。 </li>
		</ul>
		<p>如果你得到错误<code><font face="新宋体">Can't connect to MySQL server on some_hostname</font></code>，你可以尝试下列步骤找出问题是什么： 
</p>
		<ul>
				<li>通过执行<code><font face="新宋体">telnet your-host-name tcp-ip-port-number</font></code>并且按几次回车来检查服务器是否正常运行。如果有一个<strong>MySQL</strong>运行在这个端口上，你应该得到一个包含正在运行的<strong>MySQL</strong>服务器的版本号的应答。如果你得到类似于<code><font face="新宋体">telnet: Unable to connect to remote host: Connection refused</font></code>的一个错误，那么没有服务器在使用的端口上运行。 
</li>
				<li>尝试连接本地机器上的<code><font face="新宋体">mysqld</font></code>守护进程，并用<code><font face="新宋体">mysqladmin variables</font></code>检查mysqld被配置使用的TCP/IP端口(变量<code><font face="新宋体">port</font></code>)。 
</li>
				<li>检查你的<code><font face="新宋体">mysqld</font></code>服务器没有用<code><font face="新宋体">--skip-networking</font></code>选项启动。 </li>
		</ul>
		<h3>18.2.3<code><font face="新宋体"> Host '...' is blocked</font></code>错误</h3>
		<p>如果你得到象这样的一个错误：</p>
		<pre>Host 'hostname' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
</pre>
		<p>这意味着，<code><font face="新宋体">mysqld</font></code>已经得到了大量(<code><font face="新宋体">max_connect_errors</font></code>)的主机<code><font face="新宋体">'hostname'</font></code>的在中途被中断了的连接请求。在<code><font face="新宋体">max_connect_errors</font></code>次失败请求后，<code><font face="新宋体">mysqld</font></code>认定出错了(象来字一个黑客的攻击)，并且阻止该站点进一步的连接，直到某人执行命令<code><font face="新宋体">mysqladmin flush-hosts</font></code>。</p>
		<p>缺省地，<code><font face="新宋体">mysqld</font></code>在10个连接错误后阻塞一台主机。你可以通过象这样启动服务器很容易地调整它：</p>
		<pre>shell&gt; safe_mysqld -O max_connect_errors=10000 &amp;
</pre>
		<p>注意，对给定的主机，如果得到这条错误消息，你应该首先检查该主机的TCP/IP连接有没有问题。如果你的TCP/IP连接不在运行，增加<code><font face="新宋体">max_connect_errors</font></code>变量的值对你也不会有帮助！</p>
		<h3>18.2.4<code><font face="新宋体"> Too many connections</font></code>错误</h3>
		<p>如果在你试土连接<strong>MySQL</strong>时，你得到错误<code><font face="新宋体">Too many connections</font></code>，这意味着已经有<code><font face="新宋体">max_connections</font></code>个客户连接了mysqld服务器。</p>
		<p>如果你需要比缺省(100)更多的连接，那么你应该重启<code><font face="新宋体">mysqld</font></code>，用更大的 max_connections 变量值。</p>
		<p>注意，<code><font face="新宋体">mysqld</font></code>实际上允许(max_connections+1)个客户连接。最后一个连接是为一个用<code><font face="新宋体">Process</font></code>权限的用户保留的。通过不把这个权限给一般用户(他们不应该需要它)，有这个权限一个管理员可以登录并且使用<code><font face="新宋体">SHOW PROCESSLIST</font></code>找出什么可能出错。见7.21<code><font face="新宋体"> SHOW</font></code>句法(得到表，列的信息）。</p>
		<h3>18.2.5<code><font face="新宋体"> Out of memory</font></code>错误</h3>
		<p>如果你发出查询并且得到类似于下面的错误： </p>
		<pre>mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory
</pre>
		<p>注意，错误指向了<strong>MySQL</strong>客<code><font face="新宋体">户mysql</font></code>。这个错误的原因很简单，客户没有足够的内存存储全部结果。</p>
		<p>为了修正这个问题，首先检查你的查询是否正确。它应该返回这么多的行，这合理吗？如果是这样，你可以使用<code><font face="新宋体">mysql --quick</font></code>，它使用<code><font face="新宋体">mysql_use_result()</font></code>检索结果集合。这将较少的负担放在了客户端(只是服务器更多)。</p>
		<h3>18.2.6<code><font face="新宋体"> Packet too large</font></code>错误</h3>
		<p>当一个<strong>MySQL</strong>客户或<code><font face="新宋体">mysqld</font></code>服务器得到一个比<code><font face="新宋体">max_allowed_packet</font></code>个字节长的包，它发出一个<code><font face="新宋体">Packet too large</font></code>错误并终止连接。</p>
		<p>如果你正在使用<code><font face="新宋体">mysql</font></code>客户，你可以通过用<code><font face="新宋体">mysql --set-variable=max_allowed_packet=8M</font></code>指定一个更大的缓冲区来启动客户程序。</p>
		<p>如果你正在使用不允许你指定最大包大小的其他客户(例如<code><font face="新宋体"> DBI</font></code>)，你需要在你启动服务器时设置包大小。你可以使用<code><font face="新宋体">mysqld</font></code>的命令行选项设置<code><font face="新宋体">max_allowed_packet</font></code>为一个更大的尺寸。例如，如果你正期望将一个全长的<code><font face="新宋体">BLOB</font></code>存入一张表中，你将需要用<code><font face="新宋体">--set-variable=max_allowed_packet=24M</font></code>选项来启动服务器。</p>
		<p>　</p>
		<h3>18.2.7<code><font face="新宋体"> The table is full</font></code>错误</h3>
		<p>这个错误发生在内存临时表变得比<code><font face="新宋体">tmp_table_size</font></code>字节大时。为了避免这个问题，你可以使用<code><font face="新宋体">mysqld</font></code>的<code><font face="新宋体">-O tmp_table_size=#</font></code>选项来增加临时表的大小，或在你发出有疑问的查询之前使用SQL选项<code><font face="新宋体">SQL_BIG_TABLES</font></code>。见7.25<code><font face="新宋体"> SET OPTION</font></code>句法。</p>
		<p>你也可以使用<code><font face="新宋体">--big-tables</font></code>选项启动<code><font face="新宋体">mysqld</font></code>。这与为所有查询使用<code><font face="新宋体">SQL_BIG_TABLES</font></code>完全相同。</p>
		<p>
		</p>
		<h3>18.2.8<code><font face="新宋体"> Commands out of sync</font></code> in client错误</h3>
		<p>如果你在你的客户代码中得到<code><font face="新宋体">Commands out of sync; You can't run this command now</font></code>，你正在以错误的次序调用客户函数！</p>
		<p>这可能发生，例如，如果你正在使用<code><font face="新宋体">mysql_use_result()</font></code>并且在你已经调用了<code><font face="新宋体">mysql_free_result()</font></code>之前试图执行新查询。如果你在<code><font face="新宋体">mysql_use_result()</font></code>或<code><font face="新宋体">mysql_store_result()</font></code>之间试图执行返回数据的2个查询，它也可能发生。</p>
		<h3>18.2.9<code><font face="新宋体"> Ignoring user</font></code>错误</h3>
		<p>如果你得到下列错误： </p>
		<p>
				<code>
						<font face="新宋体">Found wrong password for user: 'some_user@some_host'; Ignoring user</font>
				</code>
		</p>
		<p>这意味着在<code><font face="新宋体">mysqld</font></code>启动时或在它再次装载权限表时，它在<code><font face="新宋体">user</font></code>表中找到了一个有一个无效口令的条目。结果，条目简单地被权限系统忽略。</p>
		<p>可能导致这个问题的原因和修正： 
</p>
		<ul>
				<li>你可能正在运行一个有一个老的<code><font face="新宋体">user</font></code>表的新版本<code><font face="新宋体">mysqld</font></code>。你可以通过执行<code><font face="新宋体">mysqlshow mysql user</font></code>看看口令字段是否少于 16个字符来检查它。如果是这样，你可以通过运行<code><font face="新宋体">scripts/add_long_password</font></code>脚本改正这种情况。 
</li>
				<li>用户有一个老式的口令(8个字符长)并且你没使用<code><font face="新宋体">--old-protocol</font></code>选项启动<code><font face="新宋体">mysqld</font></code>。用一个新口令更新在<code><font face="新宋体">user</font></code>表中的用户或用<code><font face="新宋体">--old-protocol</font></code>重启<code><font face="新宋体">mysqld</font></code>。 
</li>
				<li>你没有使用<code><font face="新宋体">PASSWORD()</font></code>函数在在<code><font face="新宋体">user</font></code>表中指定了一个口令。使用<code><font face="新宋体">mysql</font></code>以一个新口令更新在<code><font face="新宋体">user</font></code>表中的用户。确保使用<code><font face="新宋体">PASSWORD()</font></code>函数：<pre>mysql&gt; update user set password=PASSWORD('your password')
           where user='XXX';
</pre></li>
		</ul>
		<h3>18.2.10<code><font face="新宋体"> Table 'xxx' doesn't exist</font></code>错误</h3>
		<p>如果你得到错误<code><font face="新宋体">Table 'xxx' doesn't exist</font></code>或<code><font face="新宋体">Can't find file: 'xxx' (errno: 2)</font></code>，这意味着在当前数据库中没有名为<code><font face="新宋体">xxx</font></code>的表存在。</p>
		<p>注意，因为<strong>MySQL</strong>使用目录和文件存储数据库和表，数据库和表名件是<strong>区分大小写的</strong>！（在Win32上，数据库和表名不是区分大小写的，但是在查询中对所有表的引用必须使用相同的大小写！）</p>
		<p>你可以用<code><font face="新宋体">SHOW TABLES</font></code>检查你在当前数据库中有哪个表。见7.21<code><font face="新宋体"> SHOW</font></code>句法(得到表、列的信息）。<br /></p>
		<h2>18.3 MySQL怎样处理一个溢出的磁盘</h2>
		<p>当出现一个磁盘溢出的情况时，<strong>MySQL</strong>做下列事情： 
</p>
		<ul>
				<li>它每分钟检查一次看是否有足够空间写入当前行。如果有足够的空间，它继续好像发生什么事情。 
</li>
				<li>每6分钟它将有关磁盘溢出的警告写入日志文件。 </li>
		</ul>
		<p>为了缓和这个问题，你可以采取下列行动： 
</p>
		<ul>
				<li>继续，你只需释放足够的空闲磁盘空间以便插入所有记录。 
</li>
				<li>放弃线程，你必须发一个<code><font face="新宋体">mysqladmin kill</font></code>到线程。在下一次检查磁盘时，线程将被放弃(在1分钟内)。 
</li>
				<li>注意，其他线程可能正在等待引起“磁盘溢出”条件的表。如果你有几个“锁定的”的线程，杀死正在等待磁盘溢出条件的那个线程将允许其他线程继续。 </li>
		</ul>
		<h2>18.4 如何从一个文本文件运行SQL命令</h2>
		<p>一般地，<code><font face="新宋体">mysql</font></code>客户被交互性地使用，象这样：</p>
		<pre>shell&gt; mysql database</pre>
		<p>然而，也可以把你的SQL命令放在一个文件中并且告诉<code><font face="新宋体">mysql</font></code>从该文件读取其输入。要想这样做，创造一个文本文件<tt><font face="新宋体">“text_file”</font></tt>，它包含你想要执行的命令。然后如下那样调用<code><font face="新宋体">mysql</font></code>：</p>
		<pre>shell&gt; mysql database &lt; text_file
</pre>
		<p>你也能启动有一个<code><font face="新宋体">USE db_name</font></code>语句的文本文件。在这种情况下，在命令行上指定数据库名是不必要的：</p>
		<pre>shell&gt; mysql &lt; text_file
</pre>
		<pre>见12.1 不同的MySQL程序概述。 </pre>
		<h2>18.5 MySQL在哪儿存储临时文件</h2>
		<p>
				<strong>MySQL</strong>使用<code><font face="新宋体">TMPDIR</font></code>环境变量的值作为存储临时文件的目录的路径名。如果你没有设置<code><font face="新宋体">TMPDIR</font></code>，<strong>MySQL</strong>使用系统缺省值，它通常是<tt><font face="新宋体">“/tmp”</font></tt>或<tt><font face="新宋体">“/usr/tmp”</font></tt>。如果包含你的临时文件目录的文件系统太小，你应该编辑<code><font face="新宋体">safe_mysqld</font></code>设定<code><font face="新宋体">TMPDIR</font></code>指向你有足够空间的一个文件系统！你也可以使用<code><font face="新宋体">mysqld的--tmpdir</font></code>选项目设置临时目录。</p>
		<p>
				<strong>MySQL</strong>以“隐含文件”创建所有临时文件。这保证了如果<code><font face="新宋体">mysqld</font></code>被终止，临时文件也将被删除。使用隐含文件的缺点是你将看不到一个大的临时文件填满了临时文件目录所在的文件系统。</p>
		<p>当排序(<code><font face="新宋体">ORDER BY</font></code>或<code><font face="新宋体">GROUP BY</font></code>)时，<strong>MySQL</strong>通常使用一个或两个临时文件。最大磁盘空间需求是：</p>
		<pre>(存储东西的长度 + sizeof (数据库指针))
* 匹配的行数
* 2
</pre>
		<p>
				<code>
						<font face="新宋体">sizeof(数据库指针)</font>
				</code>通常是4，但是在未来对确实很大的表可能增加。</p>
		<p>对一些<code><font face="新宋体">SELECT</font></code>查询，<strong>MySQL</strong>也创建临时SQL表。这些没被隐含且有<tt><font face="新宋体">“SQL_*”</font></tt>格式的名字。</p>
		<p>
				<code>
						<font face="新宋体">ALTER TABLE</font>
				</code>和<code><font face="新宋体">OPTIMIZE TABLE</font></code>在原数据库表的同一个目录中创建一张临时表。</p>
		<h2>18.6 怎样保护<tt><font face="新宋体">“/tmp/mysql.sock ”</font></tt>不被删除</h2>
		<p>如果你有这个问题，事实上任何人可以删除<strong>MySQL</strong>通讯套接字<tt><font face="新宋体">“/tmp/mysql.sock”</font></tt>，在Unix的大多数版本上，你能通过为其设置<code><font face="新宋体">sticky</font></code>（t）位来保护你的<tt><font face="新宋体">“/tmp”</font></tt>文件系统。作为<code><font face="新宋体">root</font></code>登录并且做下列事情：</p>
		<pre>shell&gt; chmod +t /tmp
</pre>
		<p>这将保护你的<tt><font face="新宋体">“/tmp”</font></tt>文件系统使得文件仅能由他们的所有者或超级用户(<code><font face="新宋体">root</font></code>)删除。</p>
		<p>你能执行<code><font face="新宋体">ls -ld /tmp</font></code>检查<code><font face="新宋体">sticky</font></code>位是否被设置，如果最后一位许可位是<code><font face="新宋体">t</font></code>，该位被设置了。</p>
		<h2>18.7<code><font face="新宋体"> Access denied</font></code>错误</h2>
		<p>见6.6 权限系统如何工作。并且特别要看6.13 引起<code><font face="新宋体">Access denied</font></code>错误的原因。 </p>
		<h2>18.8 怎样作为一个一般用户运行MySQL</h2>
		<p>
				<strong>MySQL</strong>服务器<code><font face="新宋体">mysqld</font></code>能被任何用户启动并运行。为了将<code><font face="新宋体">mysqld</font></code>改由Unix用户<code><font face="新宋体">user_name</font></code>来运行，你必须做下列事情： 
</p>
		<ol>
				<li>如果它正在运行，停止服务器(使用<code><font face="新宋体">mysqladmin shutdown</font></code>)。 
</li>
				<li>改变数据库目录和文件以便<code><font face="新宋体">user_name</font></code>有权限读和写文件(你可能需要作为Unix的<code><font face="新宋体">root</font></code>用户才能做到)：<pre>shell&gt; chown -R user_name /path/to/mysql/datadir
</pre><p>如果在<strong>MySQL</strong>数据目录中的目录或文件是符号链接，你也将需要顺着那些链接并改变他们指向的目录和文件。<code><font face="新宋体">chown -R</font></code>不能跟随符号链接。</p></li>
				<li>以<code><font face="新宋体">user_name</font></code>用户启动服务器，或如果你正在使用<strong>MySQL</strong> 3.22或以后版本，以Unix<code><font face="新宋体"> root</font></code>用户启动<code><font face="新宋体">mysqld</font></code>并使用<code><font face="新宋体">--user=user_name</font></code>选项，<code><font face="新宋体">mysqld</font></code>将在接受任何连接之前切换到以Unix <code><font face="新宋体">user_name</font></code>用户运行。 
</li>
				<li>如果在系统被重新启动时，你使用<code><font face="新宋体">mysql.server</font></code>脚本启动<code><font face="新宋体">mysqld</font></code>，你应该编辑<code><font face="新宋体">mysql.server</font></code>用<code><font face="新宋体">su</font></code>以用户<code><font face="新宋体">user_name</font></code>运行<code><font face="新宋体">mysqld</font></code>，或使用<code><font face="新宋体">--user</font></code>选项调用<code><font face="新宋体">mysqld</font></code>。（不改变<code><font face="新宋体">safe_mysqld</font></code>是必要的。） </li>
		</ol>
		<p>现在，你的<code><font face="新宋体">mysqld</font></code>进程应该正在作为Unix用户<code><font face="新宋体">user_name</font></code>运行，并运行完好。尽管有一件事情没有变化：权限表的内容。缺省 地(就在运行了脚本<code><font face="新宋体">mysql_install_db</font></code>安装的权限表后)，<strong>MySQL</strong>用户<code><font face="新宋体">root</font></code>是唯一有存取<code><font face="新宋体">mysql</font></code>数据库或创建或抛弃数据库权限的用户。除非你改变了那些权限，否则他们仍然保持。当你作为一个Unix用户而不是<code><font face="新宋体">root</font></code>登录时，这不应该阻止你作为<strong>MySQL</strong><code><font face="新宋体">root</font></code>用户来存取<strong>MySQL</strong>；只要为客户程序指定<code><font face="新宋体">-u root</font></code>的选项。</p>
		<p>注意通过在命令行上提供<code><font face="新宋体">-u root</font></code>，作为<code><font face="新宋体">root</font></code>存取<strong>MySQL</strong>，与作为Unix <code><font face="新宋体">root</font></code>用户或其他Unix用户运行<strong>MySQL</strong><em>没有关系</em>。<strong>MySQL</strong>的存取权限和用户名与Unix用户名字是完全分开的。唯一与Unix用户名有关的是，如果当你调用一个客户程序时，你不提供一个<code><font face="新宋体">-u</font></code>选项，客户将试图使用你的Unix登录名作为你的<strong>MySQL</strong>用户名进行连接。</p>
		<p>如果你的Unix机器本身不安全，你可能应该至少在存取表中为<strong>MySQL</strong><code><font face="新宋体">root</font></code>用户放上一个口令。否则，在那台机器上有一个帐号的任何用户能运行<code><font face="新宋体">mysql -u root db_name</font></code>并且做他喜欢做的任何事情。</p>
		<h2>18.9 怎样重新设置一个忘记的口令</h2>
		<p>如果你忘记了<strong>MySQL</strong>的<code><font face="新宋体">root</font></code>用户的口令，你可以用下列过程恢复它。 
</p>
		<ol>
				<li>通过发送一个<code><font face="新宋体">kill</font></code>（不是<code><font face="新宋体">kill -9</font></code>)到<code><font face="新宋体">mysqld</font></code>服务器来关闭mysqld服务器。pid 被保存在一个<code><font face="新宋体">.pid</font></code>文件中，通常在<strong>MySQL</strong>数据库目录中：<pre>kill `cat /mysql-data-directory/hostname.pid`
</pre><p>你必须是一个UNIX<code><font face="新宋体"> root</font></code>用户或运行服务器的相同用户做这个。</p></li>
				<li>使用<code><font face="新宋体">--skip-grant-tables</font></code>选项重启<code><font face="新宋体">mysqld</font></code>。 
</li>
				<li>用<code><font face="新宋体">mysql -h hostname mysql</font></code>连接mysqld服务器并且用一条<code><font face="新宋体">GRANT</font></code>命令改变口令。见7.26<code><font face="新宋体"> GRANT</font></code>和<code><font face="新宋体">REVOKE</font></code>句法。你也可以用<code><font face="新宋体">mysqladmin -h hostname -u user password 'new password'</font></code> 进行。 
</li>
				<li>用<code><font face="新宋体">mysqladmin -h hostname flush-privileges</font></code>或用SQL命令<code><font face="新宋体">FLUSH PRIVILEGES</font></code>来装载权限表。 </li>
		</ol>
		<h2>18.10 文件许可权限问题</h2>
		<p>如果你有与文件许可有关的问题，例如，如果当你创建一张表时，<code><font face="新宋体">mysql</font></code>发出下列错误消息： </p>
		<pre>ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) 
</pre>
		<p>那么可能是在<code><font face="新宋体">mysqld</font></code>启动时，环境变量<code><font face="新宋体">UMASK</font></code>可能设置不正确。缺省的umask值是<code><font face="新宋体">0660</font></code>。你可以如下启动<code><font face="新宋体">safe_mysqld</font></code>改变其行为：</p>
		<pre>shell&gt; UMASK=384  # = 600 in octal
shell&gt; export UMASK
shell&gt; /path/to/safe_mysqld &amp;
</pre>
		<h2>18.11 文件没找到</h2>
		<p>如果你从<strong>MySQL</strong>得到<code><font face="新宋体">ERROR '...' not found (errno: 23)</font></code>, <code><font face="新宋体">Can't open file: ... (errno: 24)</font></code>或任何其他有<code><font face="新宋体">errno 23</font></code>或<code><font face="新宋体">errno 24</font></code>的错误，它意味着，你没有为<strong>MySQL</strong>分配足够的文件描述符。你能使用<code><font face="新宋体">perror</font></code>实用程序得到错误号含义是什么的描述：</p>
		<pre>shell&gt; perror 23
File table overflow
shell&gt; perror 24
Too many open files
</pre>
		<p>这里的问题是<code><font face="新宋体">mysqld</font></code>正在试图同时保持打开太多的文件。你也可以告诉<code><font face="新宋体">mysqld</font></code>一次不打开那么多的文件，或增加<code><font face="新宋体">mysqld</font></code>可得到的文件描述符数量。</p>
		<p>为了告诉<code><font face="新宋体">mysqld</font></code>一次保持打开更少的文件，你可以通过使用<code><font face="新宋体">safe_mysqld</font></code>的<code><font face="新宋体">-O table_cache=32</font></code>选项（缺省值是64)使表缓冲更小。减小<code><font face="新宋体">max_connections</font></code>值也将减少打开文件的数量(缺省值是90)。</p>
		<p>要想改变<code><font face="新宋体">mysqld</font></code>可用的文件描述符数量，修改<code><font face="新宋体">safe_mysqld</font></code>脚本。脚本中有一条注释了的行<code><font face="新宋体">ulimit -n 256</font></code>。你可以删除<code><font face="新宋体">'#'</font></code>字符来去掉该行的注释，并且改变数字256改变为<code><font face="新宋体">mysqld</font></code>可用的文件描述符的数量。</p>
		<p>
				<code>
						<font face="新宋体">ulimit</font>
				</code>能增加文件描述符的数量，但是只能到操作系统强加的限制。如果你需要增加每个进程可用的文件描述符数量的OS限制，参见你的操作系统文档。</p>
		<p>注意，如果你运行<code><font face="新宋体">tcsh</font></code>外壳，<code><font face="新宋体">ulimit</font></code>将不工作！当你请求当前限制时，<code><font face="新宋体">tcsh</font></code>也将报告不正确的值！在这种情况下，你应该用<code><font face="新宋体">sh</font></code>启动<code><font face="新宋体">safe_mysqld</font></code>！<br /></p>
		<h2>18.12 使用<code><font face="新宋体">DATE</font></code>列的问题</h2>
		<p>一个<code><font face="新宋体">DATE</font></code>值的格式是<code><font face="新宋体">'YYYY-MM-DD'</font></code>。根据ANSI SQL，不允许其他格式。你应该在<code><font face="新宋体">UPDATE</font></code>表达式和<code><font face="新宋体">SELECT</font></code>语句的WHERE子句中使用这个格式。例如：</p>
		<pre>mysql&gt; SELECT * FROM tbl_name WHERE date &gt;= '1997-05-05';
</pre>
		<p>为了方便，如果日期用在数字上下文，<strong>MySQL</strong>自动变换一个日期到一个数字(并且反过来也如此)。当更新时和将一个日期与<code><font face="新宋体">TIMESTAMP</font></code>、<code><font face="新宋体">DATE</font></code>或<code><font face="新宋体">DATETIME</font></code>列比较的一个<code><font face="新宋体">WHERE</font></code>子句中，也是足够灵活以允许一种“宽松”的字符串格式。（宽松格式意味着任何标点字符用作在部件之间的分割符。例如，<code><font face="新宋体">'1998-08-15'</font></code>和<code><font face="新宋体">'1998#08#15'</font></code>是等价的。）<strong>MySQL</strong>也能变换不包含分割符的一个字符串(例如<code><font face="新宋体"> '19980815'</font></code>)，如果它作为一个日期说得通。</p>
		<p>特殊日期<code><font face="新宋体">'0000-00-00'</font></code>可以作为<code><font face="新宋体">'0000-00-00'</font></code>被存储和检索<code><font face="新宋体">。</font></code>当通过<strong>MyODBC</strong>使用一个<code><font face="新宋体">'0000-00-00'</font></code>日期时，在<strong>MyODBC</strong> 2.50.12和以上版本，它将自动被转换为<code><font face="新宋体">NULL</font></code>，因为ODBC不能处理这种日期。</p>
		<p>因为<strong>MySQL</strong>实行了上述的变换，下列语句可以工作：</p>
		<pre>mysql&gt; INSERT INTO tbl_name (idate) VALUES (19970505);
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('19970505');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('97-05-05');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('1997.05.05');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('1997 05 05');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('0000-00-00');

mysql&gt; SELECT idate FROM tbl_name WHERE idate &gt;= '1997-05-05';
mysql&gt; SELECT idate FROM tbl_name WHERE idate &gt;= 19970505;
mysql&gt; SELECT mod(idate,100) FROM tbl_name WHERE idate &gt;= 19970505;
mysql&gt; SELECT idate FROM tbl_name WHERE idate &gt;= '19970505';
</pre>
		<p>然而，下列将不工作： </p>
		<pre>mysql&gt; SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;
</pre>
		<p>
				<code>
						<font face="新宋体">STRCMP()</font>
				</code>是字符串函数，因此它将<code><font face="新宋体">idate</font></code>转换为一个字符串并且实施字符串比较。它不将<code><font face="新宋体">'19970505'</font></code>转换为一个日期并实施日期比较。</p>
		<p>注意，<strong>MySQL</strong>不检查日期是否正确。如果你存储一个不正确的日期，例如<code><font face="新宋体">'1998-2-31'</font></code>，错误的日期将被存储。如果日期不能被变换到任何合理的值，在<code><font face="新宋体">DATE</font></code>字段中存储一个<code><font face="新宋体">0</font></code>。这主要是一个速度问题并且我们认为检查日期是应用程序的责任，而不服务器。</p>
		<p>
		</p>
		<h2>18.13 时区问题</h2>
		<p>如果你有一个问题，<code><font face="新宋体">SELECT NOW()</font></code>以GMT时间返回值而不是你的本地时间，你必须设定<code><font face="新宋体">TZ</font></code>环境变量为你的当前时区。这应该在服务器运行的环境进行，例如在<code><font face="新宋体">safe_mysqld</font></code>或<code><font face="新宋体">mysql.server</font></code>中。</p>
		<p>
		</p>
		<h2>18.14 在搜索中的大小写敏感性</h2>
		<p>缺省地，<strong>MySQL</strong>搜索是大小写不敏感的(尽管有一些字符集从来不是忽略大小写的，例如<code><font face="新宋体">捷克语</font></code>)。这意味着，如果你用<code><font face="新宋体">col_name LIKE 'a%'</font></code>搜寻，你将得到所有以<code><font face="新宋体">A</font></code>或<code><font face="新宋体">a</font></code>开始的列值。如果你想要使这个搜索大小写敏感，使用象<code><font face="新宋体">INDEX(col_name, "A")=0</font></code>检查一个前缀。或如果列值必须确切是<code><font face="新宋体">"A"</font></code>，使用<code><font face="新宋体">STRCMP(col_name, "A") = 0</font></code>。</p>
		<p>简单的比较操作(<code><font face="新宋体">&gt;=、&gt;、= 、&lt; 、&lt;=</font></code>、排序和聚合)是基于每个字符的“排序值”。有同样排序值的字符(象E，e和'e)被视为相同的字符！</p>
		<p>
				<code>
						<font face="新宋体">LIKE</font>
				</code>比较在每个字符的大写值上进行(E==e 但是E&lt;&gt;'e）。</p>
		<p>如果你想要一个列总是被当作大小写敏感的方式，声明它为<code><font face="新宋体">BINARY</font></code>。见7.7<code><font face="新宋体"> CREATE TABLE</font></code>句法。</p>
		<p>如果你使用以所谓的big5编码的中文数据，你要使所有的字符列是<code><font face="新宋体">BINARY</font></code>，它可行，是因为big5编码字符的排序顺序基于 ASCII代码的顺序。</p>
		<p>
		</p>
		<h2>18.15 <code><font face="新宋体">NULL</font></code>值问题</h2>
		<p>
				<code>
						<font face="新宋体">NULL</font>
				</code>值的概念是造成SQL的新手的混淆的普遍原因，他们经常认为<code><font face="新宋体">NULL</font></code>是和一个空字符串<code><font face="新宋体">''</font></code>的一样的东西。不是这样的！例如，下列语句是完全不同的：</p>
		<pre>mysql&gt; INSERT INTO my_table (phone) VALUES (NULL);
mysql&gt; INSERT INTO my_table (phone) VALUES ("");
</pre>
		<p>两个语句把值插入到<code><font face="新宋体">phone</font></code>列，但是第一个插入一个<code><font face="新宋体">NULL</font></code>值而第二个插入一个空字符串。第一个的含义可以认为是“电话号码不知道”，而第二个则可意味着“她没有电话”。 </p>
		<p>在SQL中，<code><font face="新宋体">NULL</font></code>值在于任何其他值甚至<code><font face="新宋体">NULL</font></code>值比较时总是假的（FALSE）。包含<code><font face="新宋体">NULL</font></code>的一个表达式总是产生一个<code><font face="新宋体">NULL</font></code>值，除非在包含在表达式中的运算符和函数的文档中指出。在下列例子，所有的列返回<code><font face="新宋体">NULL</font></code>：</p>
		<pre>mysql&gt; SELECT NULL,1+NULL,CONCAT('Invisible',NULL);
</pre>
		<p>如果你想要寻找值是<code><font face="新宋体">NULL</font></code>的列，你不能使用<code><font face="新宋体">=NULL</font></code>测试。下列语句不返回任何行，因为对任何表达式，<code><font face="新宋体">expr = NULL</font></code>是假的：</p>
		<pre>mysql&gt; SELECT * FROM my_table WHERE phone = NULL;
</pre>
		<p>要想寻找<code><font face="新宋体">NULL</font></code>值，你必须使用<code><font face="新宋体">IS NULL</font></code>测试。下例显示如何找出<code><font face="新宋体">NULL</font></code>电话号码和空的电话号码：</p>
		<pre>mysql&gt; SELECT * FROM my_table WHERE phone IS NULL;
mysql&gt; SELECT * FROM my_table WHERE phone = "";
</pre>
		<p>在<strong>MySQL</strong>中，就像很多其他的SQL服务器一样，你不能索引可以有<code><font face="新宋体">NULL</font></code>值的列。你必须声明这样的列为<code><font face="新宋体">NOT NULL</font></code>，而且，你不能插入<code><font face="新宋体">NULL</font></code>到索引的列中。</p>
		<p>当用<code><font face="新宋体">LOAD DATA INFILE</font></code>读取数据时，空列用<code><font face="新宋体">''</font></code>更新。如果你想要在一个列中有<code><font face="新宋体">NULL</font></code>值，你应该在文本文件中使用<code><font face="新宋体">\N</font></code>。字面上的词<code><font face="新宋体">'NULL'</font></code>也可以在某些情形下使用。见7.16<code><font face="新宋体"> LOAD DATA INFILE</font></code>句法。</p>
		<p>当使用<code><font face="新宋体">ORDER BY</font></code>时，首先呈现<code><font face="新宋体">NULL</font></code>值。如果你用<code><font face="新宋体">DESC</font></code>以降序排序，<code><font face="新宋体">NULL</font></code>值最后显示。当使用<code><font face="新宋体">GROUP BY</font></code>时，所有的<code><font face="新宋体">NULL</font></code>值被认为是相等的。</p>
		<p>为了有助于<code><font face="新宋体">NULL</font></code>的处理，你能使用<code><font face="新宋体">IS NULL</font></code>和<code><font face="新宋体">IS NOT NULL</font></code>运算符和<code><font face="新宋体">IFNULL()</font></code>函数。</p>
		<p>对某些列类型，<code><font face="新宋体">NULL</font></code>值被特殊地处理。如果你将<code><font face="新宋体">NULL</font></code>插入表的第一个<code><font face="新宋体">TIMESTAMP</font></code>列，则插入当前的日期和时间。如果你将<code><font face="新宋体">NULL</font></code>插入一个<code><font face="新宋体">AUTO_INCREMENT</font></code>列，则插入顺序中的下一个数字。</p>
		<p>　</p>
		<h2>18.16 <code><font face="新宋体">alias</font></code>问题</h2>
		<p>你可以在<code><font face="新宋体">GROUP BY</font></code>、<code><font face="新宋体">ORDER BY</font></code>或在<code><font face="新宋体">HAVING</font></code>部分中使用别名引用列。别名也可以用来为列取一个更好点的名字：</p>
		<pre>SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt &gt; 0;
SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt &gt; 0;
SELECT id AS "Customer identity" FROM table_name;
</pre>
		<p>注意，你的 ANSI SQL 不允许你在一个<code><font face="新宋体">WHERE</font></code>子句中引用一个别名。这是因为在<code><font face="新宋体">WHERE</font></code>代码被执行时，列值还可能没有终结。例如下列查询是<strong>不合法</strong>：</p>
		<pre>SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt &gt; 0 GROUP BY id;
</pre>
		<p>
				<code>
						<font face="新宋体">WHERE</font>
				</code>语句被执行以确定哪些行应该包括<code><font face="新宋体">GROUP BY</font></code>部分中，而<code><font face="新宋体">HAVING</font></code>用来决定应该只用结果集合中的哪些行。 </p>
		<h2>18.17 从关联的表中删除行</h2>
		<p>因为<strong>MySQL</strong>不支持子选择或在<code><font face="新宋体">DELETE</font></code>语句中使用多个表，你应该使用下列方法从2个关联的表中删除行： 
</p>
		<ol>
				<li>在主表中基于某个<code><font face="新宋体">WHERE</font></code>条件<code><font face="新宋体">SELECT</font></code>行。 
</li>
				<li>在主表中基于相同的条件<code><font face="新宋体">DELETE</font></code>行。 
</li>
				<li>
						<code>
								<font face="新宋体">DELETE FROM related_table WHERE related_column IN (selected_rows)</font>
						</code>
				</li>
		</ol>
		<p>如果在<code><font face="新宋体">related_column</font></code>查询中的字符的全部数量超过1,048,576(缺省值<code><font face="新宋体">max_allowed_packet</font></code>），你应该分成更小的部分并且执行多个<code><font face="新宋体">DELETE</font></code>语句。如果<code><font face="新宋体">related_column</font></code>是一个索引，你每次只删除100-1000个<code><font face="新宋体">related_column</font></code> id将可能使得<code><font face="新宋体">DELETE</font></code>最快。如果<code><font face="新宋体">related_column</font></code>不是一个索引，速度与<code><font face="新宋体">IN</font></code>子句中参数的数量无关。<br /></p>
		<h2>18.18 解决没有匹配行的问题</h2>
		<p>如果你有一个复杂的查询，涉及多个表，但没有返回任何行，你应该使用下列过程查找你的询问有什么不对： 
</p>
		<ol>
				<li>
						<code>
								<font face="新宋体">EXPLAIN</font>
						</code>测试查询并且检查你是否能找出显然是错误的一些东西。见7.22<code><font face="新宋体"> EXPLAIN</font></code>句法(得到关于一个<code><font face="新宋体">SELECT</font></code>的信息)。 
</li>
				<li>仅选择那些在<code><font face="新宋体">WHERE</font></code>子句中使用的字段。 
</li>
				<li>一次从查询中删除一个表，直到它返回一些行。如果表很大，对查询使用<code><font face="新宋体">LIMIT 10</font></code>是一个好主意。 
</li>
				<li>对应该已经匹配一行的列做一个<code><font face="新宋体">SELECT</font></code>，针对从询问中做后被删除的表。 
</li>
				<li>如果你将<code><font face="新宋体">FLOAT</font></code>或<code><font face="新宋体">DOUBLE</font></code>列与有小数的数字进行比较，你不能使用<code><font face="新宋体">=</font></code>!。这个问题在大多数计算机语言是常见的，因为浮点值不是准确的值。<pre>mysql&gt; SELECT * FROM table_name WHERE float_column=3.5;
   -&gt;
mysql&gt; SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;
</pre><p>在大多数情况下，将<code><font face="新宋体">FLOAT</font></code>改成一个<code><font face="新宋体">DOUBLE</font></code>将修正它！</p></li>
				<li>如果你仍然不能发现错误是什么，创建一个最小的可运行<code><font face="新宋体">mysql test &lt; query.sql</font></code>的测试来显示你的问题。你可以用<code><font face="新宋体">mysqldump --quick database tables &gt; query.sql</font></code>创建一个测试文件，在一个编辑器编辑文件，删除一些插入行(如果有太多这些语句)并且在文件末尾加入你的选择语句。测试你仍然有问题，可以这样做：<pre>shell&gt; mysqladmin create test2
shell&gt; mysql test2 &lt; query.sql
</pre><p>使用<code><font face="新宋体">mysqlbug</font></code>的邮寄测试文件到mysql@lists.mysql.com。</p></li>
		</ol>
		<h2>18.19 与<code><font face="新宋体">ALTER TABLE</font></code>有关的问题</h2>
		<p>如果<code><font face="新宋体">ALTER TABLE</font></code>死于这样一个错误：</p>
		<pre>Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)
</pre>
		<p>问题可能是<strong>MySQL</strong>在前一个<code><font face="新宋体">ALTER TABLE</font></code>中已经崩溃并且留下了一个名为<tt><font face="新宋体">“A-xxx”</font></tt>或<tt><font face="新宋体">“B-xxx”</font></tt>的老的数据库表。在这种情况下，到<strong>MySQL</strong>数据目录中并删除所有名字以<code><font face="新宋体">A-</font></code>或<code><font face="新宋体">B-</font></code>开始的文件。（你可以把他们移到别的地方而不是删除他们)。</p>
		<p>
				<code>
						<font face="新宋体">ALTER TABLE</font>
				</code>工作方式是： 
</p>
		<ul>
				<li>以要求的改变创建一个名为<tt><font face="新宋体">“A-xxx”</font></tt>的新表。 
</li>
				<li>从老表把所有行拷贝到<tt><font face="新宋体">“A-xxx”</font></tt>。 
</li>
				<li>老表被改名为<tt><font face="新宋体">“B-xxx”</font></tt>。 
</li>
				<li>
						<tt>
								<font face="新宋体">“A-xxx”</font>
						</tt>被改名为你的老表的名字。 
</li>
				<li>
						<tt>
								<font face="新宋体">“B-xxx”</font>
						</tt>被删除。 </li>
		</ul>
		<p>如果某些改名操作出错，<strong>MySQL</strong>试图还原改变。如果出错严重(当然，这不应该发生。)，<strong>MySQL</strong>可能留下了老表为<tt><font face="新宋体">“B-xxx”</font></tt>但是一个简单改名就应该恢复你的数据。</p>
		<h2>18.20 怎样改变一张表中列的顺序</h2>
		<p>SQL的要点是中抽象应用程序以避免数据存储格式。你应该总是以你想要检索数据的意愿指定顺序。例如：</p>
		<pre>SELECT col_name1, col_name2, col_name3 FROM tbl_name;
</pre>
		<p>将以<code><font face="新宋体">col_name1</font></code>、<code><font face="新宋体">col_name2</font></code>、<code><font face="新宋体">col_name3</font></code>的顺序返回列，而：</p>
		<pre>SELECT col_name1, col_name3, col_name2 FROM tbl_name; 
</pre>
		<p>将以<code><font face="新宋体">col_name1</font></code>、<code><font face="新宋体">col_name3</font></code>、<code><font face="新宋体">col_name2</font></code>的顺序返回列。</p>
		<p>在一个应用程序中，你应该<strong>决不</strong>基于他们的位置使用<code><font face="新宋体">SELECT *</font></code> 检索列，因为被返回的列的顺序永远<strong>不能</strong>保证；对你的数据库的一个简单改变可能导致你的应用程序相当有戏剧性地失败。</p>
		<p>不管怎样，如果你想要改变列的顺序，你可以这样做： 
</p>
		<ol>
				<li>以正确的列顺序创建一张新表。 
</li>
				<li>执行<code><font face="新宋体">INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table</font></code>. 
</li>
				<li>删除或改名<code><font face="新宋体">old_table</font></code>。 
</li>
				<li>
						<code>
								<font face="新宋体">ALTER TABLE new_table RENAME old_table</font>
						</code>。</li>
		</ol>
<img src ="http://www.blogjava.net/seaairland/aggbug/44773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-05-06 16:57 <a href="http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>