MySQL高级查询与编程笔记 • 【第2章 数据定义和操作】
全部章节 >>>>
本章目录
2.1 数据定义语言和数据操作语言
2.1.1 设计“优乐网”数据库
“优乐网”是一个向用户提供日常生活商品和消费服务的团购平台,此系统满足以下需求:
- 系统支持生成商品的入库和出库。入库之后的商品可以在平台显示
- 所有用户都可以浏览系统的商品信息,只有注册用户才能订购团购商品和服务
- 系统支持订单数据自动生成
- 为方便用户检索所需的团购商品和服务信息,系统支持按商品和服务的类型、商家以及所在地区进行分类
根据上述需求,设计出“优乐网”数据库表结构
customer(客户表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
customerID | 客户编号 | int | 非空 | 主键,自增 |
login | 登录名 | varchar(20) | 非空 | --- |
pwd | 密码 | varchar(20) | 非空 | --- |
customerName | 客户姓名 | varchar(20) | 非空 | --- |
gender | 性别 | varchar(2) | 非空 | --- |
birthday | 客户生日 | date | --- | --- |
tel | 客户电话 | varchar(20) | --- | --- |
address | 客户住址 | varchar(50) | --- | --- |
area(区域表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
areaID | 地区编号 | int | 非空 | 主键,自增 |
areaName | 地区名 | varchar(20) | 非空 | --- |
p_areaID | 上级地区编号 | int | 非空 | 外键,参照本表主键 |
shop(商家表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
shopID | 商家编号 | int | 非空 | 主键,自增 |
shopName | 商家名 | varchar(20) | 非空 | --- |
shopAddress | 商家地址 | varchar(50) | --- | --- |
contact | 商家联系方式 | varchar(50) | --- | --- |
category(商品类型表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
categoryID | 类型编号 | int | 非空 | 主键,自增 |
categoryName | 类型名 | varchar(20) | 非空 | --- |
p_categoryID | 上级类型编号 | int | 非空 | 外键,参照本表主键 |
ordersdetail(订单明细表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
ordersID | 订单编号 | int | 非空 | 联合主键,外键,参照 orders 表 |
productID | 商品编号 | int | 非空 | 联合主键,外键,参照 product 表 |
quantity | 件数 | int | 非空 | --- |
product(商品表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
productID | 商品编号 | int | 非空 | 主键,自增 |
title | 商品标题 | varchar(20) | 非空 | --- |
productDesc | 描述 | text | --- | --- |
originalPrice | 原价 | decimal(10,2) | --- | --- |
currentPrice | 团购价 | decimal(10,2) | --- | --- |
picture | 商品图片地址 | varchar(100) | --- | --- |
isCommend | 是否被推荐 | varchar(10) | --- | --- |
salesCount | 累计销售数量 | int | --- | --- |
categoryID | 类型编号 | int | --- | 外键,参照 category 表 |
areaID | 地区编号 | int | --- | 外键,参照 area 表 |
shopID | 商家编号 | int | --- | 外键,参照 shop 表 |
orders(订单表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
ordersID | 订单编号 | int | 非空 | --- |
ordersDate | 下单时间 | date | --- | --- |
deliveryDate | 送达时间 | date | --- | --- |
amount | 订单金额 | decimal(10,2) | --- | --- |
customerID | 客户编号 | int | --- | 外键,参照 customer 表 |
2.1.2 数据定义语言
数据定义语言(Data Definition Language,DDL)是我们在创建表时用到的一些 SQL 语句,比如 create、alter、drop 等
DDL 主要是用在定义或改变表的结构、数据类型、表之间的连接和约束等初始化工作上
语法:
crerate database database_name
子语句:
查看数据库
show databases
删除数据库
drop database database_name
更改数据库名
rename database old_database_name to new_database_name
创建数据表:
create table table_name(
字段名 1, 数据类型【列级别约束条件】【默认值】,
字段名 2, 数据类型【列级别约束条件】【默认值】,
...
【列级别约束条件】
)
实例:使用 DDL 创建“锦途网”线路表 line
create table line(
lineID int auto_increment primary key, -- 主键,自动增长
lineName varchar(50), days int, price decimal(10,2),
vehicle varchar(10), hotel varchar(10), hasMeal char(2),
foreign key(lineTypeID) references linetype(lineTypeID) -- 外键,参照线路类型表主键
)
实例:使用 DDL 创建“优乐网”订单表 orders
create table orders(
ordersID int auto_increment primary key, -- 主键,自动增长
ordersDate date, -- 下单日期 deliveryDate date, -- 交付日期
amount decimal(10,2), -- 金额 customerID int, -- 客户 ID
foreign key(customerID) references customer(customerID) -- 外键,参照客户表主键 customerID
)
修改表结构的 DDL
语法:
alter table 表名 修改子句
新增字段修改子句表达式
add column_name data_type [not null] [default default_value]
变更字段子句表达式
change column_name new_column_name data_type [not null] [default default_value]
更新字段子句表达式
modify column_name new_data_type [not null] [default default_value]
删除字段子句表达式
drop column column_name
删除唯一约束子句表达式
drop unique constraint_name
修改供应商表内容
- 新增字段供应商地址 address,类型为 varchar(50)
- 将字段 mobile 更名为 tel,字段类型维持不变,仍为 varchar(20)
- 将字段 pName 的类型修改为 varchar(50),原类型为 varchar(20)
- 删除字段 contact
DDL 语句
alter table provider add address varchar(50), change mobile tel varchar(20),
modify pName varchar(50), drop column contact
2.1.3 数据操作语言
数据操作语言(Data Manipulation Language,DML)由 DBMS 提供,提供给用户或程序员使用,实现对数据库中数据的操作
DML 是在 SQL 语句中负责对数据库对象运行数据访问工作的指令集,以 insert、update、delete 3 种指令为核心,分别代表插入、更新与删除
语法:
insert [into] table_name[( 字段列表 )] values( 值列表 )
实例:新增一条线路
insert into line(lineName,days,price,lineTypeID) values(' 凤凰古城 ',3,959,1)
如果我们需要修改或更新 MySQL 中的数据,我们可以使用“update”SQL 语句来操作,该语句可以对表中的一行、多行甚至所有记录进行修改
语法:
update table_name set
字段名 1= 值 1, 字段名 2= 值 2, … , 字段名 n= 值 n;
[where 条件表达式 ]
update customer set city=concat(city,' 市 '), phone= concat('86',phone)
使用“delete from”SQL 语句来删除 MySQL 数据表中的记录
语法:
delete from table_name [where 条件表达式 ]
当删除有主从关系的表记录时,为避免发生删除时异常,一定要事先设置从表外键约束的“删除时”状态为 null,或者为“cascade”。
在通常情况下,都是设置从表外键约束的“删除时”状态为 null,而不是“cascade”,因为这样容易误删除从表数据。“不允许删除被从表引用的主表记录”这一法则,也符合现实的业务逻辑。
例如,企业根据业务重组的需要,裁减了某个部门,但这并不等同于把该部门的员工也一并裁员,而是将这个被裁减部门的员工分配至其他部门,或是暂定为“未分配”,在数据库中就是设置员工的部门信息为 null。
2.1.4 实践练习
2.2 数据查询
2.2.1 select 语句基本结构
select 语句是任何 SQL 语言中使用频率最高的语句,是 SQL 语言的灵魂
select 语句可以使数据库服务器根据客户的要求查询所需要的信息,并按规定的格式返回给客户。select 语句具有强大的查询功能,允许从一个表或多个表中选择满足给定条件的一个或多个行或列
select <column1, column2, column3 … > from <table_name>
[where < 条件表达式 >]
[group by column1, column2, column3 … | having < 条件表达式 >]
[order by < column1, column2, column3 … > [asc 或 desc]]
查询商家名和商家地址,要求采用别名显示查询结果
select shopName as 商家名 , shopAddress as 商家地址 from product shop
注意:为提高查询效率,使用 select 语句时需遵循“按需取材”的原则。即使用“select 字段 1,字段 2,… from 表”,其中的字段 1、字段 2…为所需查询的数据列,而不要使用“select * from 表”。
2.2.2 查询结果排序
- 使用“order by 字段 1,字段 2…”可以对查询结果按照“字段 1,字段 2…”的次序进行升序或降序显示
- 关键字 asc 表示升序(默认为升序,故升序时可省略 asc),desc 表示降序
- 除可在单列进行排序外,还可以按多列进行排序。多列排序的规则为:依照排序列从左至右的次序依次降低
查询在线影院售票系统中所有影片的电影名、导演名、票价和片长,按电影类型和片长排列,如果电影类型相同,则按片长降序排列
select movieName 电影名 ,director 导演名 ,ticketPrice 票价(元),filmLength 片长(分钟)
from movie order by typeId,filmLength desc
2.2.3 过滤重复字段
- 关键字“distinct”用于过滤重复的字段信息
查询所有影片的导演名,要求所显示的导演名不能重复
select distinct director from movie
2.2.4 限定指定的记录
在我们使用查询语句时,经常要返回前几条或者中间某几行数据。MySQL 提供的 limit 子句可以被用于强制select 语句返回指定的记录数
- 参数 offset 和 rows 必须为整数,offset 可以省略。
- offset 指定第一个返回记录行的偏移量。注意:初始记录行的偏移量是 0,而不是 1
- rows 指定返回记录行的最大数目
select * from table limit [offset,] rows
查询片长最短的前 5 个电影,显示电影名和片长
select movieName 电影名 ,filmLength 片长(分钟) from movie order by filmLength limit 0,5
2.2.5 模糊查询
在查询的过程中,如果遇到不能明确指明查询的限定条件时,就会用到模糊查询的 like 运算符进行模式匹配查询
在查询时可以使用如下几个通配符
- %:包含零个或多个字符的任意字符串
- _(下划线):任意单个字符
- []:指定范围(如 [a-d])或集合([abcdef])中的任意单个字符
- [^]:不属于指定范围(如 [^a-d])或集合([^abcdef])中的任意单个字符
查询所有黄姓演员的主要电影信息,显示电影名、导演名和主演
select movieName 电影名 ,filmLength 片长(分钟) from movie order by filmLength limit 0,5
2.2.6 实践练习
2.3 聚合函数和分组统计
2.3.1 在线影院售票系统数据库结构
customer(客户表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
id | 顾客编号 | int | 非空 | 主键,自增 |
username | 用户名 | varchar(20) | 非空 | --- |
password | 密码 | varchar(20) | 非空 | --- |
tel | 联系电话 | varchar(20) | --- | --- |
totalFee | 累计购票金额 | decimal(6,2) | --- | --- |
movie_type(电影类型表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
id | 电影类型编号 | varchar(10) | 非空 | 主键 |
typeName | 电影类型名 | varchar(20) | 非空 | --- |
movie(电影表)
列名 | 含义 | 数据类型 | 允许空 | 约束 |
id | 电影编号 | int | 非空 | 主键,自增 |
movieName | 电影名 | varchar(20) | 非空 | --- |
director | 导演名 | varchar(20) | --- | --- |
actors | 主演 | varchar(200) | --- | 多 个 演 员 以“、”分隔 |
filmLength | 片长(按分钟计) | int | --- | --- |
ticketPrice | 票价 | decimal(6,2) | --- | --- |
preferentialPrice | 优惠票价 | decimal(6,2) | --- | --- |
isActive | 优惠票价激活 | tinyint | --- | --- |
abstract | 电影简介 | text | --- | 0:未激活(默认值)1:激活 |
2.3.2 聚合函数
聚合函数是 SQL 基本函数,它对一组值执行计算,并返回单个值。除了 count() 函数以外,聚合函数都会忽略空值。聚合函数经常与 select 语句的 group by 子句一起使用
常用聚合函数:
函数名称 | 函数功能 |
sum() | 返回选取的某列值的总和 |
max() | 返回选取的某列值的最大值 |
min() | 返回选取的某列值的最小值 |
avg() | 返回选取的某列值的平均值 |
count() | 返回选取的某列值或记录的行数 |
获取电影的数量、最长片长、最短片长和平均片长
select count(*) 数量 ,max(filmLength)(分钟) 最长片长 ,min(filmLength) 最短片长(分钟),
avg(filmLength) 平均片长(分钟) from movie
计算平均片长还可以采用 sum(fileLength)/count(fileLength) 方式获得
select count(director) 导演信息不为空的电影数量 from movie
统计导演信息不为空的电影数量
count(*) 用于统计当前表所选取的行数,
count(col) 用于统计当前表所选取的 col 列值不为 null 的行数。
sum(col) 用于汇总当前表所选取的 col 列的值。简而言之,即 count 用于统计数据行数,sum 用于汇总数据。
2.3.3 group by 分组统计
使用 group by 子句可以将数据划分到不同的组中,实现对记录的分组统计
group by 从英文字面的意义上可以理解为“根据(by)一定的规则进行分组(group)”,该子句的作用是通过一定的规则将一个数据集划分成若干个小的区域,然后针对这若干个小区域进行统计汇总
语法:
group by 字段列表 [having 条件表达式 ]
按类型显示电影的数量、平均片长,最高票价,按票价、片长升序显示, 常规分组统计
select typeID 类型 ID,count(*) 数量 ,avg(filmLength) 平均片长(分钟),max(ticketPrice)
最高票价(元) from movie group by typeId order by avg(filmLength)
按类型显示票价不高于 100 元的电影的数量、平均片长,最高票价,按票价、片长升序显示,分组之前进行过滤
select typeID 类型 ID,count(*) 数量 ,avg(filmLength) 平均片长(分钟),max(ticketPrice)
最高票价(元) from movie where ticketPrice<=100 group by typeId order by avg(filmLength)
显示票价不高于 100 元的电影的数量、平均片长和最高票价,按票价片长升序显示平均片长不小于 100 分钟的统计信息,利用 having 子句对分组结果进行过滤
select typeID 类型 ID,count(*) 数量 ,avg(filmLength) 平均片长(分钟),max(ticketPrice)
最高票价(元) from movie where ticketPrice<=100 group by typeId
having avg(filmLength)>100 order by avg(filmLength)
2.3.4 实践练习
2.4 连接查询
2.4.1 内连接查询
内连接也称为连接,它还可以被称为完全匹配连接。由于内连接使用比较运算符比较每个表共有的列的值,所以内连接可能会丢失信息
语法:
Select fieldlist from table1 [inner] join table2 on table1.column1=table2.column2
一般情况下,column1 和 column2 为 table1 表与 table2表的主键和外键
显示战争类电影相关信息,要求输出电影名、导演名和票价
select movieName 电影名 ,director 导演名 ,ticketPrice 票价(元) from movie m
join movie_type mt on m.typeId=mt.id where mt.typeName=' 战争 '
2.4.2 简单多表连接查询
如果在 from 子句中,直接列出所有要连接的表,然后在 where 子句中指定连接条件,此为简单多表查询。简单多表连接查询是内连接查询的简单表现形式,它与内连接查询的功能相同
语法:
Select fieldlist from table1, table2 where table1.column1=table2.column2
显示战争类电影相关信息,要求输出电影名、导演名和票价
select movieName 电影名 ,director 导演名 ,ticketPrice 票价(元) from movie m,
movie_type mt where m.typeId=mt.id and mt.typeName=' 战争 '
2.4.3 外连接查询
在内连接查询中,只有满足连接条件的记录才能出现在查询结果中。但在实际应用中,如果希望不满足连接条件的记录也在查询结果中出现,这时就需要使用外连接查询
外连接可以是左外连接、右外连接或全连接
左外连接(left join) 结果集包括 left join 子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值
示例:采用左外连接方式显示所有电影的相关信息,要求输出电影名、导演名、票价和类型
select movieName 电影名 ,director 导演名 ,ticketPrice 票价(元),typeName 类型
from movie m left join movie_type mt on m.typeId=mt.id
非匹配行。来源于 右表列相应字段为空
右外连接(right join) 右外连接是左外连接的反向连接,它返回右表的所有行。如果右表的某行在左表中没有匹配行,则在相关联的结果集行中,表的所有选择列表列均为空值
示例:采用右外连接方式显示所有电影类型的相关信息,要求输出电影名、导演名、票价和类型
select movieName 电影名 ,director 导演名 ,ticketPrice 票价(元),typeName 类型
from movie m right join movie_type mt on m.typeId=mt.id
非匹配行。来源于 左表列相应字段为空
全连接(full join) 全连接返回左表和右表中的所有行,当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。MySQL 目前在语法上暂不支持全连接,但可以通过将左外连接和右外连接使用 union 进行连接来实现全连接
显示所有电影和所有类型的相关信息,要求输出电影名、导演名、票价和类型
select movieName 电影名 ,director 导演名 ,ticketPrice 票价(元),typeName 类型
from movie m left join movie_type mt on m.typeId=mt.id
union
select movieName 电影名 ,director 导演名 ,ticketPrice 票价(元),typeName 类型
from movie m right join movie_type mt on m.typeId=mt.id
全连接返回左表和 右表中的所有行
2.4.4 实践练习
总结:
- DDL 主要是用在定义或改变表的结构、数据类型、表之间的连接和约束等初始化工作上,DDL有 create、alter、drop 等语句
- DML 是在 SQL 语句中负责对数据库对象运行数据访问工作的指令集。DML 有insert、update、delete语句
- select 语句是任何 SQL 语言中使用频率最高的语句。可以对查询进行排序、过滤重复字段、限定指定的记录、模糊查询等
- 聚合函数经常与 select 语句的 group by 子句一起使用。连接查询有内连接查询和外连接查询。外连接可以是左外连接、右外连接或全连接
本文来自博客园,作者:明金同学,转载请注明原文链接:https://www.cnblogs.com/vmuu/p/15663382.html
公众号:【明金同学】