数据合并、数据持久化和索引

前面文章中使用的user1和t3表中都包含了人员信息,如果需要同时查看两个表都包含的人员信息字段,可以使用数据合并功能,也称为联合(union)。

MySQL数据库中,数据合并就是使用union关键字将多个查询结果进行纵向合并,查询结果的字段名会使用第一个查询的字段名。下面是user1和t3表相关字段的对照表。

user1表字段t3表字段说明
usernamef1t3表中f1为员工编号,与username一样可作为系统的唯一标识。
fullnamef2姓名
sexf3性别

下面的代码会将user1表和t3表中三个字段的数据合并。

MySQL
use cdb_demo;

select username,fullname,sex from user1
union
select f1,f2,f3 from t3;

代码查询结果如下图所示。

合并查询结果

如果两个查询结果有完全相同的数据会怎么样呢?下面进行一些测试,首先在t3表中添加几条记录,代码如下。

MySQL
use cdb_demo;

insert into t3(f1,f2,f3)
values('user11','测试用户11',0),
('user12','测试用户12',0),
('user13','测试用户13',0),
('user14','测试用户14',0);

接下来再次执行前面的合并查询,可以看到,默认情况下重复数据会自动过滤,查询结果与t3表没有添加新记录时相同。需要显示所有数据时,可以在union关键字后添加all关键字,如下面的代码。

MySQL
use cdb_demo;

select username,fullname,sex from user1
union all
select f1,f2,f3 from t3;

查询结果如下图所示,可以看到,添加all关键字后,两个查询结果中相同的数据都会显示。

合并查询结果

为方便重复操作,同样可以将合并查询定义为视图,如下面的代码。

MySQL
use cdb_demo;

create view v_user1_t3
as
select username,fullname,sex from user1
union all
select f1,f2,f3 from t3;

创建视图后,可以直接使用“select * from v_user1_t3;”查询合并结果。

如果需要查看v_user1_t3视图的定义,可以使用如下代码。

MySQL
use cdb_demo;

show create view v_user1_t3;

从查询结果的“Create View”字段中可以得到完整的视图创建语句,需要时可以复制使用。

删除视图时可以使用drop view语句。下面的代码会删除v_user1_t3视图,然后创建不包含重复数据的新视图。

MySQL
use cdb_demo;

drop view v_user1_t3;

create view v_user1_t3
as
select username,fullname,sex from user1
union
select f1,f2,f3 from t3;

对于查询结果,还可以保存到数据表以方便进一步操作,称为数据的持久化。下面的代码会将v_user_t3视图的查询结果保存到t_user1_t3表中。

MySQL
use cdb_demo;

create table t_user1_t3 
as
select * from v_user1_t3;

执行语句后中,v_user1_t3视图的查询结果就会保存到新的t_user1_t3表,下面的代码可以查询表中的所有数据。

MySQL
use cdb_demo;

select * from t_user1_t3;

为了提高新表的数据查询效率,还可以对关键数据创建索引,语法如下。

MySQL
create index <索引名>
on <表名>(<字段名>)

下面的代码,会对t_user1_t3表的username字段数据创建索引。

MySQL
use cdb_demo;

create index ind_t_user1_t3_username 
on t_user1_t3(username);

索引应用的一些其本注意事项:

  • 表中的主键字段会自动创建索引。
  • 索引多用于数据唯一的字段,对于相同数据较多的字段一般不需要添加索引。
  • 对于经常作为条件查询的字段、排序的字段、分组的字段、统计的字段等可以创建索引以提高访问效率。
  • 对于经常增减数据的表或经常更新数据的字段不宜添加索引,因为数据变化时会重新创建索引数据,影响数据库整体性能。

删除索引时需要在alter table语句中使用drop index子句,如下面的代码。

MySQL
use cdb_demo;

alter table t_user1_t3
drop index ind_t_user1_t3_username;

需要将查询数据保存到一个已存在的表时,可以使用insert into...select语句。下面的代码,首先删除t3表中user11到user14的记录,因为user1表的username字段定义为唯一键,添加这些记录会有冲突。

MySQL
use cdb_demo;

delete from t3 
where f1 in ('user11','user12','user13','user14');

下面的代码会将t3表中的f1、f2、f3字段数据添加到user1表中,分别对应username、fullname、sex字段。

MySQL
use cdb_demo;

insert into user1(username,fullname,sex)
select f1,f2,f3 from t3;

执行后可以通过“select * from user1;”语句查询user1表的数据,结果如下图所示。

查询结果