MySQL中的alter table命令的基本使用方法及提速优化

 更新时间:2015年11月24日 09:53  点击:2183

一、基本用法

1. 增加列

alter table tbl_name add col_name type

例如,  给pet的表增加一列 weight,

mysql>alter table pet add weight int;

2. 删除列

alter table tbl_name drop col_name

例如, 删除pet表中的weight这一列

mysql>alter table pet drop weight;

3. 改变列

分为改变列的属性和改变列的名字

改变列的属性――方法1:

alter table tbl_name modify col_name type

例如,改变weight的类型

mysql>alter table pet modify weight varchar(30);

改变列的属性――方法2:

alter table tbl_name change old_col_name col_name type

例如,改变weight的类型

alter table pet change weight weight varchar(30);

改变列的名字:

alter table tbl_name change old_col_name col_name

例如改变pet表中weight的名字:

mysql>alter table pet change weight wei;

4. 改变表的名字

alter table tbl_name rename new_tbl

例如, 把pet表更名为animal

mysql>alter table pet rename animal;

二、对ALTER TABLE的优化
在系统的日常维护中,经常需要对表结构进行更新,例如添加/删除一个字段,改变一个VARCHAR的字段长度等等。MySQL针对这种修改表结构的处理方式是先创建一张新的结构的表,接着会通过执行Insert语句将旧表的内容插入到新表中,最后删除整张旧表。这种处理方式在数据量比较小的时候,不会有什么问题,可是当数据量很大的时候可能需要很多时间来处理该过程。
 
执行一个更新表结构的操作花费了几个小时的时间,这是无法忍受的。如果你用的是5.1之前的版本的话,还会在执行表结构更新是数据库往往是停止服务的,幸好在最新的版本中这个问题得到了改善
 
如果在进行表结构更新的时候你采用了恰当的方法,也并不是所有的更新操作会占用你很久的时间。
例如 你想更新用户表的默认密码为“666666”,通常采用的做法是

mysql> ALTER TABLE user      -> MODIFY COLUMN pwd VARCHAR NOT NULL DEFAULT ‘666666';

 
通过SHOW STATUS你可以发现在执行这个操作的过程中进行了大量的Insert操作,当用户的数量很大时 例如百万,千万条的数据时,必然会消耗很多的时间。
 
可是如果你采用下边的方式来更新的话,时间会大大的缩短

mysql> ALTER TABLE user     -> ALTER COLUMN pwd varchar not null SETDEFAULT 5;

 
执行SHOW STATUS操作发现大量的插入操作不存在了,且时间也大大的缩短了(需要先进行FLUSH STATUS)
 之所以可能缩短时间是因为
(1)表字段的默认值是放在表的frm(.frm:表结构文件  .MYD:表数据文件  .MYI:表索引)文件中
(2)ALTER COLUMN会更新frm文件,而不会涉及到表的内容
(3)MODIFY COLUMN会涉及到表数据的内容
 
 从前面的列子可以看出如果操作的过程中只涉及到frm文件的改动的话,表结构的更新效率会大大的提高,但是很多时候在没有必要的时候mysql也会进行表的重建。如果你愿意承担风险,可以用修改frm文件的方式以达到提速修改表结的目的
 
并不是所有的表结构改动都可以通过修改frm文件的方式来提高修改的效率,下面的一些改动可以通过修改frm文件的方式达到更新的目的:
(1)      更改字段的默认值
(2)      增加/删除字段的AUTO_INCREMENT属性
(3)      增加/删除/修改 ENUM的常量值。对于删除操作,如果有字段引用了这个常量值,则在删除后查询的结构为空字符串
 
下面以更新字段的默认值属性为例,分别通过使用ALTER COLUMN和修改frm文件的方式来提高修改表结构的效率
 
1 执行ALTER COLUMN
1.1   首先准备一张字典表

CREATETABLE IF NOT EXISTS dictionary (    id int(10) unsigned NOT NULLAUTO_INCREMENT,  word varchar(100) NOT NULL,  mean varchar(300) NOT NULL,   PRIMARY KEY (`id`)   );  

1.2    插入一些测试数据

mysql>DELIMITER $$mysql>DROP PROCEDURE IF EXISTS SampleProc$$Query OK, 0rows affected, 1 warning (0.01 sec)
CREATEPROCEDURE SampleProc()
BEGIN
DECLARE xINT;
SET x = 1;
WHILEx  <= 110000 DO
insert intodictionary (word, mean) values(concat('a',x),concat('a means',x));
SET  x = x + 1;
END WHILE;
END
mysql>    DELIMITER ;
mysql>call SampleProc();

1.3    SHOW STATUS 观察结果Modify Column 以及Alter Column的区别
首先使用MODIFY COLUMN

mysql> flush status;Query OK, 0 rows affected (0.00 sec)mysql> alter table dictionary      ->modify column mean varchar(20) NOT null default 'DEFAULT1';Query OK, 110002 rows affected (3.07 sec)Records: 110002 Duplicates: 0 Warnings: 0mysql> SHOW STATUS WHERE Variable_name LIKE'Handler%'  ->OR Variable_name LIKE 'Created%';+----------------------------+--------+| Variable_name       | Value |+----------------------------+--------+| Handler_read_rnd_next   | 110003 || Handler_rollback      | 0   || Handler_savepoint     | 0   || Handler_savepoint_rollback | 0   || Handler_update       | 0   || Handler_write       | 110002 |+----------------------------+--------+

 
在使用ALTER COLUMN

 mysql> flush status;mysql> alter table dictionary     -> alter column mean set default'DEFAULT2';Query OK, 0 rowsaffected (0.03 sec)Records: 0 Duplicates: 0 Warnings: 0 mysql> SHOW STATUSWHERE Variable_name LIKE 'Handler%'     -> OR Variable_name LIKE 'Created%';+----------------------------+-------+| Variable_name       | Value |+----------------------------+-------+|Handler_read_rnd_next   | 0   ||Handler_savepoint_rollback | 0   || Handler_update       | 0   || Handler_write       | 0   |

2    修改frm文件
通过修改frm文件的方式来提高修改表结构效率的步骤大概如下
1.       备份相关的数据库文件
2.       创建一张和旧表完全相同的表结构

mysql>create table dictionary_new like dictionary;

3.       执行FLUSH TABLES WITH READ LOCK. 所有的表都被关闭

mysql> alter table dictionary_new     -> modify column mean varchar(30)default 'DEFAULR#';mysql> flush table with read lock;

 
5.       把dictionary_new.frm文件重名为dictionary.frm
6.       执行UNLOCK TABLES

       mysql> unlock tables;       mysql> insert into dictionary(word) values('Random');       mysql> select * from dictionarywhere word='Random';

从下面的结果可以看出,默认值已经被改掉,且不涉及到内容的改变

+--------+--------+----------+| id   | word | mean   |+--------+--------+----------+| 110004 |Random | DEFAULR# |+--------+--------+----------+

 
7.        Drop dictionary_new

[!--infotagslink--]

相关文章

  • 图解PHP使用Zend Guard 6.0加密方法教程

    有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
  • ps怎么使用HSL面板

    ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。 &#8195;...2017-07-06
  • Plesk控制面板新手使用手册总结

    许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
  • 使用insertAfter()方法在现有元素后添加一个新元素

    复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31
  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
  • 使用percona-toolkit操作MySQL的实用命令小结

    1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24
  • 如何使用php脚本给html中引用的js和css路径打上版本号

    在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24
  • jQuery 1.9使用$.support替代$.browser的使用方法

    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31
  • Linux中grep命令详解

    grep命令是Linux系统中最重要的命令之一,功能是从文本文件或管道数据流中筛选匹配的行和数据,如果再配合正则表达式,功能十分强大,是Linux运维人员必备的命令,这篇文章主要介绍了Linux中grep详解,需要的朋友可以参考下...2023-02-15
  • MySQL日志分析软件mysqlsla的安装和使用教程

    一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
  • 安装和使用percona-toolkit来辅助操作MySQL的基本教程

    一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24
  • Mysql效率优化定位较低sql的两种方式

    关于mysql效率优化一般通过以下两种方式定位执行效率较低的sql语句。通过慢查询日志定位那些执行效率较低的 SQL 语句,用 --log-slow-queries[=file_name] 选项启动时, mysqld 会 写一个包含所有执行时间超过 long_quer...2015-11-08
  • C#注释的一些使用方法浅谈

    C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
  • C#隐式运行CMD命令(隐藏命令窗口)

    这篇文章主要介绍了C#隐式运行CMD命令(隐藏命令窗口),本文实现在winform窗口中运行CMD命令,需要的朋友可以参考下...2020-06-25
  • php语言中使用json的技巧及json的实现代码详解

    目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
  • MySQL针对Discuz论坛程序的基本优化教程

    过了这么久,discuz论坛的问题还是困扰着很多网友,其实从各论坛里看到的问题总结出来,很关键的一点都是因为没有将数据表引擎转成InnoDB导致的,discuz在并发稍微高一点的环境下就表现的非常糟糕,产生大量的锁等待,这时候如果...2015-11-24
  • PHP实现连接设备、通讯和发送命令的方法

    本文实例讲述了PHP实现连接设备、通讯和发送命令的方法。分享给大家供大家参考。具体如下:开发的BS架构的软件(PHP),需要跟设备进行通讯,在此记录一下,欢迎各位指正:1. 采用php socket技术使用TCP/IP连接设备参数$service_po...2015-10-21
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • PHP实现无限级分类(不使用递归)

    无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
  • php类的使用实例教程

    php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25