目录
Mysql的外键约束定义的语法:
ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name, ...) REFERENCES tbl_name (index_col_name,...) [ON DELETE reference_option] [ON UPDATE reference_option]
外键参数:
CASCADE
在父表上update/delete记录时,同步update/delete掉子表的匹配记录
SET NULL
在父表上update/delete记录时,将子表上匹配记录的列设为null (要注意子表的外键列不能为not null)
NO ACTION
如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
RESTRICT
同no action, 都是立即检查外键约束
SET NULL
父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别
参数选用的具体效果:
NULL、RESTRICT、NO ACTION
删除:从表记录不存在时,主表才可以删除。删除从表,主表不变
更新:从表记录不存在时,主表才可以更新。更新从表,主表不变
CASCADE
删除:删除主表时自动删除从表。删除从表,主表不变
更新:更新主表时自动更新从表。更
新从表,主表不变
SET NULL
删除:删除主表时自动更新从表值为NULL。删除从表,主表不变
更新:更新主表时自动更新从表值为NULL。更新从表,主表不变
实例:
举一个简单的例子解释:
这里主要说一下本人用到的CASCADE(应该也是最容易碰到的)
- 开发一个用户收藏功能:
首先肯定要有的是:用户表(user)、项目表(project)。
user表存在具有标识性的主键:id;project表同样也存在主键:id.
两张表中其余信息根据开发的具体需求进行设计:
比如用户表还应该包括用户名、密码、用户的其他基本信息;项目表应该有项目名,项目类型、项目简介等信息。
接下来开发收藏功能需要新建一张收藏表用来存放用户与项目之间的收藏关系:
CREATE TABLE collect(id INT PRIMARY KEY auto_increment,user_id INT,project_id INT);
收藏表主键这里同样设置的是id(按序自增),然后还有user_id和project_id,分别用来表示收藏人和收藏项目。
(很显然,user_id和project_id需要被设置成外键,这里没有在建表时设置,而是选择建表后将其设置为外键)
ALTER TABLE collect ADD FOREIGN KEY (user_id) REFERENCES user(id) ON UPDATE CASCADE ON DELETE CASCADE; //设置user_id为外键,关联的是user表的主键 id
ALTER TABLE collect ADD FOREIGN KEY (project_id) REFERENCES project(id) ON UPDATE CASCADE ON DELETE CASCADE; //设置project_id为外键,关联project表的主键 id
可以看到这里使用了ON UPDATE CASCADE ON DELETE CASCADE 参数,代表的是对user表和project表进行”更新“和“删除”操作,collect表都会进行相应的改变,其余如果只想在对主表进行更新或者删除单个操作时子表跟着改变,可以只使用ON UPDATE CASCADE 或者 ON DELETE CASCADE,其余操作应该一样(作者没有试过,只是合理推断,如果说错了的话,请大家多多包涵,可以的话也可以留言,我看到会第一时间更改的。)
接下来进行验证:
建立user表和project表,并插入几个测试数据:
用上述sql语句建立collect表:(这里是因为之前设计的表,所以多了一个request_id字段,不过用不到,是不影响的)
插入测试数据:
这里要注意一下,因为是外键,所以插入的数据中,user_id 和 project_id 必须是user表和project表中存在的数据,这里可以从上图中看到,user表中存在id为6的用户,project表中存在id为3的项目,插入数据成功。(专门尝试着插入两张表中不存在的数据,结果当然是报 ERROR )
select一下,可以看到插入数据成功,(collect表id的值不用在意,因为设置的自增,之前测试过,然后把数据删除了,所以现在id是自增到了7,这种的也很烦人,自己操作删数据库中的某条数据以后,id的值就会缺项,比较容易影响到后续的开发,现在还不知道怎么解决,有知道的小伙伴希望留言或私信告诉我,在此谢过)
目前表中数据代表的是,用户表中 id 为 6 的用户收藏了项目表中 id 为 3 的项目,这时候无论是将user表中这个用户的信息删除,还是将project表中这条项目的信息删除,收藏表中的这条收藏信息都会被自动删除。(更新操作也一样)
反之,将collect表中这条信息删除,不会影响其余两张表。(再插了一条project数据进行演示,所以id是4)
可以看到,在project表中删除对应的项目信息,collect表中这条收藏信息会被自动删除;但是如果在collect表中删除这条收藏信息,project表中此条项目信息仍然存在。(逻辑是没问题的,我可以取消收藏这个项目,但是不会对这个项目产生任何影响;但是一旦我这个项目被删除了,那就不可能存在收藏了,对user表操作的原理与此相同就不再做重复演示了)
至此,一个简单收藏功能的mysql表就设计完成了。
作者只是个边学边用的小白,如有不足还请大家多多指出。