数据库(学习笔记七)--------主键与外键的基本概念详解
本人上课提问,问什么是主键,什么是外键。本来觉得意会的东西,结果说出来就很奇怪。
所以查阅了一些资料,有很多写的挺好的,我就当做学习笔记记录一下吧。
主要内容:
什么是主键?
什么是外键?外键的作用是什么?何时可以删除一个外键?
主键索引和唯一索引的区别?
如何用sql创建一个主键和一个外键?
如何删除一个主键?(针对有auto_increment会有所不同)
如何对有外键的表添加数据?和删除数据?
1.主键的定义
主关键字(primary key)是表中的一个或多个字段,它的值用于唯一地标识表中的某一条记录。
我之前以为主键只能是一个列,但是一个或者多个字段都是可以的。
2.什么是外键?
实例一:
表1中有学号的属性,表2中也有。表1可以看做是主表,表二可以看做是子表,而学号这个属性就把表1和表2连接起来学了。表2中的学号就是表1的外键。
实例二:
比如
学生表(学号,姓名,性别,班级)
其中每个学生的学号是唯一的,学号就是一个主键
课程表(课程编号,课程名,学分)
其中课程编号是唯一的,课程编号就是一个主键
成绩表(学号,课程号,成绩)
成绩表中单一一个属性无法唯一标识一条记录,学号和课程号的组合才可以唯一标识一条记录,所以 学号和课程号的属性组是一个主键
成绩表中的学号不是成绩表的主键,但它和学生表中的学号相对应,并且学生表中的学号是学生表的主键,则称成绩表中的学号是学生表的外键
同理 成绩表中的课程号是课程表的外键
3.外键的作用:外键能保持数据的一致性、完整性
当你更改表2的学号时,那么表1中主键的值也会有所改变。就是二者是一个东西。
4.注意:
外键不一定要是主表的主键,还可以是一个唯一索引。
主键约束和唯一性约束都是唯一性索引。
FOREIGN KEY 约束并不仅仅可以与另一表的 PRIMARY KEY 约束相链接,它还可以定义为引用另一表的 UNIQUE 约束。FOREIGN KEY 约束可以包含空值,但是,如果任何组合 FOREIGN KEY 约束的列包含空值,则将跳过组成 FOREIGN KEY 约束的所有值的验证。若要确保验证了组合 FOREIGN KEY 约束的所有值,请将所有参与列指定为 NOT NULL。
5.主键约束(PRIMARY KEY)和唯一性约束(unique)的不同?
简单说就是主键不可以为空,但是unique可以。
具体:
PRIMARY KEY:
1.主键用于唯一地标识表中的每一条记录,可以定义为一列或者多列为主键。
2.主键列上没有任何两行具有相同的值(重复性),并且不可以为null。
UNIQUE:
1.唯一性约束用来限制不受主键约束列上的数据的唯一性,用于作为访问某行的可选手段,一个表上可以放置多个唯一性约束。
2.表中任意两行在一指定列上都不允许有相同的值(重复性),但是可以为null。
6.删除外键时注意事项。
当你要删除一个列,但是他是另一个表的外键时,就要保证,另一个表已经没有数据了。否则不可以删除是外键的这个属性列,或者属性值。
这是一会我测试代码时创建表的说明。
7.如何创建一个主键或者一个外键?(在sql语句中如何写)
7.1如何创建一个主键?
两种方式:
第一种:在创建一个表的时候,声明一个列的属性的时候就声明这个列为主键;
create table table_name(id int not null primary key auto_increment,name char(20) not null);
此时id为主键,关键字是primary key
第二种:正常创建表,但是在创建表后添加。
alter table table_name add primary key(column_name);
alter table table_name add primary key(id);
此时id为主键;
7.2 如何删除一个主键?
7.2.1 如果主键是自增长的,那么需要先取消自增长在删除主键。
测试:
删除成功。
7.2.2 如果不是自增长的直接删除即可;
(这里的主键不能是别的表的外键,否则删除这个主键的时候,你得先把他的外键删掉);
alter table table_name drop primary key;
删除成功。
7.3 如何创建一个外键?
两种方式:
第一种,创建的时候声明;
1:创建一个父表,主键作为子表的外键:
1 create table province( 2 pId int primary key auto_increment, 3 pName varchar(20) 4 );
2:创建子表,外键是父表的主键:
1 create table user( 2 userId int primary key auto_increment, 3 userName varchar(40), 4 pid int, 5 foreign key(pid) references province(pId) 6 );
子表创建外键成功。
第二种:创建好表之后声明
alter table user(table_name) add foreign key(pid-子表中外键的名称) references province(pId-父表的主键名字);
如何给外键设置属性。关于数据删除的问题。
7.4 如何在两个表中添加数据?
如果存在一个父表和一个子表,必须先给父表添加数据,才能给子表添加数据。否则添加不进入。
如果主键id设置的是自动增长,在insert的时候,也可以规定id的值,然后在下一次不再规定后,会在上一次的id后面加1,作为本次插入的id值,中间跳过的值就跳过了。
先插入3次,id正常自增长;
规定了pid是5,可以插入。
再自动插入时显示
注意:在子表插入一个数据的时候,如果因为外键的原因报错,而导致没有插入进去的时候,自增长的id也会因此增加。
错误插入两次后。uid在插入的时候会变成9.
但是如果我的父表(provice)如果有数据插入不进入的现象,就不会出现这个问题,为什么呢?他们都是主键,都是自动增长的,就是以为provice的pid是user中的外键吗?
7.5 如何删除一个外键?
alter table table_name drop foreign key(property);
当我按照刚刚的要删除外键的时候,一直在报我的错误。
因为我的property 填写错了,我写的pid。虽然pid确实是外键,但是我们删除的不是pid这个列,而是他的外键的这个性质。
所以property的正确理解是:CONSTRAINT后面的那个值。
如果你在声明一个外键的时候,是这么写的,
foreign key(pid) references province(pId)
就是没有显示的注明这个值,没关系,你用show create table table_name查看,mysql给我们自动生成的就可以了。
删除成功。
参考:https://blog.****.net/harbor1981/article/details/53449435
参考:https://blog.****.net/haiross/article/details/50435374
参考:https://blog.****.net/biexiansheng/article/details/77451353
参考:https://www.cnblogs.com/yccmelody/p/5416456.html
参考:https://blog.****.net/zskcy/article/details/2069016