交互式 SQL
实验目的
通过进行给定使用场景下的 SQL 语句编写和运行,理解 SQL 语句的执行过程。
实验环境
- 本次实验使用 MySQL Community 8.0.12.0 版。
- 本次实验使用了 MySQL Workbench 工具。
- 操作系统同 实验一。
实验内容和完成情况
本次使用的数据库内容
| maker | model | type |
|---|---|---|
| A | 1001 | pc |
| A | 1002 | pc |
| A | 2004 | laptop |
| B | 1003 | pc |
| B | 1004 | pc |
| B | 2005 | laptop |
| C | 1005 | pc |
| C | 2006 | laptop |
| C | 2007 | laptop |
| model | speed | ram | hd | price |
|---|---|---|---|---|
| 1001 | 2.66 | 1024 | 250 | 2114 |
| 1002 | 2.10 | 512 | 250 | 995 |
| 1003 | 1.42 | 512 | 80 | 478 |
| 1004 | 2.80 | 1024 | 250 | 649 |
| 1005 | 3.15 | 2048 | 500 | 4028 |
| model | speed | ram | hd | screen | price |
|---|---|---|---|---|---|
| 2004 | 2.00 | 512 | 60 | 13.3 | 1150 |
| 2005 | 2.16 | 1024 | 120 | 17.0 | 2500 |
| 2006 | 5.00 | 4096 | 500 | 17.0 | 6094 |
| 2007 | 3.58 | 4028 | 120 | 14.5 | 4000 |
数据定义
模式的创建与删除
-
为当前用户创建一个名为
computer_products的模式。1
CREATE SCHEMA `computer_products`;
![]()
![]()
![]()
![]()
- MySQL 创建模式时不需要
AUTHORIZATION子句。 - 创建完模式后,需要双击
computer_products或使用use computer_products;命令进入该模式。 - 应当进行已有数据库的检查,若已存在,则先删除再插入。其实采用以下语句会更加科学。
1
2DROP SCHEMA IF EXISTS `computer_products`;
CREATE SCHEMA IF NOT EXISTS `computer_products`; - MySQL 创建模式时不需要
-
本次实验已结束,本模式不再需要。请删除
computer_products模式。1
DROP SCHEMA computer_products;
![]()
![]()
![]()
执行成功后,SCHEMAS 栏中不再有此模式(见最右图)。
基本表的创建与删除
-
创建计算机产品数据库的 Product 表、PC 表和 Laptop 表。
1
2
3
4
5create table Product(
maker char(2),
model int(4) primary key,
type char(10)
);1
2
3
4
5
6
7
8create table PC(
model int(4) primary key,
speed float(3),
ram int(5),
hd int(4),
price int(5),
foreign key (model) references Product(model)
);1
2
3
4
5
6
7
8
9create table Laptop(
model int(4) primary key,
speed float(3),
ram int(5),
hd int(4),
screen float(2),
price int(5),
foreign key (model) references Product(model)
);![]()
![]()
![]()
![]()
![]()
![]()
- MySQL 中引用外码的写法是
FOREIGN KEY (<外码列名>) REFERENCES <表名>(<引用列名>)。 - 后来,我将 screen 和 speed 的数据类型改为了
decimal(MySQL 中不支持 numeric 的写法),在后面的数据查找操作中会简单讲下为什么要这样做。
- MySQL 中引用外码的写法是
-
为 PC 表中加入屏幕尺寸列,取值为一位小数。
1
ALTER TABLE pc ADD COLUMN screen FLOAT(1);
![]()
![]()
-
为统计屏幕尺寸创建了一个新表 screen,现在统计结束,不再需要此表。
1
DROP TABLE screen;
![]()
![]()
![]()
索引的建立与删除
-
按照降序序列建立 PC 表中价格的索引。
1
CREATE INDEX pc_price ON pc(price DESC);
![]()
![]()
![]()
-
1 中的索引不再需要,请删除
pc_price索引。1
DROP INDEX pc_price ON pc;
![]()
![]()
在 MySQL 中,
drop index语句中也有on子句,需要指定索引所在表。
数据操作
数据更新
-
向计算机产品数据库中添加给定数据。
![]()
![]()
![]()
![]()
![]()
![]()
在 MySQL 中,
VALUES子句可以一次插入多组值。 -
将所有硬盘容量为 120GB 的笔记本的价格下调 200 元。
1
2
3UPDATE laptop
SET price=price-200
WHERE hd=120;![]()
![]()
-
型号为 2004 的电脑已经停产,请删除其相关记录。
1
2
3DELETE
FROM laptop
WHERE model=2004;![]()
![]()
数据查询
-
(单表查询)查询制造商 A 的所有产品,按照产品序列号降序排列。
1
2
3SELECT * FROM product
where maker='A'
ORDER BY model DESC;![]()
![]()
-
(连接查询 I)查询生产了速度为 2.80 的 PC 机制造商。
1
2
3SELECT maker FROM product, pc
WHERE product.model=pc.model
AND speed=2.8;![]()
![]()
由于浮点数比较问题,这里的 speed 若是 float 或 double 类型,则会查找失败!
解决方案:将 speed 设为 decimal (dec) 类型。 -
(连接查询 II)计算制造商 C 生产的所有笔记本的总价格。
1
2
3
4SELECT SUM(price)
FROM product, laptop
WHERE maker IN('C')
AND product.model=laptop.model;![]()
![]()
-
(嵌套查询 I)查询生产了型号为 2007 号笔记本的厂商都生产了哪些产品和型号。
1
2
3
4
5
6SELECT model, type
FROM product
WHERE maker IN (SELECT maker
FROM product, pc, laptop
WHERE (product.model=pc.model OR product.model=laptop.model)
AND product.model=2007);![]()
![]()
-
(嵌套查询 II)查询硬盘容量比所有 PC 机都小的笔记本电脑的型号及其硬盘容量大小。
1
2
3SELECT model, hd
FROM laptop
WHERE hd<ALL(SELECT hd FROM pc);![]()
![]()
-
(集合查询)查询所有硬盘容量为 500G 的电脑型号及其类型。
1
2
3
4
5
6
7SELECT product.model,type
FROM laptop, product
WHERE product,model=laptop.model AND hd=500
UNION
SELECT product.model, type
FROM pc, product
WHERE product.model=pc.model AND hd=500;![]()
![]()
视图操作
在 MySQL 中,视图是一种虚拟表,它的数据并不存储在数据库中,而是通过查询语句动态生成。
-
(视图创建)建立笔记本电脑所有信息的视图。
1
2
3
4
5
6CREATE VIEW laptop_info AS
SELECT maker, speed, ram, hd, price
FROM product, laptop
WHERE
type IN ('laptop')
AND product.model=laptop.model;![]()
![]()
![]()
-
(视图更新)将制造商 C 的所有笔记本价格上调 200 元。
1
2
3
4SET SQL_SAFE_UPDATES=0;
UPDATE laptop_info
SET price=price+200
WHERE maker='C';![]()
![]()
-
(视图查询)在笔记本中找出屏幕大小为 17 寸的所有产品信息。
1
2SELECT * FROM laptop_info
WHERE screen=17;![]()
![]()
若 screen 的数据类型为 double 或 float,类似于数据查询,也会导致查询失败!
-
(视图删除)删除笔记本电脑信息视图。
1
DROP VIEW laptop_info;
![]()
![]()
遇到的问题和解决方案
-
使用 update 命令更新数据时出现 1175 错误。提示信息如下:
1
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
MySQL 有个叫
SQL_SAFE_UPDATES的变量,为了数据库更新操作的安全性,此值默认为1,所以才会出现更新失败的情况。所以,出现 1175 错误的时候,可以先设置SQL_SAFE_UPDATES的值为0,然后再执行更新。对于上例来说,直接在前面加上一句SET SQL_SAFE_UPDATES = 0;即可解决问题。 -
在 MySQL 中,
CREATE DATABASE和CREATE SCHEMA的区别是什么?“CREATE DATABASE creates a database with the given name. To use this statement, you need the CREATE privilege for the database. CREATE SCHEMA is a synonym for CREATE DATABASE.”
CREATE DATABASE根据给定的名称创建数据库,你需要拥有数据库的CREATE权限来使用这个语句。CREATE SCHEMA是CREATE DATABASE的一个代名词。由此可见,在 MySQL 的语法操作中(MySQL5.0.2 之后),可以使用CREATE DATABASE和CREATE SCHEMA来创建数据库,两者在功能上是一致的。在使用 MySQL 官方的 MySQL 管理工具 MySQL Workbench 5.2.47 创建数据库时,使用的是CREATE SCHEMA来创建数据库的。而这和 MS SQL 中的SCHEMA有很大差别。 -
在 MySQL 修改基本表中列的数据类型时,使用的命令是
CHANGE COLUMN。





















































