【发布时间】:2015-12-03 15:28:29
【问题描述】:
我有一个简单的 MySQL 数据库,在某些表列上有一些外键。一些外键列设置为 ON DELETE SET NULL,它似乎工作正常。但是,对于其中一张表,我无法配置 ON DELETE SET NULL - 我只能配置 ON DELETE CASCADE。
初始表格如下所示:
CREATE TABLE sessions(
session_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(50) NOT NULL,
UNIQUE KEY uk_sessions(name))
COLLATE utf8_unicode_ci;
CREATE TABLE blocks(
block_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(50) NOT NULL,
UNIQUE KEY uk_blocks(name))
COLLATE utf8_unicode_ci;
CREATE TABLE edot(
edah_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(50) NOT NULL,
UNIQUE KEY uk_edot(name))
COLLATE utf8_unicode_ci;
CREATE TABLE campers(
camper_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
edah_id int,
FOREIGN KEY fk_edah_id(edah_id) REFERENCES edot(edah_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
session_id int,
FOREIGN KEY fk_session_id(session_id) REFERENCES sessions(session_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
first varchar(50) NOT NULL,
last varchar(50) NOT NULL,
email varchar(50) NOT NULL,
needs_first_choice bool DEFAULT 0,
active bool NOT NULL DEFAULT 1)
COLLATE utf8_unicode_ci;
以上都可以正常工作。当我尝试这样做时,问题就来了:
CREATE TABLE block_instances(
block_id int NOT NULL,
FOREIGN KEY fk_block_id(block_id) REFERENCES blocks(block_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
session_id int,
FOREIGN KEY fk_session_id(session_id) REFERENCES sessions(session_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
PRIMARY KEY pk_block_instances(block_id, session_id))
COLLATE utf8_unicode_ci;
返回
ERROR 1005 (HY000): Can't create table 'chugbot_db.block_instances' (errno: 150)
如果我将第二个 ON DELETE SET NULL 更改为 ON DELETE CASCADE,错误就会消失:
CREATE TABLE block_instances(
block_id int NOT NULL,
FOREIGN KEY fk_block_id(block_id) REFERENCES blocks(block_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
session_id int,
FOREIGN KEY fk_session_id(session_id) REFERENCES sessions(session_id)
ON DELETE **CASCADE**
ON UPDATE CASCADE,
PRIMARY KEY pk_block_instances(block_id, session_id))
COLLATE utf8_unicode_ci;
工作正常。
谁能告诉我在 block_instances 表中使用 ON DELETE SET NULL 有什么问题?它似乎与 campers 表中的 ON DELETE SET NULL 完全相同。
【问题讨论】:
-
列 session_id 是否可以为空?
-
是的,应该是。根据上面的 SQL,它没有 NOT NULL 约束。
-
@DavidLobron 这里的重点是,如果您希望目标表的列 (
sessions.session_id) 在CASCADE上为SET NULL,则它必须可以为空。 -
@JiriTousek:session_id int NOT NULL 在原始表中,但不在引用表中。我觉得应该没问题。有效的表“campers”在 session_id 上有“ON DELETE SET NULL”,这很好。但是当我尝试在 block_instances 中做同样的事情时,它失败了——我不明白为什么。
-
@DavidLobron 我的立场是正确的,我把 FK 的方向弄糊涂了。
标签: php mysql sql database-schema