我正在重新设计一些应用程序安全日志表(例如用户登录,访问不同文件等等)以满足一些不断变化的需求。它们最初是用MyISAM
创建的,但实际上并没有真正被访问,并且切换到InnoDB
并且为数据完整性添加一堆外键真的会更有益。因为无论如何我必须重新制作表格,我觉得这是一个很好的时间来进行切换。
在大多数情况下,一切都是简单的外键,并按预期工作。我正在尝试一些奇怪的问题和遇到问题的唯一部分是user_ids。这些日志表中的每条记录都与user_id相关联,我想确保在插入记录时存在给定的user_id。添加引用用户表的外键可以解决这个问题 - 简单的东西。以下是一些简洁,有代表性的表格:
用户表
CREATE TABLE tbl_user (
id INT(10) NOT NULL AUTO_INCREMENT,
first_name VARCHAR(50),
PRIMARY KEY(id)
) ENGINE=InnoDB;
示例日志表
CREATE TABLE tbl_login_time (
id INT(10) NOT NULL AUTO_INCREMENT,
user_id INT(10) NOT NULL,
login_at TIMESTAMP NOT NULL,
PRIMARY KEY(id),
CONSTRAINT 'tbl_login_time_fk_1` FOREIGN KEY (user_id) REFERENCES tbl_user
ON UPDATE CASCADE ON DELETE ???
) ENGINE=InnoDB;
我的问题是我希望对插入强制执行外键,更新级联,但删除tbl_user中的记录根本不影响tbl_login_time。通常,用户被标记为非活动状态,但每隔一段时间用户就会被完全删除,但需要维护日志。
MySQL docs列出ON DELETE
的6个选项,但这些选项听起来都不合适:
我之前从未使用过这样的外键(强制执行INSERT
和UPDATE
而不是DELETE
),并且在阅读了很多其他问题之后看起来并不像其他人都做了。这应该告诉我这是错误的方法,但它可以以某种方式工作吗?
答案 0 :(得分:2)
我的问题是我想要对插入强制执行外键, 更新要级联,但删除tbl_user中的记录不会影响 tbl_login_time。
使用外键约束无法实现这一点。
在某些应用程序中,ON DELETE SET NULL是有意义的。但是您的应用程序本质上是存储在SQL数据库中的日志文件。您有一个重要问题,即您要删除标识信息(用户),但在某些情况下会保留其ID号。坦率地说,我不明白为什么你愿意保留用户23332今天18:40登录的事实,而不关心你是否可以识别用户23332 是。
您有几个选择。
我很确定我们同意最明显的选择 - 使用ON DELETE CASCADE的外键 - 对你的应用来说是错误的。