postgresql建表中因为业务逻辑,需要用到外键,所以来说说。
参考文档:
我们拿微博举例来说明。
微博里面有很多的小伙伴,小伙伴可以建立一张person表。小伙伴会发很多微博,建立一张weibo表。
person表中有uid (primary key),weibo中有weiboid (primary key),uid (foreign key)。
uid的小伙伴发了weiboid这条微博,这样写建表语句:
create table person (
uid varchar(12) primary key,
name varchar(32)
);
create table weibo (
weiboid varchar(10) primary key,
uid varchar(12) references person (uid),
content varchar(280)
);
问题来了:
如果person里用户被删除或者修改,那么weibo表里面用户发的微博怎么办?person是被关联表,weibo是关联表。
1. 关联表的相关行同样被删除或修改;
on delete cascade, on update cascade
2. 因为两表有关联,只要关联表中存在相应值的行,raise Error,不允许删除或修改两表的相关行;
on delete restrict, on update restrict
3. 删除时关联表的相关行被设置为null or default;
on delete set null, on delete set default。如果default值作为外键,而被关联表中没有default值,则操作失败。(操作失败:关联表不变,被关联表删除;关联表和被关联表都不变?需要做下实验,估计是都不变。)
4. 删除时因两表相关,只要关联表中存在相应的行,不产生任何操作,与第二条不同的是,对约束条件的检查,允许在事务中延缓。
on delete no action
如果关联表的外键是null,就不需要满足两表的约束,所以定义外键为not null。代码更新为:
create table person (
uid varchar(12) primary key,
name varchar(32)
);
create table weibo (
weiboid varchar(10) primary key,
uid varchar(12) references person (uid) on delete restrict not null,
content varchar(280)
);
与foreign key相约束的,
被关联表中的键必须是primary key or unique,外键自身也要有索引。
-
关联表插入或更新时,要去被关联表中检查约束,所以被关联表中的键必须有索引,提高检查约束效率。
-
被关联表删除或更新时,会扫描关联表是否有相应的约束,所以关联表的外键最好有索引。
create index weibo_uid on weibo (uid);
练习题:
请写出微博应有的建表语句?可以考虑数据量不大的情况。
阅读(2711) | 评论(2) | 转发(0) |