全文本搜索
两个最常用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持。
在使用全文本搜索时,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行。这样,MySQL可以快速有效地决定哪些词匹配,哪些词不匹配,它们的匹配频率等。
使用全文本搜索
为了进行全文本搜索,必须索引被搜索的列,而且要随着数据的改变不断地重新索引。在对表列进行适当设计后,mysql会自动进行所有的索引和重新索引。
在索引之后,select可与match()和against()一起使用以实际执行搜索。
启用全文本搜索支持
一般在创建表时启用全文本搜索。create table
语句接受fulltext
子句,它给出被索引列的一个逗号分隔的列表。
CREATE TABLE productnotes
(
note_id int NOT NULL AUTO_INCREMENT,
prod_id char(10) NOT NULL,
note_date datetime NOT NULL,
note_text text NULL ,
PRIMARY KEY(note_id),
FULLTEXT(note_text)
) ENGINE=MyISAM;
进行全文本搜索
在索引之后,使用两个函数match()和against()执行全文本搜索,其中match()指定被搜索的列,against()指定要使用的搜索表达式。
select 列名 from 表名 where match(列名) against('表达式');
传递给match()的值必须与fulltext()定义中的相同。
除非使用binary方式,搜索不区分大小写。
全文本搜索的一个重要部分就是对结果排序。
演示排序如何工作:
select (match(搜索列) against('表达式')) as rank1 from 表名 ;
此列包含全文本搜索计算出的等级值。等级由mysql根据行中词的数目、唯一词的数目、整个索引中词的总数以及包含该词的行的数目计算出来。如果指定多个搜索项,则包含多数匹配词的那些行将具有比包含较少词的那些行高的等级值。
使用查询扩展
查询扩展用来设法放宽所返回的全文本搜索结果的范围。
在使用查询扩展时,MySQL对数据和索引进行两遍扫描来完成搜索:
- 首先,进行一个基本的全文本搜索,找出与搜索条件匹配的所有行。
- 其次,MySQL检查这些匹配行并选择所有有用的词。
- 再其次,MySQL再次进行全文本搜索,这次不仅使用原来的条件,而且还使用所有有用的词。
select 列名 from 表名 where match(搜索列) against('表达式' with query expansion);
表中的行越多,使用查询扩展返回的结果越好。
布尔文本搜索
以布尔方式,可以提供关于如下内容的细节:
- 要匹配的词
- 要排斥的词
- 排列提示(指定某些词比其他词更重要,更重要的词等级更高)
- 表达式分组
布尔方式不同于迄今为止使用的全文本搜索语法的地方在于,即使没有定义fulltext
索引,也可以使用它。但这是一种非常缓慢的操作。
布尔操作符 | 说明 |
---|---|
+ | 包含,词必须存在 |
- | 排除,词必须不出现 |
> | 包含,而且增加等级值 |
< | 包含,且减少等级值 |
() | 把词组成子表达式(允许这些子表达式作为一个组被包含、排除、排列等) |
~ | 取消一个词的排序值 |
* | 词尾的通配符 |
“” | 定义一个短语(与单个词的列表不一样,它匹配整个短语以便包含或排除这个短语) |
示例:
select note_text from productnotes where match(note_text) against('rabbit bait' in boolean mode);
没有指定操作符,这个搜索匹配rabbit和bait中的至少一个词的行。
select note_text from productnotes where match(note_text) against('+rabbit +bait' in boolean mode);
这个搜索匹配包含词rabbit和bait的行。
select note_text from productnotes where match(note_text) against('"rabbit bait"' in boolean mode);
这个搜索匹配短语rabbit bait而不是匹配两个词rabbit和bait。
全文本搜索的使用说明
- 在索引全文本数据时,短词被忽略且从索引中排除。短词定义为那些具有3个或3个一下字符的词(如果需要,这个数目可以更改)。
- MySQL带有一个内建的非用词列表,这些词在索引 全文本数据时总是被忽略。如果需要可以覆盖这个列表。
- 许多次出现的频率很高,搜索它们没有用处(返回太多结果)。因此MySQL规定了一条50%规则,如果一个词出现在50%以上的行中,则将它作为一个非用词忽略。50%规则不用于in Boolean mode。
- 如果表中的行数少于3行,则全文本搜索不返回结果。
- 忽略词中的单引号。
- 不具有词分隔符的语言不能恰当地返回全文本搜索结果。
- 仅在myISAM数据库引擎中支持全文本搜索。
插入数据
insert是用来插入行到数据库表的。插入可以用几种方式使用:
- 插入完整的行。
- 插入行的一部分。
- 插入多行。
- 插入某些查询的结果。
插入完整的行
各个列必须以它们在表定义中出现的次序填充:
insert into 表名 values(值1,值2,值3);
insert语句一般不会产生输出。
因为提供了列名,values必须以其指定的次序匹配指定的列名,不一定按各个列出现在实际表中的次序:
insert into 表名(列名1,列名2,列名3) values(值1,值2,值3);
不管使用哪种insert语法,都必须给出values的正确数目。
可以在insert操作中省略某些列。省略的列必须满足一下某个条件:
- 该列定义为允许NULL值(无值或空值)。
- 在表定义中给出默认值。
插入多个行
insert into 表名1(列名1,列名2,列名3) values(值1,值2,值3);
insert into 表名2(列名1,列名2,列名3) values(值1,值2,值3);
或者,只要每条insert语句中的列名(和次序)相同,可以如下组合各语句:
insert into 表名(列名1,列名2,列名3) values(值1,值2,值3),(值1,值2,值3);
此技术可以提高数据库处理的性能,因为MySQL用单条insert语句处理多个插入比使用多条insert语句快。
插入检索出的数据
insert还存在另一种形式,可以利用它将一条select语句的结果插入表中,这就是所谓的insert select。
insert into 表名(列名1,列名2,列名3) select 列名1,列名2,列名3 from 表名2;
insert select使用的是列的位置,select中的第一列将用来填充表列中指定的第一列。
insert select中select语句可包含where子句以过滤插入的数据。
更新和删除数据
更新数据
使用update语句。可采用两种方式使用update:
- 更新表中特定的行。
- 更新表中所有行,
update 表名 set 列名1=值1 where 列名2=值2;
如果省略where子句就会更新所有行。
ignore关键字:如果用update语句更新多行,并且在更新这些行中的一行或多行时出现一个错误,则整个update操作被取消。即使是发生错误,也继续进行更新,可使用ignore关键字:
update ignore 表名 ...
可以用NULL删除某列的值。
删除数据
使用delete语句。可以用两种方法:
- 从表中删除特定的行。
- 从表中删除所有行。
delete from 表名 where 列名=值;
delete删除整行,删除表的内容而不是表。
如果想从表中删除所有行,可以使用truncate table
,速度更快。
更新和删除的指导原则
- 除非确实打算更新和删除每一行,否则绝对不要不适用不带where子句的update或delete语句。
- 保证每个表都有主键,尽可能像where子句那样使用它。
- 在对update或delete使用where子句之前,应该先用select进行测试,保证它过滤的是正确记录。
- 使用强制实施引用完整性的数据库,这样MySQL将不允许删除具有与其他表相关联的数据的行。
创建和操纵表
创建表
两种创建表的方法:
- 使用具有交互式创建和管理表的工具。
- 表也可以直接用MySQL语句操纵。
create table 表名
(
列名 类型 not null auto_increment,
primary key(列名)
)engine=InnoDB;
使用NULL值
NULL值就是没有值或缺值。允许NULL值的列也允许在插入行时不给出该列的值。不允许NULL值的列在插入或更新行时,该列必须有值。
主键
如果主键使用单个列,则它的值必须唯一。如果使用多个列,则这些列的组合值必须唯一。
primary key(列名1,列名2,...)
主键只能使用不允许NULL值的列。允许NULL值的列不能作为唯一标识。
使用auto_increment
auto_increment告诉MySQL,本列每当增加一行时自动增量,每个表只允许一个auto_increment列,而且它必须被索引(如,通过使它成为主键)。
last_insert_id()
函数返回最后一个auto_increment值。
指定默认值
如果在插入行时没有给出值,MySQL允许指定此时使用的默认值。默认值用default关键字指定。
列名 类型 NULL default 默认值
MySQL不允许使用函数作为默认值,它只支持常量。
使用默认值而不是NULL值
引擎类型
MySQL有一个管理和处理数据的内部引擎。在你使用create table语句时,该引擎具体创建表,而在你使用select语句或进行其他数据库处理时,该引擎在内部处理你的请求。
不同引擎具有各自不同的功能和特性,为不同任务选择正确的引擎能获得良好的功能和灵活性:
- InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索。
- MEMORY在功能等同于MyISAM,但由于数据存储在内存中,速度很快。
- MyISAM是一个性能极高的引擎,它支持全文本搜索,但不支持事务处理。
引擎类型可以混用,但外键不能跨引擎,即使用一个引擎的表不能引用具有使用不同引擎的表的外键。
你依赖于什么样的特性就使用什么引擎。
更新表
为更新表定义,可使用alter table
语句。但是在理想状态下,当表中存储数据以后,该表就不应该再被更新。
添加一列
alter table 表名
add 列名 类型;
删除一列
alter table 表名
drop column 列名;
定义外键
alter table 表名
add constraint 约束名
foreign key(列名) references 表名(列名);
删除表
使用drop table
语句:
drop table 表名
删除表没有确认也不能撤销,执行这条语句将永久删除该表。
重命名表
使用rename table
语句可以重命名一个表或多个表:
rename table 表名1 to 表名2;
rename table 表名1 to 表名2
表名3 to 表名4;
使用视图
视图
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
为什么使用视图
- 重用SQL语句。
- 简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节。
- 使用表的组成部分而不是整个表。
- 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限。
- 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
在视图创建之后,可以用与表基本相同的方式利用它们。
重要的是知道视图仅仅时用来查看存储在别处的数据的一种设施。视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的,在添加或更改这些表中的数据时,视图将返回改变过的数据。
视图的规则和限制
- 与表一样,视图必须唯一命名。
- 对于可以创建的视图数目没有限制。
- 为了创建视图,必须具有足够的访问权限。这些限制通常由数据库管理人员授予。
- 视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造一个视图。
- 视图不能索引,也不能有关联的触发器或默认值。
- 视图可以和表一起使用。
使用视图
- 视图用
create view
语句来创建。 - 使用
show create view viewname;
来查看创建视图的语句。 - 用
drop
删除视图,其语法为drop view viewname;
。 - 更新视图时,可以先用
drop
再用create
,也可以直接用create or replace view
。如果要更新的视图不存在,则第二条更新语句会创建一个视图;如果要更新的视图存在,则第二条更新语句会替换原有视图。
利用视图简化复杂的联结
视图最常见的应用之一是隐藏复杂的SQL:
create view 视图名 as
select 列名1,列名2
from 表名1,表名2
where 表名1.列名3=表名2.列名3;
用视图重新格式化检索出的数据
create view 视图名 as
select concat(trim(列名1),'(',trim(列名2),')') as 别名
from 表名
order by 列名;
用视图过滤不想要的数据
视图对于应用普通的where子句也很有用。
过滤某个列名为空的行:
create view 视图名 as
select 列名1
from 表名
where 列名2 is not null;
如果从视图检索数据时使用了一条where子句,则两组子句将自动组合。
更新视图
通常视图是可更新的。更新一个视图将更新其基表。
但是,并非所有视图都是可更新的。如果MySQL不能正确地确定被更新的基数据,则不允许更新。
如果视图定义中有以下操作,则不能进行视图的更新:
- 分组
- 联结
- 子查询
- 并
- 聚集函数
- distinct
- 导出列
使用存储过程
存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然它们的作用不仅限于批处理。
为什么要使用存储过程
- 通过把处理封装在容易使用的单元中,简化复杂的操作。
- 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一存储过程,则所使用的代码都是相同的。
- 简化对变动的管理。如果表名、列名或业务逻辑有变化,只需要更改存储过程的代码。使用它的人员甚至不需要知道这些变化。
- 提高性能。因为使用存储过程比使用单独的SQL语句要快。
- 存在一些只能用在单个请求中的MySQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码。
使用存储过程
执行存储过程
MySQL称存储过程的执行为调用,因此MySQL执行存储过程的语句为call
。call
接受存储过程的名字以及需要传递给它的任意参数。
call 存储过程名(@参数1,@参数2);
创建存储过程
以一个返回产品平均价格的存储过程为例:
create procedure productpricing()
begin
select avg(prod_price) as priceaverage
from products;
end
如果你使用的是MySQL命令行实用程序,默认的MySQL语句分隔符为;。MySQL命令行实用程序也使用;作为语句分隔符。如果命令行实用程序要解释存储过程自身内的;字符,则它们最终不会成为存储过程的成分,这会使存储过程中的sql出现语法错误。
解决办法就是临时更改命令行实用程序的语句分隔符:
delimiter //
create procedure productpricing()
begin
select avg(prod_price) as priceaverage
from products;
end //
delimiter ;
使用这个存储过程:
call productpricing();
删除存储过程
存储过程在创建之后,被保存在服务器上以供使用,直至被删除。
drop procedure productpricing;
仅当存在时删除:
drop procedure if exists
使用参数
一般,存储过程不显示结果,而是把结果返回给你指定的变量。
变量:内存中一个特定的位置,用来临时存储数据。
delimiter //
create procedure productpricing(out pl decimal(8,2),out ph decimal(8,2),out pa decimal(8,2))
begin
select min(prod_price)
into pl
from products;
select max(prod_price)
into ph
from products;
select avg(prod_price)
into pa
from products;
end //
delimiter ;
此存储过程接受三个参数:pl、ph、pa。关键字out
指出相应的参数用来从存储过程传出一个值(返回给调用者)。
MySQL支持in
(传递给存储过程)、out
(从存储过程传出)和inout
(对存储过程传入和传出)类型参数。
存储过程的代码位于begin和end语句内,它们是一系列select语句,用来检索值,然后保存到相应的变量(通过指定into
关键字)。
调用此存储过程:
call productpricing (@pricelow,@pricehigh,@priceavg);
所有MySQL变量都必须以@开始。
获得值:
select @pricelow,@pricehigh,@priceavg;
另一个例子:
delimiter //
create procedure ordertotal(in onumber int,out ototal decimal(8,2))
begin
select sum(item_price*quantity)
from orderitems
where order_num=onumber
into ototal;
end //
delimiter ;
调用:
call ordertotal(20005,@total);
select @total;
建立智能存储过程
场景:获得合计、把营业税有条件地添加到合计、返回合计。
delimiter //
create procedure ordertotal(in onumber int,in taxable boolean,out ototal decimal(8,2)) comment 'obtain order total, optionally adding tax'
begin
declare total decimal(8,2);
declare taxrate int default 6;
select sum(item_price*quantity)
from orderitems
where order_num=onumber
into total;
if taxable then
select total+(total/100*taxrate) into total;
end if;
select total into ototal;
end //
delimiter ;
call ordertotal(20005,0,@total);
select @total;
在存储过程体中,用declare
语句定义了两个局部变量。declare
要求指定变量名和数据类型,它支持可选的默认值。if
语句检查taxable是否为真(非零值都考虑为真,只有0被视为假),如果为真,则用另一select语句增加营业税到局部变量total。最后用另一select语句将total保存到ototal。
comment
关键字给出的内容将在show procedure status
的结果中显示。
检查存储过程
显示用来创建一个存储过程:
show create procedure 存储过程名;
为了获得包括何时、由谁创建等详细信息的存储过程列表,使用:
show procedure status like '存储过程名'
使用游标
游标是一个存储在MySQL服务器上的数据库查询。它不是一条select语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。
有时,需要在检索出来的行中前进或后退一行或多行,这就是使用游标的原因。
MySQL游标只能用于存储过程。
使用游标
步骤:
- 在能够使用游标前,必须声明它。这个过程实际上没有检索数据,它只是定义要使用的select语句。
- 一旦声明后,必须打开游标以供使用。这个过程用前面定义的select语句把数据实际检索出来。
- 对于填有数据的游标,根据需要取出各行。
- 在结束游标使用时,必须关闭游标。
创建游标
declare
语句命名游标,并定义相应的select
语句,根据需要带where
和其他子句。
delimiter //
create procedure processorders()
begin
declare ordernumbers cursor
for
select order_num from orders;
end //
delimiter ;
存储过程处理完后,游标就消失了。
打开和关闭游标
delimiter //
create procedure processorders()
begin
declare ordernumbers cursor
for
select order_num from orders;
open ordernumbers;
close ordernumbers;
end //
delimiter ;
在一个游标关闭后,如果没有重新打开,则不能使用它。但是,使用声明过的游标不需要再次声明,用open语句打开它就行。
使用游标数据
在一个游标被打开后,可以使用fetch
语句分别访问它的每一行。
fetch
指定检索什么数据(所需的列),检索出来的数据存储在什么地方。
它还向前移动游标中的内部行指针,使下一条fetch
语句检索下一行(不能重复读取同一行)。
delimiter //
create procedure processorders()
begin
declare done boolean default 0;
declare o int;
declare t decimal(8,2);
declare ordernumbers cursor
for
select order_num from orders;
declare continue handler for sqlstate '02000' set done=1;
create table if not exists ordertotals(order_num int,total decimal(8,2));
open ordernumbers;
repeat
fetch ordernumbers into o;
call ordertotal(o,1,t);
insert into ordertotals(order_num,total)values(o,t);
until done end repeat;
close ordernumbers;
end //
delimiter ;
其中,declare continue handler for sqlstate '02000' set done=1;
,这条语句定义了一个continue handler
,它是在条件出现时被执行的代码。这里,它指出当sqlstate '02000'
出现时,set done=1。
sqlstate '02000'
是一个未找到条件,当repeat
由于没有更多的行供循环而不能继续时,出现这个条件。
declare语句的次序:用declare语句定义的局部变量必须在定义任意游标或句柄之前定义,而句柄必须在游标之后定义。
使用触发器
如果需要在某个表发生更改时自动处理,就要使用触发器。触发器响应以下任意语句而自动执行的一条MySQL语句(或位于begin和end语句之间的一组语句):
- delete
- insert
- update
其他MySQL语句不支持触发器。
创建触发器
创建触发器时,需要给出4条信息:
- 唯一的触发器名
- 触发器关联的表
- 触发器应该响应的活动
- 触发器何时执行
只有表支持触发器,视图不支持。
每个表每个事件每次只允许一个触发器。因此,每个表最多支持6个触发器(每条insert、delete和update的之前和之后)。
create trigger newordertotals after insert on ordertotals for each row select 'added' into @arg;
insert into ordertotals values(11111,111);
select @arg;
删除触发器
drop trigger 触发器名
使用触发器
创建只有一个执行语句的触发器
创建有多个执行语句的触发器
管理事务处理
事务处理可以用来维护数据库的完整性,它保证成批的MySQL要么完全执行,要么完全不执行。
事务处理是一种机制,用来管理必须成批执行的MySQL操作,以保证数据库不包含不完整的操作结果。利用事务处理,可以保证一组操作不会中途停止,它们或者作为整体执行,或者完全不执行。如果没有错误发生,整租语句提交给数据库表。如果发生错误,则进行回退以恢复数据库到某个已知且安全的状态。
几个术语:
- 事务:一组sql语句
- 回退:撤销指定sql语句的过程
- 提交:将未存储的sql语句结果写入数据库表
- 保留点:事务处理中设置的临时占位符,可以对它发布回退。
控制事务处理
管理事务处理的关键在于将sql语句组分解为逻辑块,并明确规定数据何时应该回退,何时不应该回退。
MySQL使用start transaction
来表示事务的开始。
使用rollback
rollback回退start transaction之后的所有语句。
事务处理用来管理insert、update和delete语句。你不能回退select语句,不能回退create或drop操作。事务处理块中可以使用这两条语句,但如果你执行回退,它们不会被撤销。
select * from ordertotals;
start transaction;
delete from ordertotals;
select * from ordertotals;
rollback;
select * from ordertotals;
rollback只能在一个事务处理内使用。
使用commit
一般MySQL语句都是直接针对数据库表执行和编写的。这就是所谓的隐含提交,即提交操作是自动进行的。
但是,在事务处理块中,提交不会隐含地进行。为进行明确提交,使用commit。
start transaction;
delete from orderitems where order_num = 1;
delete from orders where order_num=1;
commit;
如果第一条delete成功,第二条失败,则delete不会提交,被自动撤销。
使用保留点
更复杂的事务处理需要部分提交或回滚。
为了支持回滚部分事务处理,必须能在事务处理块中合适的位置放置占位符。这样,如果需要回退,可以回退到某个占位符。
占位符称为保留点。
savepoint 保留点名;
每个保留点都取标识它的唯一名字。为了回退到保留点,如下进行:
rollback to 保留点名;
保留点越多越好。
保留点在事务处理完成后自动释放,也可以用release savepoint
明确地释放保留点。
更改默认的提交行为
默认的MySQL行为是自动提交所有更改。为了指示MySQL不自动提交更改,使用以下语句:
set autocommit=0;
autocommit标志是针对每个连接而不是服务器的。
全球化和本地化
字符集:字母和符号的集合。
编码:为某个字符集成员的内部表示。
校对:规定字符如何比较的指令。
使用字符集和校对顺序
查看支持的字符集完整列表:
show character set;
查看所支持校对的完整列表:
show collation;
它显示所有可用的校对,以及它们适用的字符集。
可以在创建数据库时指定默认的字符集和校对。为了确定所用的字符集和校对,可以使用以下语句:
show variables like 'character%';
show variables like 'collation%';
实际上,字符集很少是服务器范围的设置。不同的表甚至不同的列都可能需要不同的字符集,而且两者都可以在创建表时指定。
create table 表名(
)default character set 字符集名
collate 校对名;
MySQL还允许对每个列设置它们:
create table 表名(
列名 类型 character set 字符集名 collate 校对名
);
校对在对用order by
子句检索出来的数据排序时起重要作用。
如果你需要用于创建表时不同的校对顺序排序指定的select语句,可以在select语句自身中进行:
select * from 表名 order by 列名 collate
安全管理
在现实世界的日常工作中,决不能使用root。应该创建一系列的账号,有的用于管理,有的供用户使用,有的供开发人员使用。
管理用户
MySQL用户账号和信息存储在名为mysql的MySQL数据库中。一般不需要直接访问mysql数据库和表,但有时需要直接访问。
需要直接访问它的时机之一是在需要获得所有用户账号列表时。
use mysql;
select user from user;
创建用户账号
create user 用户名 identified by '口令';
identified by
指定的口令为纯文本。
删除用户账号
drop user 用户名;
设置访问权限
在创建用户账号后,必须接着分配访问权限。新创建的用户账号没有访问权限。它们能登陆MySQL,但不能看到数据,不能执行任何数据库操作。
为了能看到赋予用户账号的权限,使用:
show grants for 用户名;
usage
表示根本没有权限,表示在任意数据库和任意表上对任何东西没有权限。
MySQL权限用用户名和主机名结合定义user@host
。如果不指定主机名,则使用默认的主机名%。
设置权限:
grant 权限 on 被授予访问权限的数据库或表 to 用户名;
示例:
grant select on crashcourse.* to ben;
grant
的反操作为revoke
,用来撤销特定的权限。
revoke select on crashcourse.* from ben;
grant
和revoke
可在几个层次上控制访问权限:
- 整个服务器,使用
grant all
和revoke all
。 - 整个数据库,使用
on databases.*
。 - 特定的表,使用
on database.table
。 - 特定的列。
- 特定的存储过程。
可授予或撤销的每个权限可查找相关资料。
更改口令
set password for 用户名 = '口令';
设置自己的口令:
set password = '口令';
数据库维护
备份数据
- 使用命令行实用程序
mysqldump
转储所有数据库内容到某个外部文件。 - 可用命令行实用程序
mysqlhotcopy
从一个数据库复制所有数据。 - 可以使用MySQL的
backup table
或select into outfile
转储所有数据到某个外部文件。
为了保证所有数据被写到磁盘(包括索引数据),可能需要在进行备份前使用flush tables
语句。