可以使用外键的表列为NULL吗?

ben*_*der 208 mysql sql database foreign-keys

我有一个表有几个ID列到其他表.

我希望外键只有在我放入数据时才能强制完整性.如果我稍后进行更新以填充该列,那么它还应该检查约束.

(这可能是数据库服务器依赖的,我使用MySQL和InnoDB表类型)

我相信这是一个合理的期望,但如果我错了,请纠正我.

Dan*_*llo 214

是的,只有在值不为NULL时才能强制执行约束.这可以通过以下示例轻松测试:

CREATE DATABASE t;
USE t;

CREATE TABLE parent (id INT NOT NULL,
                     PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (id INT NULL, 
                    parent_id INT NULL,
                    FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=INNODB;


INSERT INTO child (id, parent_id) VALUES (1, NULL);
-- Query OK, 1 row affected (0.01 sec)


INSERT INTO child (id, parent_id) VALUES (2, 1);

-- ERROR 1452 (23000): Cannot add or update a child row: a foreign key 
-- constraint fails (`t/child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY
-- (`parent_id`) REFERENCES `parent` (`id`))
Run Code Online (Sandbox Code Playgroud)

第一个插入将通过,因为我们在中插入一个NULL parent_id.由于外键约束,第二个插入失败,因为我们尝试插入parent表中不存在的值.

  • 父表也可以使用id INT NOT NULL声明. (16认同)
  • 我认为`parent_id INT NULL`部分(详细地)等于`parent_id int default null` (3认同)
  • java 用户的旁注,如果您使用 ibatis 或其他 ORM 并在类成员中使用原语“int”而不是“Integer”,则默认值永远不会为 null,而是为 0,并且您将无法满足约束条件。 (2认同)
  • 它可能适用于插入,但删除源数据时会发生错误:“错误代码:1451。无法删除或更新父行:外键约束失败” (2认同)

小智 30

我发现插入时,空列值必须专门声明为NULL,否则我会得到一个约束违规错误(而不是空字符串).

  • 您是否可以在列上设置默认值NULL以允许此操作? (7认同)

小智 6

是的,该值可以为 NULL,但必须明确。我以前经历过同样的情况,很容易忘记为什么会发生这种情况,因此需要一点时间来记住需要做什么。

如果提交的数据被强制转换或解释为空字符串,则会失败。但是,通过在 INSERTING 或 UPDATING 时显式将该值设置为 NULL,您就可以开始了。

但这就是编程的乐趣不是吗?创造我们自己的问题,然后解决它们!干杯!


dav*_*nal 5

是的,这会按您的预期工作。不幸的是,我似乎很难在MySQL 手册中找到对此的明确声明。

外键意味着该值必须存在于另一个表中。NULL是指没有值,因此当您将列设置为 NULL 时,尝试对其施加约束是没有意义的。

  • @vimalkrishna 不一定 - 主键不能包含 null,但如果子元素不一定有父元素,则外键可以为 null。例如,如果父元素是仓库,子元素是产品,则 NULL 值可能意味着该产品当前未存储在仓库中。这比创建一个虚拟的“无仓库”仓库来满足不允许空值的外键约束更有意义。 (2认同)