多表操作(外键)

多表操作

外键

外键(foreign key): 外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。

主表(父表):对于两个具有关联关系的表而言,相关联字段中的主键所在的那个表即是主表。

从表(子表):对于两个具有关联关系的表而言,相关联字段中的外键所在的那个表即是从表。

外键特点

  • 从表外键的值是对主表主键的引用。

  • 从表外键类型,必须与主表主键类型一致。

外键的作用: 保证数据引用的完整性、一致性。

  • 要考虑向从表添加数据时,外键字段必须是主表主键的引用,否则添加失败。

  • 要考虑从主表中删除数据时,主键并未被从表引用,否则删除失败。

语法

-- 添加外键
alter table 从表 add [constraint][外键名称] foreign key (从表外键字段名) 
references 主表 (主表的主键);
-- [外键名称]用于删除外键约束的,一般建议“_fk”结尾
-- 也可以在建表时添加外键约束,
--CONSTRAINT orders_customers_fk FOREIGN KEY (cust_id) REFERENCES customers (cust_id)

-- 删除外键
alter table 从表 drop foreign key 外键名称

案例

  现在我们有两张表“顾客表”和“订单表”,为了表明订单属于哪个顾客,通常情况下,我们将在订单表上添加一列,用于存放cust_id的信息,此列称为:外键。

在这里插入图片描述

# 添加外键
ALTER TABLE orders ADD CONSTRAINT orders_customers_fk FOREIGN KEY (cust_id) REFERENCES customers (cust_id);
# 删除外键
ALTER TABLE orders DROP FOREIGN KEY orders_customers_fk;

# 向主表添加数据
INSERT INTO customers (cust_id,cust_name) VALUES (666,'王老五');-- 成功
# 向从表添加数据
INSERT INTO orders(order_date, cust_id) VALUES (now(),666);-- 成功
# 向从表添加数据
INSERT INTO orders (order_date,cust_id) VALUES (now(),111);-- 失败
# 主表删除数据
DELETE FROM customers WHERE cust_id=666;-- 失败

  
  

表关系

  实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要顾客表(customers)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系,接下来我们将在单表的基础上,一起学习多表方面的知识。

一对一关系

  • 在实际的开发中不多.因为一对一可以创建成一张表.

  • 常见实例:商品表和商品描述表

两种建表原则:

  • 外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一unique。

  • 外键是主键:主表的主键和从表的外键,形成主外键关系。

一种商品只会有一条详细的描述记录

在这里插入图片描述
  

一对多关系

  • 常见实例:客户和订单,分类和商品,部门和员工, 省份和城市

  • 一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键.

在这里插入图片描述

一个客户可以有多条购买记录

在这里插入图片描述
  

多对多关系

  • 常见实例:商品和订单,学生和课程,用户和角色

  • 多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键

在这里插入图片描述

一个订单可能会购买多种商品,一种商品会出现在多个订单中

在这里插入图片描述

# 1.添加外键
ALTER TABLE orderitems  ADD CONSTRAINT orderiterms_orders_fk FOREIGN KEY (order_num) REFERENCES orders (order_num);
ALTER TABLE orderitems ADD CONSTRAINT orderiterms_products_fk FOREIGN KEY (prod_id) REFERENCES products(prod_id);
# 2.向订单表插入数据
INSERT INTO orders (order_num, order_date, cust_id) VALUES (101,now(),666);
# 3.向商品表插入数据
INSERT INTO products (prod_id,prod_name,vend_id,prod_price) VALUES (101,'大刀',1002,100);

# 4.向中间表插入一条数据(数据存在)
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price) VALUES (101,1,101,1,100);
# 5.向中间表插入一条数据(数据不存在)  执行失败
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price) VALUES (101,1,102,1,100);-- 产品表不存在102
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price) VALUES (102,1,101,1,100);-- 订单表不存在102
# 6.删除商品表   执行失败
DELETE FROM products WHERE prod_id=101;

  
  

实战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);

  
  

实战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)
);

特别提醒

  现在这种创建外键的方式已经不提倡,甚至被禁止了。因为在维护数据时,每次做DELETE 或者UPDATE都必须考虑外键约束。限制条件太多,效率较低。关联关系通过SQL语句来实现。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值