欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据库外键的来因及实例(为什么要使用外键?)

程序员文章站 2022-06-04 13:08:35
...

问题背景:日常生活中我们在网上购物的时候,我们会使用多个地址,而用户名只用一个,在数据库中建立两张表,一张是用户名,一张是地址信息。那么问题来了,两张表是独立的,中间仅有一个定位id,可以使地址信息对号入座,但是,如果我删除第一张表中的用户名信息,第二张表里相应的地址信息不会被删除,而是转变为垃圾信息继续存在;相反的,我使用一个第一张表里不存在的用户名去添加地址信息,此时,奇怪的事情发生了,这个地址信息能够被数据库(这里是第二张表地址表)保存,不难理解,这也是垃圾信息,因为没有用户名去使用它。这就造成了数据的不完整性。

怎样解决数据不完整性问题呢?

这就需要

外键(foreign key)

来进行对数据的约束

使用软件:Navicat Premium 12

下面第一段代码就是造成数据不完整性的SQL语句

##创建一个用户表
create table user_info(
  id char(36) primary key,
  user_name varchar(30) not null,
  password varchar(30) not null
)
##向第一张表里添加信息
insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456');

##创建一个地址表
create table address(
  id char(36) primary key,
  user_info_id char(36),
  real_name varchar(8) not null,
  mobile char(11) not null,
  address varchar(150) not null
)
##这里user_info_id与第一张表里的id相同,保证对号入座
insert into address (id,user_info_id,real_name,mobile,address) 
values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','张三','18920120206','河南安阳');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李四','18617297545','北京海淀');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','王五','17694976949','山西大同');
##执行删除操作
delete from user_info where id = '51b28fe1-4ebf-41ac-a17b-d5e276861fd0'
**##成功执行后地址表里对应的信息就变成垃圾信息了。**
##执行删除操作
delete from user_info where id = '51b28fe1-4ebf-41ac-a17b-d5e276861fd0'
##执行完后就成垃圾信息了,信息不完整,找不到用户名。

下面是外键的使用SQL语句

create table user_info(
  id char(36) primary key,
  user_name varchar(30) not null,
  password varchar(30) not null
)
insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456');

create table address(
  id char(36) primary key,
  user_info_id char(36),
  real_name varchar(8) not null,
  mobile char(11) not null,
  address varchar(150) not null,
  ##下面这一行SQL语句 就是外键的使用,保证数据的完整性
  constraint address_user_info_id_fk foreign key(user_info_id) references user_info(id)
)
insert into address (id,user_info_id,real_name,mobile,address) 
values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','张三','18920120206','河南安阳');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李四','18617297545','北京海淀');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','王五','17694976949','山西大同');

##执行删除操作
delete from user_info where id = '51b28fe1-4ebf-41ac-a17b-d5e276861fd0'
##此时会提示user_info中的信息正在被使用,无法删除。
##执行添加操作
insert into address (id,user_info_id,real_name,mobile,address) 
values ('5227c6b9-45a2-44aa-8ac0-','1234567890','李四','18617297545','北京海淀');
##操作失败,因为此时输入的id在user_info中查不到,所以报错,over

说明:

这种方案为user_info_id添加了外键,指向user_info表的主键,该约束起到了保护数据完整性的作用:如果删除的用户信息id已经在address表中使用,则该条数据无法删除;无法向address表中添加用户id不存在的地址信息。