如何创建和使用 MySQL 视图

什么是 MySQL 视图?

MySQL 视图只是一个普通的数据库对象,如果使用得当,可以为 SQL 查询编写者节省大量时间。 视图是用户可以像表一样引用的存储查询。 很多时候,用户会发现自己一遍又一遍地使用相同的基本查询来解决多个问题。 视图是一种快速保存该查询并在以后引用它的方法。

使用视图有什么好处?

视图有几个优点。 首先,视图对 MySQL 用户来说就像一张表。 SELECT 子句可以像引用表一样引用视图。 另一个优点是,当视图引用的基础表发生变化时,视图的结果也会发生变化。 第三个优点是视图在服务器上占用的空间非常小。 每次访问时都会计算视图的 SQL 结果,因此在访问之前不会将它们存储在服务器上。

本练习的表格

在本文中,将创建一个数据库,其中包含有关虚构赛车赛季的信息,该赛季由三名车手、四条赛道和每条赛道上的一场比赛组成。 在这个数据库中,有四个表。

  • 驱动程序
  • 曲目
  • 比赛
  • 饰面

表的结构如下所述。

create table drivers
(
  id int auto_increment,
  name varchar(64) not null,
  car_number int not null,
  constraint drivers_pk
     primary key (id)
);
create table tracks
(
  id int auto_increment,
  name varchar(64) not null,
  location varchar(64) not null,
  constraint track_pk
     primary key (id)
);
create table races
(
  id int auto_increment,
  name varchar(64) not null,
  track int not null,
  distance int not null,
  constraint races_pk
     primary key (id)
);


create table finishes
(
  id int auto_increment,
  driver int not null,
  race int not null,
  position int not null,
  constraint finishes_pk
     primary key (id)
);

驱动程序

现在,在下一步中,我们将在表格中插入三个司机和他们的车号。

  • 巴迪贝克 28
  • 小戴尔·恩哈特 8
  • 瑞奇·路德 88
insert into drivers (name,car_number) values
  ('Buddy Baker',28),
  ('Dale Earnhardt Jr.',8),
  ('Ricky Rudd',88);

我们的结果现在将显示以下输出。

查看表

ID姓名车号
1巴迪贝克28
2小戴尔·恩哈特8
3瑞奇·路德88

赛马场

接下来,我们添加四个赛道及其位置。

  • 塔拉迪加超级高速公路 – 林肯,AL
  • 代托纳国际赛道 – 佛罗里达州代托纳比奇
  • 印第安纳波利斯赛车场 – 印第安纳州赛道
  • 密歇根国际赛车场 – 布鲁克林,密歇根
insert into tracks (name,location) values
  ('Talladega Superspeedway','Lincoln, AL'),
  ('Daytona International Speedway','Daytona Beach, FL'),
  ('Indianapolis Motor Speedway','Speedway, IN'),
  ('Michigan International Speedway','Brooklyn, MI');

我们的结果现在将显示以下输出。

查看表

ID姓名地点
1塔拉迪加高速公路林肯,铝
2代托纳国际赛道佛罗里达州代托纳比奇
3印第安纳波利斯赛车场赛道,印第安纳州
4密歇根国际赛道密歇根州布鲁克林

比赛

现在,输入了四场比赛,以及每场比赛的距离。

  • 代托纳 500 ,2,500
  • 塔拉迪加 500,1,500
  • 砖厂 400,3, 400
  • 密歇根州 400 ,4, 400
insert into races (name,track,distance) values
  ('Daytona 500',2,500),
  ('Talladega 500',1,500),
  ('Brickyard 400',3,400),
  ('Michigan 400',4,'400');

我们的结果现在将显示以下输出。

查看表

ID姓名追踪距离
1塔拉迪加 5002500
2代托纳 5001500
3砖厂 4003400
4密歇根 4004400

结果

最后,现在创建了赛季开始的表格。

在 Daytona 500 的第一场比赛中:

  • Ricky Rudd 获得第一名
  • Dale Earnhardt Jr 获得第二名
  • 巴迪贝克获得第三名。
insert into finishes (driver, race, position) values
  (1,1,3),
  (2,1,2),
  (3,1,1);

编译数据

第一个数据输入

现在有实际数据要查询。 如果我们运行一个查询来查看所有驱动程序的结果及其对应的赛道和比赛,这会有点复杂,因为有几个连接。

select d.name as driver,
     r.name as race,
     t.name as track,
     t.location as location,
     f.position as position
  from finishes f
  left join races r
     on f.race = r.id
  left join tracks t
     on r.track = t.id
  left join drivers d
     on d.id = f.driver;

我们的结果现在显示以下输出。

查看表

司机种族追踪地点位置
巴迪贝克代托纳 500代托纳国际赛道佛罗里达州代托纳比奇3
小戴尔·恩哈特代托纳 500代托纳国际赛道佛罗里达州代托纳比奇2
瑞奇·路德代托纳 500代托纳国际赛道佛罗里达州代托纳比奇1

第二个数据输入

作为第二场比赛,Talladega 500,添加了数据,可以再次编写查询,与之前的查询相同。 在这场比赛中,戴尔·恩哈特(Dale Earnhardt)位居第一,巴迪·贝克(Buddy Baker)位居第二。

insert into finishes (driver, race, position) values
  (1,2,2),
  (2,2,1),
  (3,2,3);

上述查询的结果将如下所示。

查看表

司机种族追踪地点位置
巴迪贝克代托纳 500代托纳国际赛道佛罗里达州代托纳比奇3
小戴尔·恩哈特代托纳 500代托纳国际赛道佛罗里达州代托纳比奇2
瑞奇·路德代托纳 500代托纳国际赛道佛罗里达州代托纳比奇1
巴迪贝克塔拉迪加 500塔拉迪加高速公路林肯,铝2
小戴尔·恩哈特塔拉迪加 500塔拉迪加高速公路林肯,铝1
瑞奇·路德塔拉迪加 500塔拉迪加高速公路林肯,铝3

创建视图

既然数据库中有多个种族,就有了查看结果的新方法。 可以为“最佳完成”和“最多获胜”编写查询。 这些查询都将从相同的基础数据开始,即车手在每场比赛的位置上完成了什么。 为了简化开发这些查询的过程,可以使用“create or replace view as”子句来创建视图。 该子句后跟要保存的 SQL。 在这种情况下,它被添加到我们上面显示的上一个查询之前。

create or replace view all_finishes as
select d.name as driver,
     r.name as race,
     t.name as track,
     t.location as location,
     f.position as position
  from finishes f
  left join races r
     on f.race = r.id
  left join tracks t
     on r.track = t.id
  left join drivers d
     on d.id = f.driver;

结果是 SQL 的一个强大功能。 这个结果现在看起来像一个表,但当新信息添加到任何基础表时会发生变化。 让我们运行这个查询。

select * from all_finishes;

查看表

司机种族追踪地点位置
巴迪贝克代托纳 500代托纳国际赛道佛罗里达州代托纳比奇3
小戴尔·恩哈特代托纳 500代托纳国际赛道佛罗里达州代托纳比奇2
瑞奇·路德代托纳 500代托纳国际赛道佛罗里达州代托纳比奇1
巴迪贝克塔拉迪加 500塔拉迪加高速公路林肯,铝2
小戴尔·恩哈特塔拉迪加 500塔拉迪加高速公路林肯,铝1
瑞奇·路德塔拉迪加 500塔拉迪加高速公路林肯,铝3

结果与我们上次运行此查询时相同:

不同的是,现在可以像表格一样查询视图。 显示每场比赛的获胜者的查询。

select * from all_finishes where position = 1;

查询 提供这些结果。

查看表

司机种族追踪地点位置
瑞奇·路德代托纳 500代托纳国际赛道佛罗里达州代托纳比奇1
小戴尔·恩哈特塔拉迪加 500塔拉迪加高速公路林肯,铝1

也可以编写查询以显示基于平均完成的领导者.

select avg(position) as finish,
  driver
from all_finishes
  group by driver
     order by finish;

这表明戴尔恩哈特在本赛季到目前为止处于领先地位:

查看表

结束司机
1.5小戴尔·恩哈特
2.0瑞奇·路德
2.5巴迪贝克

因为视图可以引用其他视图,所以可以使用这些查询创建更广泛的视图。

create view standings_leader as
select avg(position) as finish,
  driver
from all_finishes
  group by driver
     order by finish;

上述查询的结果将如下所示。

查看表

结束司机
1.5小戴尔·恩哈特
2.0瑞奇·路德
2.5巴迪贝克

也:

create view race_winners as
select * from all_finishes where position = 1;

这为我们提供了相同的结果。

查看表

司机种族追踪地点位置
瑞奇·路德代托纳 500代托纳国际赛道佛罗里达州代托纳比奇1
小戴尔·恩哈特塔拉迪加 500塔拉迪加高速公路林肯,铝1

添加数据

视图中最有效的部分是,当我们添加更多数据时,例如 Buddy Baker 赢得 Brickyard 400 和密歇根 400 的比赛结束时,我们可以查询我们的视图以获得相同的结果。

insert into finishes (driver, race, position) values
  (1,3,1),
  (2,3,3),
  (3,3,2);

insert into finishes (driver, race, position) values
  (1,4,1),
  (2,4,2),
  (3,4,3);

现在我们可以看到这个查询的所有完成。

select * from all_finishes;

上述查询的结果将如下所示。

查看表

司机种族追踪地点位置
巴迪贝克代托纳 500代托纳国际赛道佛罗里达州代托纳比奇3
小戴尔·恩哈特代托纳 500代托纳国际赛道佛罗里达州代托纳比奇2
瑞奇·路德代托纳 500代托纳国际赛道佛罗里达州代托纳比奇1
巴迪贝克塔拉迪加 500塔拉迪加高速公路林肯,铝2
小戴尔·恩哈特塔拉迪加 500塔拉迪加高速公路林肯,铝1
瑞奇·路德塔拉迪加 500塔拉迪加高速公路林肯,铝3
巴迪贝克砖厂 400印第安纳波利斯赛车场赛道,印第安纳州1
小戴尔·恩哈特砖厂 400印第安纳波利斯赛车场赛道,印第安纳州3
瑞奇·路德砖厂 400印第安纳波利斯赛车场赛道,印第安纳州2
巴迪贝克密歇根 400密歇根国际赛道密歇根州布鲁克林1
小戴尔·恩哈特密歇根 400密歇根国际赛道密歇根州布鲁克林2
瑞奇·路德密歇根 400密歇根国际赛道密歇根州布鲁克林3

我们还可以运行:

select * from race_winners;

这给了我们:

查看表

司机种族追踪地点位置
瑞奇·路德代托纳 500代托纳国际赛道佛罗里达州代托纳比奇1
小戴尔·恩哈特塔拉迪加 500塔拉迪加高速公路林肯,铝1
巴迪贝克砖厂 400印第安纳波利斯赛车场赛道,印第安纳州1
巴迪贝克密歇根 400密歇根国际赛道密歇根州布鲁克林1

此外,这导致系列冠军:

select * from standings_leader;

结果是:

查看表

结束司机
2巴迪贝克
2小戴尔·恩哈特
2瑞奇·路德

结论

当我们将查询保存在数据库服务器中(更具体地说是在数据库目录中)并为其命名时,这 新命名的查询称为数据库视图,或者, 更简单地说,一种观点。 MySQL 视图是保存重要和可重用查询的有效方式,可以帮助我们加快重要信息的检索. 因为这些保存视图可以引用其他视图,所以可以使用这些实质性查询创建更详细的视图。

评价我们!

我们以成为 Hosting™ 中最有帮助的人而自豪!

我们的支持团队由经验丰富的 Linux 技术人员和才华横溢的系统管理员组成,他们对多种网络托管技术有着深入的了解,尤其是本文中讨论的技术。

如果您对此信息有任何疑问,我们将随时为您解答与本文相关问题的任何询问,每天 24 小时、每周 7 天、每年 365 天。

如果您是完全托管的 VPS 服务器, Cloud 专用,VMWare 私有 Cloud私有父服务器, 托管 Cloud 服务器或专用服务器所有者并且您对执行概述的任何步骤感到不舒服,可以通过电话@800.580.4985 联系我们, 聊天 或支持票以帮助您完成此过程。