5. 数据库设计与多表查询

一. 数据库设计基础

1. 设计概念

数据库设计是软件研发过程中很重要的一个环节,在学习数据库设计之前,要先了解软件研发的步骤。

一个成熟的软件,从想法的产生到成功上线,要经历需求调研及分析,设计,编码,测试和部署等过程,在开始阶段产品经理会根据客户的需求设计产品原型,而设计一般有架构师和开发工程师完成,这其中就包括数据库设计,还有软件结构设计,接口设计等,接着就是由开发工程师来编写代码,由测试工程师来测试,接着就可以部署上线。

image.png|675

数据库设计就是根据业务系统的具体需求,结合我们所选用的 DBMS,为这个业务系统构造出最优的数据存储模型。通俗的说就是建立数据库中的表结构以及表与表之间的关联关系的过程,分析有哪些表,哪些字段等。

数据库设计分为以下几个步骤:

  • 需求分析
  • 逻辑分析
  • 物理分析
  • 维护设计

2. 表的关系

表和表之间的关系有一对一的关系,主要用于表的拆分,利于把常用数据和不常用数据分开存储,提高查询的效率。一对多或者多对一的关系,例如部门表和员工表的关系,多对多的关系,例如商品和订单的关系。

一对多的关系中,在表示多的一方建立外键,指向另一方的主键,示例:

-- 删除表
DROP TABLE IF EXISTS tb_emp;
DROP TABLE IF EXISTS tb_dept;
-- 部门表
CREATE TABLE tb_dept(
id int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
-- 员工表
CREATE TABLE tb_emp(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键 dep_id,关联 dept 表的id主键
CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES tb_dept(id)
);

查看两表结构模型:

image.png|475

多对多的关系中,建立第三张中间表,中间表至少包含两个外键,分别关联两方主键,例如商品表和订单表。示例:

-- 删除表
DROP TABLE IF EXISTS tb_order_goods;
DROP TABLE IF EXISTS tb_order;
DROP TABLE IF EXISTS tb_goods;

-- 订单表
CREATE TABLE tb_order(
    id int primary key auto_increment,
    payment double(10,2),
    payment_type TINYINT,
    status TINYINT
);

-- 商品表
CREATE TABLE tb_goods(
    id int primary key auto_increment,
    title varchar(100),
    price double(10,2)
);

-- 订单商品中间表
CREATE TABLE tb_order_goods(
    id int primary key auto_increment,
    order_id int,
    goods_id int,
    count int
);

-- 建完表后,添加外键
alter table tb_order_goods add CONSTRAINT fk_order_id FOREIGN key(order_id) REFERENCES
tb_order(id);
alter table tb_order_goods add CONSTRAINT fk_goods_id FOREIGN key(goods_id) REFERENCES
tb_goods(id);

查看两表的结构模型:

image.png|500

一对一的关系中,在任意一方加入外键,关联另一方主键,并且设置外键为唯一(UNIQUE),例如用户和用户详情。

示例:

create table tb_user_desc (
    id int primary key auto_increment,
    city varchar(20),
    edu varchar(10),
    income int,
    status char(2),
    des varchar(100)
);
create table tb_user (
    id int primary key auto_increment,
    photo varchar(100),
    nickname varchar(50),
    age int,
    gender char(1),
    desc_id int unique,
-- 添加外键
CONSTRAINT fk_user_desc FOREIGN KEY(desc_id) REFERENCES tb_user_desc(id)
);
image.png|500

二. 多表联合查询

前面学习查询操作时,一直是从一张表中查询数据,而数据库的多表查询操作也是非常重要的一部分。多表查询就是一次性从多张表中查询出需要的数据。

在MySQL中多表查询分为连接查询和子查询,而连接查询又分为内连接查询和外连接查询,外连接查询的方式有左外连接查询和右外连接查询。下面对多表查询做一些基础的练习!

下面是演示多表查询使用的 sql:

DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;

# 创建部门表
CREATE TABLE dept(
    did INT PRIMARY KEY AUTO_INCREMENT,
    dname VARCHAR(20)
);
# 创建员工表
CREATE TABLE emp (
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(10),
    gender CHAR(1), -- 性别
    salary DOUBLE, -- 工资
    dep_id INT,
    FOREIGN KEY (dep_id) REFERENCES dept(did) -- 外键,关联部门表(部门表的主键)
);
-- 添加部门数据
INSERT INTO dept (dNAME) VALUES ('研发部'),('财务部'),('销售部');
-- 添加员工数据
INSERT INTO emp(NAME,gender,salary,dep_id) VALUES
('小张','男',3000,1),
('小李','女',3600,2),
('小王','男',9000,2),
('小美','女',5000,null);

执行 sql ,创建表:

image.png|500

1. 内连接查询

内连接查询分为隐式内连接查询和显式内连接查询,表示查询 A 集合和 B 集合的交集。

image.png|500

语法:

-- 隐式内连接查询
SELECT 字段列表 FROM 表1,表2… WHERE 条件;

-- 显示内连接查询
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 条件;

隐式内连接查询示例:

select * from emp,dept where dep_id=did;

结果:

image.png|500

显式内连接查询示例:

select * from emp inner join dept on dep_id=did;

结果:

image.png|500

2. 外连接查询

外连接查询分为作为连接查询和右外连接查询。左外连接查询:相当于查询A表所有数据和交集部分数据。

image.png|500

右外连接查询:相当于查询B表所有数据和交集部分数据。

|500

语法:

-- 左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;

-- 右外连接
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;

左外连接查询示例:

select * from emp left outer join dept on dep_id=did;

结果:

image.png|500

右外连接查询示例:

select * from emp right outer join dept on dep_id=did;

结果:

image.png|500

3. 子查询

子查询是指查询中嵌套有查询,以下的几种情况通常使用嵌套查询:

子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断,例如查询员工中工资大于小李的员工信息:

select * from emp where salary >(select salary from emp where name='小李');

结果:

image.png|500

子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断,例如查询研发部和财务部员工信息:


select * from emp where dep_id in (select did from dept where dname='研发部' or dname= '财务部');

结果:

image.png|500

子查询语句结果是多行多列,子查询语句作为虚拟表,例如查询员工中工资大于3000的员工的信息和部门信息:

select * from (select * from emp where salary>3000) t1, dept where t1.dep_id=dept.did;
image.png|500

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇