mysql多表操作简单理解

表与表之间的关系

  • ⼀对⼀关系:
    • 在实际的开发中应⽤不多.因为⼀对⼀可以创建成⼀张表.
    • 常⻅实例:身份证表与员⼯信息表
  • ⼀对多关系:
    • 常⻅实例:客户和订单,分类和商品,部⻔和员⼯, 省份和城市
  • 多对多关系:
    • 常⻅实例:学⽣和课程、⽤户和⻆⾊, 演员和电影, 商品和订单

外键约束

现在我们有tb_student和tb_score两张表,为了表明是哪个学生,我们添加id⼀列,⽤于存放学号信息,此列称为:外键

此时“学生表tb_student称为:主表,“id”我们称为主键。得分表tb_score称为:从表,stu_id称为外键。我们通过主表的主键和从表的外键来描述主外键关系,就这让表与表之间产⽣了关系。

  • 外键特点:
    • 从表外键的值是对主表主键的引⽤。
    • 从表外键类型,必须与主表主键类型⼀致。
  • 声明外键约束
    • 语法:
alter table 从表 add [constraint][外键名称] foreign key (从表外键字段名) references 主表 (主表的主键);
  • [外键名称]⽤于删除外键约束的,⼀般建议“_fk”结尾
alter table 从表 drop foreign key 外键名称

使⽤外键⽬的:

  • 保证数据完整性
    • 要考虑从表添加数据
    • 要考虑主键删除数据

提供表结构如下:

# 分类表
CREATE TABLE category (
    cid VARCHAR(32) PRIMARY KEY ,
    cname VARCHAR(50)
);
#商品表
CREATE TABLE products(
    pid VARCHAR(32) PRIMARY KEY ,
    pname VARCHAR(50),
    price INT,
    flag VARCHAR(2), #是否上架标记为:1表示上架、0表示下架
    category_id VARCHAR(32)
);

初始化数据

#分类
INSERT INTO category(cid,cname) VALUES('c001','家电');
INSERT INTO category(cid,cname) VALUES('c002','服饰');
INSERT INTO category(cid,cname) VALUES('c003','化妆品');
#商品
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p001','联想',5000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p002','海尔',3000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');
INSERT INTO products (pid, pname,price,flag,category_id)
VALUES('p004','JACK JONES',800,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p005','真维斯',200,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p006','花花公⼦',440,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p007','劲霸',2000,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p008','⾹奈⼉',800,'1','c003');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'1','c003');

多表关系实战

实战1:省和市

  • ⽅案1:多张表,⼀对多
-- 创建省份表
create table province(
    pid int PRIMARY KEY,
    pname varchar(32), -- 省份名称
    description varchar(100) -- 描述
);
-- 创建城市表
create table city (
    cid int PRIMARY KEY,
    cname varchar(32), -- 城市名称
    description varchar(100), -- 描述
    province_id int,
    CONSTRAINT city_province_fk foreign key(province_id) references province(pid)
);

  • ⽅案2:⼀张表,⾃关联⼀对多
create table area (
    id int PRIMARY key AUTO_INCREMENT,
    `name` varchar(32),
    description varchar(100),
    parent_id int,
    CONSTRAINT area_area_fk FOREIGN KEY(parent_id) REFERENCES area(id)
);
INSERT into area values(null, '辽宁省', '这是⼀个省份', null);
INSERT into area values(null, '⼤连市', '这是⼀个城市', 1);
INSERT into area values(null, '沈阳市', '这是⼀个城市', 1);
INSERT into area values(null, '河北省', '这是⼀个省份', null);
INSERT into area values(null, '⽯家庄市', '这是⼀个城市', 4);
INSERT into area values(null, '保定市', '这是⼀个城市', 4);

扫描二维码关注公众号,回复: 11498335 查看本文章

实战2:用户和角色

  • 多对多关系
-- ⽤户表
create table `user` (
    uid varchar(32) PRIMARY KEY,
    username varchar(32),
    `password` varchar(32)
);
-- ⻆⾊表
create table role (
    rid varchar(32) PRIMARY KEY,
    rname varchar(32)
);
-- 中间表
create table user_role(
    user_id varchar(32),
    role_id varchar(32),
    CONSTRAINT user_role_pk PRIMARY KEY(user_id,role_id),
    CONSTRAINT user_id_fk FOREIGN KEY(user_id) REFERENCES `user`(uid),
    CONSTRAINT role_id_fk FOREIGN KEY(role_id) REFERENCES role(rid)
);

多表查询(商品有好多分类,但都对应一个分类表)

# 分类表
CREATE TABLE category (
    cid VARCHAR(32) PRIMARY KEY ,
    cname VARCHAR(50)
);
#商品表
CREATE TABLE products(
    pid VARCHAR(32) PRIMARY KEY ,
    pname VARCHAR(50),
    price INT,
    flag VARCHAR(2), #是否上架标记为:1表示上架、0表示下架
    category_id VARCHAR(32),
    CONSTRAINT products_category_fk FOREIGN KEY (category_id) REFERENCES category (cid)
);

初始化数据

#分类
INSERT INTO category(cid,cname) VALUES('c001','家电');
INSERT INTO category(cid,cname) VALUES('c002','服饰');
INSERT INTO category(cid,cname) VALUES('c003','化妆品');
#商品
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p001','联想',5000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p002','海尔',3000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p004','JACK JONES',800,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p005','真维斯',200,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p006','花花公⼦',440,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p007','劲霸',2000,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p008','⾹奈⼉',800,'1','c003');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'1','c003');

多表查询

交叉连接查询(开发中不使⽤-得到的是两个表的乘积) 

  • 语法: select * from A,B;
select * from category,products ORDER BY cid, pid;

效果: category表中每条记录, 与 products表中每条记录分别连接

常⽤的多表查询⽅式(SQL JOINS 深色区域为查询结果集):

                              

内连接查询(使⽤的关键字 inner join -- inner可以省略)

  • 隐式内连接: select * from A,B where 条件;

  • 显示内连接: select * from A inner join B on 条件;

-- 查询那些分类的商品已经上架
-- 隐式内连接
SELECT DISTINCT
*
FROM
category c,
products p
WHERE
c.cid = p.category_id;
-- 显示内连接
SELECT DISTINCT
*
FROM
category c INNER JOIN products p
ON
c.cid = p.category_id;

外连接查询(使⽤的关键字 outer join -- outer可以省略)

  • 左外连接:left outer join

    • select * from A left outer join B on 条件;

  • 右外连接:right outer join

    • select * from A right outer join B on 条件;

#2.查询所有分类商品的个数
#左外连接
INSERT INTO category(cid,cname) VALUES('c004','奢侈品');
SELECT cname,COUNT(category_id)
FROM category c LEFT OUTER JOIN products p
ON c.cid = p.category_id
GROUP BY cname;

子查询

⼦查询:
⼀条select语句结果作为另⼀条select语法⼀部分(查询条件,查询结果,表等)。
语法:

select ....查询字段 ... from ... 表.. where ... 查询条件
-- ⼦查询, 查询“化妆品”分类上架商品详情
-- 内连接⽅式
select
p.*
from
category c, products p
WHERE
c.cid = p.category_id and c.cname = '化妆品'
-- ⼦查询⽅式 第⼀种(作为查询条件值使⽤)
select
*
from
products p
where
p.category_id = (SELECT cid from category where cname='化妆品')
-- ⼦查询⽅式 第⼆种(作为 ⼀张表 使⽤)
select
p.*
FROM
products p, (select * from category where cname='化妆品') c
WHERE
p.category_id = c.cid;

练习:

#查询“化妆品”和“家电”两个分类上架商品详情
select
*
from
products
WHERE
category_id in (select cid from category where cname='家电' or
cname='化妆品');
-- select cid from category where cname='家电' or cname='化妆品';
-- select cid from category where cname in ('家电', '化妆品');

猜你喜欢

转载自blog.csdn.net/weixin_40959890/article/details/107711609