今天因为mysql服务没打开,mysql不能使用,以前从没出现这种服务没开启的问题。因为以前服务一直都是开的。
一开始以为是权限问题,因为错误提示里有‘localhost’权限的字样,于是狂改,还是一直有问题,网上的类似问题也都试了,都无效。
于是决定卸了,重装,但在千钧一发之际,经一哥们指点,发现是服务没开。我晕死..............................................
看来我的Windows操作也太薄弱了。
这不,搞了一天mysql的错误,于是总结如下:
***************************Mysql 常见错误集锦*********************************
1. Host ’...’ is blocked错误
如果你得到象这样的一个错误:
Host ’hostname’ is blocked because of many connection errors.
Unblock with ’mysqladmin flush-hosts’
这意味着, mysqld已经得到了大量 (max_connect_errors)的主机 ’hostname’的在中途被中断了的连接请求。在 max_connect_errors次失败请求后, mysqld认定出错了 (象来字一个黑客的攻击 ),并且阻止该站点进一步的连接,直到某人执行命令 mysqladmin flush-hosts。
缺省地, mysqld在 10个连接错误后阻塞一台主机。你可以通过象这样启动服务器很容易地调整它:
shell> safe_mysqld -O max_connect_errors=10000 &
注意,对给定的主机,如果得到这条错误消息,你应该首先检查该主机的 TCP/IP连接有没有问题。如果你的 TCP/IP连接不在运行,增加 max_connect_errors变量的值对你也不会有帮助!
2. Too many connections错误
如果在你试土连接 MySQL时,你得到错误 Too many connections,这意味着已经有 max_connections个客户连接了 mysqld服务器。
如果你需要比缺省 (100)更多的连接,那么你应该重启 mysqld,用更大的 max_connections 变量值。
注意, mysqld实际上允许 (max_connections+1)个客户连接。最后一个连接是为一个用 Process权限的用户保留的。通过不把这个权限给一般用户 (他们不应该需要它 ),有这个权限一个管理员可以登录并且使用 SHOW PROCESSLIST找出什么可能出错。见 7.21 SHOW句法 (得到表,列的信息)。
3. Out of memory错误
如果你发出查询并且得到类似于下面的错误:
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
注意,错误指向了 MySQL客户 mysql。这个错误的原因很简单,客户没有足够的内存存储全部结果。
为了修正这个问题,首先检查你的查询是否正确。它应该返回这么多的行,这合理吗?如果是这样,你可以使用 mysql --quick,它使用 mysql_use_result()检索结果集合。这将较少的负担放在了客户端 (只是服务器更多 )。
4.Packet too large错误
当一个 MySQL客户或 mysqld服务器得到一个比 max_allowed_packet个字节长的包,它发出一个 Packet too large错误并终止连接。
如果你正在使用 mysql客户,你可以通过用 mysql --set-variable=max_allowed_packet=8M指定一个更大的缓冲区来启动客户程序。
如果你正在使用不允许你指定最大包大小的其他客户 (例如 DBI),你需要在你启动服务器时设置包大小。你可以使用 mysqld的命令行选项设置 max_allowed_packet为一个更大的尺寸。例如,如果你正期望将一个全长的 BLOB存入一张表中,你将需要用 --set-variable=max_allowed_packet=24M选项来启动服务器。
5. The table is full错误
这个错误发生在内存临时表变得比 tmp_table_size字节大时。为了避免这个问题,你可以使用 mysqld的 -O tmp_table_size=#选项来增加临时表的大小,或在你发出有疑问的查询之前使用 SQL选项 SQL_BIG_TABLES。见 7.25 SET OPTION句法。
你也可以使用 --big-tables选项启动 mysqld。这与为所有查询使用 SQL_BIG_TABLES完全相同。
6. Commands out of sync in client错误
如果你在你的客户代码中得到 Commands out of sync; You can’t run this command now,你正在以错误的次序调用客户函数!
这可能发生,例如,如果你正在使用 mysql_use_result()并且在你已经调用了 mysql_free_result()之前试图执行新查询。如果你在 mysql_use_result()或 mysql_store_result()之间试图执行返回数据的 2个查询,它也可能发生。
7. Ignoring user错误
如果你得到下列错误:
Found wrong password for user: ’some_user@some_host’; Ignoring user
这意味着在 mysqld启动时或在它再次装载权限表时,它在 user表中找到了一个有一个无效口令的条目。结果,条目简单地被权限系统忽略。
可能导致这个问题的原因和修正:
你可能正在运行一个有一个老的 user表的新版本 mysqld。你可以通过执行 mysqlshow mysql user看看口令字段是否少于 16个字符来检查它。如果是这样,你可以通过运行 scripts/add_long_password脚本改正这种情况。
用户有一个老式的口令 (8个字符长 )并且你没使用 --old-protocol选项启动 mysqld。用一个新口令更新在 user表中的用户或用 --old-protocol重启 mysqld。
你没有使用 PASSWORD()函数在在 user表中指定了一个口令。使用 mysql以一个新口令更新在 user表中的用户。确保使用 PASSWORD()函数:
mysql> update user set password=PASSWORD(’your password’)
where user=’XXX’;
8. Table ’xxx’ doesn’t exist错误
如果你得到错误 Table ’xxx’ doesn’t exist或 Can’t find file: ’xxx’ (errno: 2),这意味着在当前数据库中没有名为 xxx的表存在。
注意,因为 MySQL使用目录和文件存储数据库和表,数据库和表名件是区分大小写的!(在 Win32上,数据库和表名不是区分大小写的,但是在查询中对所有表的引用必须使用相同的大小写!)
你可以用 SHOW TABLES检查你在当前数据库中有哪个表。见 7.21 SHOW句法 (得到表、列的信息)。
9. MySQL怎样处理一个溢出的磁盘
当出现一个磁盘溢出的情况时, MySQL做下列事情:
它每分钟检查一次看是否有足够空间写入当前行。如果有足够的空间,它继续好像发生什么事情。
每 6分钟它将有关磁盘溢出的警告写入日志文件。
为了缓和这个问题,你可以采取下列行动:
继续,你只需释放足够的空闲磁盘空间以便插入所有记录。
放弃线程,你必须发一个 mysqladmin kill到线程。在下一次检查磁盘时,线程将被放弃 (在 1分钟内 )。
注意,其他线程可能正在等待引起 “磁盘溢出 ”条件的表。如果你有几个 “锁定的 ”的线程,杀死正在等待磁盘溢出条件的那个线程将允许其他线程继续。
10. 如何从一个文本文件运行 SQL命令
一般地, mysql客户被交互性地使用,象这样:
shell> mysql database
然而,也可以把你的 SQL命令放在一个文件中并且告诉 mysql从该文件读取其输入。要想这样做,创造一个文本文件 “text_file”,它包含你想要执行的命令。然后如下那样调用 mysql:
shell> mysql database < text_file
你也能启动有一个 USE db_name语句的文本文件。在这种情况下,在命令行上指定数据库名是不必要的:
shell> mysql < text_file
11. MySQL在哪儿存储临时文件
MySQL使用 TMPDIR环境变量的值作为存储临时文件的目录的路径名。如果你没有设置 TMPDIR, MySQL使用系统缺省值,它通常是 “/tmp”或 “/usr/tmp”。如果包含你的临时文件目录的文件系统太小,你应该编辑 safe_mysqld设定 TMPDIR指向你有足够空间的一个文件系统!你也可以使用 mysqld的 --tmpdir选项目设置临时目录。
MySQL以 “隐含文件 ”创建所有临时文件。这保证了如果 mysqld被终止,临时文件也将被删除。使用隐含文件的缺点是你将看不到一个大的临时文件填满了临时文件目录所在的文件系统。
当排序 (ORDER BY或 GROUP BY)时, MySQL通常使用一个或两个临时文件。最大磁盘空间需求是:
(存储东西的长度 + sizeof (数据库指针 ))
* 匹配的行数
* 2
sizeof(数据库指针 )通常是 4,但是在未来对确实很大的表可能增加。
对一些 SELECT查询, MySQL也创建临时 SQL表。这些没被隐含且有 “SQL_*”格式的名字。
ALTER TABLE和 OPTIMIZE TABLE在原数据库表的同一个目录中创建一张临时表。
12. 怎样保护 “/tmp/mysql.sock ”不被删除
如果你有这个问题,事实上任何人可以删除 MySQL通讯套接字 “/tmp/mysql.sock”,在 Unix的大多数版本上,你能通过为其设置 sticky( t)位来保护你的 “/tmp”文件系统。作为 root登录并且做下列事情:
shell> chmod +t /tmp
这将保护你的 “/tmp”文件系统使得文件仅能由他们的所有者或超级用户 (root)删除。
你能执行 ls -ld /tmp检查 sticky位是否被设置,如果最后一位许可位是 t,该位被设置了。
13. Access denied错误
见 6.6 权限系统如何工作。并且特别要看 6.13 引起 Access denied错误的原因。
14. 怎样作为一个一般用户运行 MySQL
MySQL服务器 mysqld能被任何用户启动并运行。为了将 mysqld改由 Unix用户 user_name来运行,你必须做下列事情:
如果它正在运行,停止服务器 (使用 mysqladmin shutdown)。
改变数据库目录和文件以便 user_name有权限读和写文件 (你可能需要作为 Unix的 root用户才能做到 ):
shell> chown -R user_name /path/to/mysql/datadir
如果在 MySQL数据目录中的目录或文件是符号链接,你也将需要顺着那些链接并改变他们指向的目录和文件。 chown -R不能跟随符号链接。
以 user_name用户启动服务器,或如果你正在使用 MySQL 3.22或以后版本,以 Unix root用户启动 mysqld并使用 --user=user_name选项, mysqld将在接受任何连接之前切换到以 Unix user_name用户运行。
如果在系统被重新启动时,你使用 mysql.server脚本启动 mysqld,你应该编辑 mysql.server用 su以用户 user_name运行 mysqld,或使用 --user选项调用 mysqld。(不改变 safe_mysqld是必要的。)
现在,你的 mysqld进程应该正在作为 Unix用户 user_name运行,并运行完好。尽管有一件事情没有变化:权限表的内容。缺省 地 (就在运行了脚本 mysql_install_db安装的权限表后 ), MySQL用户 root是唯一有存取 mysql数据库或创建或抛弃数据库权限的用户。除非你改变了那些权限,否则他们仍然保持。当你作为一个 Unix用户而不是 root登录时,这不应该阻止你作为 MySQL root用户来存取 MySQL;只要为客户程序指定 -u root的选项。
注意通过在命令行上提供 -u root,作为 root存取 MySQL,与作为 Unix root用户或其他 Unix用户运行 MySQL没有关系。 MySQL的存取权限和用户名与 Unix用户名字是完全分开的。唯一与 Unix用户名有关的是,如果当你调用一个客户程序时,你不提供一个 -u选项,客户将试图使用你的 Unix登录名作为你的 MySQL用户名进行连接。
如果你的 Unix机器本身不安全,你可能应该至少在存取表中为 MySQL root用户放上一个口令。否则,在那台机器上有一个帐号的任何用户能运行 mysql -u root db_name并且做他喜欢做的任何事情。
15. 怎样重新设置一个忘记的口令
如果你忘记了 MySQL的 root用户的口令,你可以用下列过程恢复它。
通过发送一个 kill(不是 kill -9)到 mysqld服务器来关闭 mysqld服务器。 pid 被保存在一个 .pid文件中,通常在 MySQL数据库目录中:
kill `cat /mysql-data-directory/hostname.pid`
你必须是一个 UNIX root用户或运行服务器的相同用户做这个。
使用 --skip-grant-tables选项重启 mysqld。
用 mysql -h hostname mysql连接 mysqld服务器并且用一条 GRANT命令改变口令。见 7.26 GRANT和 REVOKE句法。你也可以用 mysqladmin -h hostname -u user password ’new password’ 进行。
用 mysqladmin -h hostname flush-privileges或用 SQL命令 FLUSH PRIVILEGES来装载权限表。
16. 文件许可权限问题
如果你有与文件许可有关的问题,例如,如果当你创建一张表时, mysql发出下列错误消息:
ERROR: Can’t find file: ’path/with/filename.frm’ (Errcode: 13)
那么可能是在 mysqld启动时,环境变量 UMASK可能设置不正确。缺省的 umask值是 0660。你可以如下启动 safe_mysqld改变其行为:
shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> /path/to/safe_mysqld &
17. 文件没找到
如果你从 MySQL得到 ERROR ’...’ not found (errno: 23), Can’t open file: ... (errno: 24)或任何其他有 errno 23或 errno 24的错误,它意味着,你没有为 MySQL分配足够的文件描述符。你能使用 perror实用程序得到错误号含义是什么的描述:
shell> perror 23
File table overflow
shell> perror 24
Too many open files
这里的问题是 mysqld正在试图同时保持打开太多的文件。你也可以告诉 mysqld一次不打开那么多的文件,或增加 mysqld可得到的文件描述符数量。为了告诉 mysqld一次保持打开更少的文件,你可以通过使用 safe_mysqld的 -O table_cache=32选项(缺省值是 64)使表缓冲更小。减小 max_connections值也将减少打开文件的数量 (缺省值是 90)。
要想改变 mysqld可用的文件描述符数量,修改 safe_mysqld脚本。脚本中有一条注释了的行 ulimit -n 256。你可以删除 ’#’字符来去掉该行的注释,并且改变数字 256改变为 mysqld可用的文件描述符的数量。
ulimit能增加文件描述符的数量,但是只能到操作系统强加的限制。如果你需要增加每个进程可用的文件描述符数量的 OS限制,参见你的操作系统文档。注意,如果你运行 tcsh外壳, ulimit将不工作!当你请求当前限制时, tcsh也将报告不正确的值!在这种情况下,你应该用 sh启动 safe_mysqld!
18. 使用 DATE列的问题
一个 DATE值的格式是 ’YYYY-MM-DD’。根据 ANSI SQL,不允许其他格式。你应该在 UPDATE表达式和 SELECT语句的 WHERE子句中使用这个格式。例如:
mysql> SELECT * FROM tbl_name WHERE date >= ’1997-05-05’;
为了方便,如果日期用在数字上下文, MySQL自动变换一个日期到一个数字 (并且反过来也如此 )。当更新时和将一个日期与 TIMESTAMP、 DATE或 DATETIME列比较的一个 WHERE子句中,也是足够灵活以允许一种 “宽松 ”的字符串格式。(宽松格式意味着任何标点字符用作在部件之间的分割符。例如, ’1998-08-15’和 ’1998#08#15’是等价的。) MySQL也能变换不包含分割符的一个字符串 (例如 ’19980815’),如果它作为一个日期说得通。特殊日期 ’0000-00-00’可以作为 ’0000-00-00’被存储和检索。当通过 MyODBC使用一个 ’0000-00-00’日期时,在 MyODBC 2.50.12和以上版本,它将自动被转换为 NULL,因为 ODBC不能处理这种日期。
因为 MySQL实行了上述的变换,下列语句可以工作:
mysql> INSERT INTO tbl_name (idate) VALUES (19970505);
mysql> INSERT INTO tbl_name (idate) VALUES (’19970505’);
mysql> INSERT INTO tbl_name (idate) VALUES (’97-05-05’);
mysql> INSERT INTO tbl_name (idate) VALUES (’1997.05.05’);
mysql> INSERT INTO tbl_name (idate) VALUES (’1997 05 05’);
mysql> INSERT INTO tbl_name (idate) VALUES (’0000-00-00’);
mysql> SELECT idate FROM tbl_name WHERE idate >= ’1997-05-05’;
mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT idate FROM tbl_name WHERE idate >= ’19970505’;
然而,下列将不工作:
mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,’19970505’)=0;
STRCMP()是字符串函数,因此它将 idate转换为一个字符串并且实施字符串比较。它不将 ’19970505’转换为一个日期并实施日期比较。
注意, MySQL不检查日期是否正确。如果你存储一个不正确的日期,例如 ’1998-2-31’,错误的日期将被存储。如果日期不能被变换到任何合理的值,在 DATE字段中存储一个 0。这主要是一个速度问题并且我们认为检查日期是应用程序的责任,而不服务器。
19. 时区问题
如果你有一个问题, SELECT NOW()以 GMT时间返回值而不是你的本地时间,你必须设定 TZ环境变量为你的当前时区。这应该在服务器运行的环境进行,例如在 safe_mysqld或 mysql.server中。
20. 在搜索中的大小写敏感性
缺省地, MySQL搜索是大小写不敏感的 (尽管有一些字符集从来不是忽略大小写的,例如捷克语 )。这意味着,如果你用 col_name LIKE ’a%’搜寻,你将得到所有以 A或 a开始的列值。如果你想要使这个搜索大小写敏感,使用象 INDEX(col_name, "A")=0检查一个前缀。或如果列值必须确切是 "A",使用 STRCMP(col_name, "A") = 0。
简单的比较操作 (>=、 >、 = 、 < 、 <=、排序和聚合 )是基于每个字符的 “排序值 ”。有同样排序值的字符 (象 E, e和 ’e)被视为相同的字符!
LIKE比较在每个字符的大写值上进行 (E==e 但是 E<>’e)。
如果你想要一个列总是被当作大小写敏感的方式,声明它为 BINARY。见 7.7 CREATE TABLE句法。
如果你使用以所谓的 big5编码的中文数据,你要使所有的字符列是 BINARY,它可行,是因为 big5编码字符的排序顺序基于 ASCII代码的顺序。
21. NULL值问题
NULL值的概念是造成 SQL的新手的混淆的普遍原因,他们经常认为 NULL是和一个空字符串 ’’的一样的东西。不是这样的!例如,下列语句是完全不同的:
mysql> INSERT INTO my_table (phone) VALUES (NULL);
mysql> INSERT INTO my_table (phone) VALUES ("");
两个语句把值插入到 phone列,但是第一个插入一个 NULL值而第二个插入一个空字符串。第一个的含义可以认为是 “电话号码不知道 ”,而第二个则可意味着 “她没有电话 ”。
在 SQL中, NULL值在于任何其他值甚至 NULL值比较时总是假的( FALSE)。包含 NULL的一个表达式总是产生一个 NULL值,除非在包含在表达式中的运算符和函数的文档中指出。在下列例子,所有的列返回 NULL:
mysql> SELECT NULL,1+NULL,CONCAT(’Invisible’,NULL);
如果你想要寻找值是 NULL的列,你不能使用 =NULL测试。下列语句不返回任何行,因为对任何表达式, expr = NULL是假的:
mysql> SELECT * FROM my_table WHERE phone = NULL;
要想寻找 NULL值,你必须使用 IS NULL测试。下例显示如何找出 NULL电话号码和空的电话号码:
mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = "";
在 MySQL中,就像很多其他的 SQL服务器一样,你不能索引可以有 NULL值的列。你必须声明这样的列为 NOT NULL,而且,你不能插入 NULL到索引的列中。当用 LOAD DATA INFILE读取数据时,空列用 ’’更新。如果你想要在一个列中有 NULL值,你应该在文本文件中使用 N。字面词 ’NULL’也可以在某些情形下使用。见
22. LOAD DATA INFILE句法。当使用 ORDER BY时,首先呈现 NULL值。如果你用 DESC以降序排序, NULL值最后显示。当使用 GROUP BY时,所有的 NULL值被认为是相等的。为了有助于 NULL的处理,你能使用 IS NULL和 IS NOT NULL运算符和 IFNULL()函数。
对某些列类型, NULL值被特殊地处理。如果你将 NULL插入表的第一个 TIMESTAMP列,则插入当前的日期和时间。如果你将 NULL插入一个 AUTO_INCREMENT列,则插入顺序中的下一个数字。
23. alias问题
你可以在 GROUP BY、 ORDER BY或在 HAVING部分中使用别名引用列。别名也可以用来为列取一个更好点的名字:
SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0;
SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0;
SELECT id AS "Customer identity" FROM table_name;
注意,你的 ANSI SQL 不允许你在一个 WHERE子句中引用一个别名。这是因为在 WHERE代码被执行时,列值还可能没有终结。例如下列查询是不合法: SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;
WHERE语句被执行以确定哪些行应该包括 GROUP BY部分中,而 HAVING用来决定应该只用结果集合中的哪些行。
24. 从关联的表中删除行
因为 MySQL不支持子选择或在 DELETE语句中使用多个表,你应该使用下列方法从 2个关联的表中删除行:
在主表中基于某个 WHERE条件 SELECT行。
在主表中基于相同的条件 DELETE行。
DELETE FROM related_table WHERE related_column IN (selected_rows)
如果在 related_column查询中的字符的全部数量超过 1,048,576(缺省值 max_allowed_packet),你应该分成更小的部分并且执行多个 DELETE语句。如果 related_column是一个索引,你每次只删除 100-1000个 related_column id将可能使得 DELETE最快。如果 related_column不是一个索引,速度与 IN子句中参数的数量无关。
25. 解决没有匹配行的问题
如果你有一个复杂的查询,涉及多个表,但没有返回任何行,你应该使用下列过程查找你的询问有什么不对:
EXPLAIN测试查询并且检查你是否能找出显然是错误的一些东西。见 7.22 EXPLAIN句法 (得到关于一个 SELECT的信息 )。
仅选择那些在 WHERE子句中使用的字段。
一次从查询中删除一个表,直到它返回一些行。如果表很大,对查询使用 LIMIT 10是一个好主意。
对应该已经匹配一行的列做一个 SELECT,针对从询问中做后被删除的表。
如果你将 FLOAT或 DOUBLE列与有小数的数字进行比较,你不能使用 =!。这个问题在大多数计算机语言是常见的,因为浮点值不是准确的值。
mysql> SELECT * FROM table_name WHERE float_column=3.5;
->
mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;
在大多数情况下,将 FLOAT改成一个 DOUBLE将修正它!
如果你仍然不能发现错误是什么,创建一个最小的可运行 mysql test < query.sql的测试来显示你的问题。你可以用 mysqldump --quick database tables > query.sql创建一个测试文件,在一个编辑器编辑文件,删除一些插入行 (如果有太多这些语句 )并且在文件末尾加入你的选择语句。测试你仍然有问题,可以这样做:
shell> mysqladmin create test2
shell> mysql test2 < query.sql
使用 mysqlbug的邮寄测试文件到 [email protected]。
26. 与 ALTER TABLE有关的问题
如果 ALTER TABLE死于这样一个错误:
Error on rename of ’./database/name.frm’ to ’./database/B-a.frm’ (Errcode: 17)
问题可能是 MySQL在前一个 ALTER TABLE中已经崩溃并且留下了一个名为 “A-xxx”或 “B-xxx”的老的数据库表。在这种情况下,到 MySQL数据目录中并删除所有名字以 A-或 B-开始的文件。(你可以把他们移到别的地方而不是删除他们 )。
ALTER TABLE工作方式是:
以要求的改变创建一个名为 “A-xxx”的新表。
从老表把所有行拷贝到 “A-xxx”。
老表被改名为 “B-xxx”。
“A-xxx”被改名为你的老表的名字。
“B-xxx”被删除。
如果某些改名操作出错, MySQL试图还原改变。如果出错严重 (当然,这不应该发生。 ), MySQL可能留下了老表为 “B-xxx”但是一个简单改名就应该恢复你的数据。
27. 怎样改变一张表中列的顺序
SQL的要点是中抽象应用程序以避免数据存储格式。你应该总是以你想要检索数据的意愿指定顺序。例如:
SELECT col_name1, col_name2, col_name3 FROM tbl_name;
将以 col_name1、 col_name2、 col_name3的顺序返回列,而:
SELECT col_name1, col_name3, col_name2 FROM tbl_name;
将以 col_name1、 col_name3、 col_name2的顺序返回列。
在一个应用程序中,你应该决不基于他们的位置使用 SELECT * 检索列,因为被返回的列的顺序永远不能保证;对你的数据库的一个简单改变可能导致你的应用程序相当有戏剧性地失败。
不管怎样,如果你想要改变列的顺序,你可以这样做:
以正确的列顺序创建一张新表。
执行 INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table.
删除或改名 old_table。
ALTER TABLE new_table RENAME old_table。
ps:作者:施杨 (施杨de编程世界 )
出处:http://www.cnblogs.com/shiyangxt