外键约束。子表有空值吗?错误1452(23000)

时间:2015-05-03 22:20:59

标签: mysql database-design null foreign-keys

我有一个受控的词汇表,如下所示:

-- create the film_stock table
DROP TABLE IF EXISTS film_stock;
CREATE TABLE film_stock (
    stock varchar (10) NOT NULL,
    PRIMARY KEY(stock))
    ENGINE = INNODB;

只有两个值分配给' stock' - 硝酸盐和醋酸盐。

'股票'在我的电影中扮演外键:

-- create the films table
DROP TABLE IF EXISTS films;
CREATE TABLE films (
    title varchar (100) NOT NULL,
    alternate_title varchar (50) NULL,
    year_of_release varchar (15) NULL,  
    country varchar (50) NULL,
    running_time_minutes int (10) NULL,
    footage_lenght_feet int (10) NULL,
    stock varchar (10) NULL,
    gauge varchar (10) NULL,
    bw_color varchar (10) NULL,
    notes varchar (255) NULL,
    print_publications varchar (255) NULL,
    existent_print varchar (255) NULL,
    url_1 varchar (100) NULL,
    url_2 varchar (100) NULL,
    url_3 varchar (100) NULL,
    PRIMARY KEY(title),
    FOREIGN KEY(country) REFERENCES countries (country),
    FOREIGN KEY(stock) REFERENCES film_stock (stock),
    FOREIGN KEY(gauge) REFERENCES film_gauge (gauge),
    FOREIGN KEY(bw_color) REFERENCES bw_or_color (bw_color))
    ENGINE = INNODB;

在这部电影的表格中,该栏目的股票是'如果经常是空的,因为我还不知道任何特定电影的胶片库存。

我在运行脚本时遇到此错误:

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`hbm248_BucherFilms1`.`films`, CONSTRAINT `films_ibfk_2` FOREIGN KEY (`stock`) REFERENCES `film_stock` (`stock`))

当我引用的外键没有空值时,我的电影表中是否允许空值?我认为设置' stock'在films表中为NULL将允许空值...或者我还需要在film_stock表中将stock设置为NULL吗?现在它不是NULL ... 或者我是否需要输入一些价值,例如' unknown'进入受控词汇表' stock'然后用这个未知的电影填充电影中的库存栏。当我确定该股票是硝酸盐还是醋酸盐时,价值并在以后更改? 这最后一个选项似乎可以解决我的问题,但也觉得它应该是不必要的,并且应该有一种方法让MySQL在电影表中允许空值。

谢谢!

1 个答案:

答案 0 :(得分:0)

  

子表可以有空值吗?

目前的FK关系无法做到这一点。以下部分将提供有关设置词汇表的指导。

多表的词汇表

使用PK的ID为每个列表创建一个表。然后,此ID将用作其他表上的FK。

CREATE TABLE film_stock (
  `ID` int NOT NULL AUTO_INCREMENT,  
  stock varchar (10) NOT NULL,
    PRIMARY KEY(ID))
ENGINE = INNODB;
  

并为每个列表重复...

单一表的替代方式

CREATE TABLE VocabularyList (
  `ID` int NOT NULL AUTO_INCREMENT,  
  groupName varchar (10) NOT NULL,
  groupValue varchar (50) NOT NULL,
  groupOrder int NOT NULL Default 0,
    PRIMARY KEY(ID))
ENGINE = INNODB;

插入VocabularyList语句

insert into VocabularyList(groupName, groupValue, groupOrder) VALUES ('DefaultValue','Pending_Value',1);

insert into VocabularyList(groupName, groupValue, groupOrder) VALUES ('stock','nitrate',1);

insert into VocabularyList(groupName, groupValue, groupOrder) VALUES ('stock','acetate',2);

查询从VocabularyList

检索股票信息
select groupValue
from VocabularyList
where groupName = 'stock'
order by groupOrder

使用单表替代

更新了电影表格
CREATE TABLE films (
    title varchar (100) NOT NULL,
    alternate_title varchar (50) NULL,
    year_of_release varchar (15) NULL,  
    countryID int NOT NULL DEFAULT 1,
    running_time_minutes int (10) NULL,
    footage_lenght_feet int (10) NULL,
    stockID int NOT NULL DEFAULT 1,
    gaugeID int NOT NULL DEFAULT 1,
    bw_colorID int NOT NULL DEFAULT 1,
    notes varchar (255) NULL,
    print_publications varchar (255) NULL,
    existent_print varchar (255) NULL,
    url_1 varchar (100) NULL,
    url_2 varchar (100) NULL,
    url_3 varchar (100) NULL,
    PRIMARY KEY(title),
    FOREIGN KEY(countryID) REFERENCES VocabularyList(ID),
    FOREIGN KEY(stockID) REFERENCES VocabularyList(ID),
    FOREIGN KEY(gaugeID) REFERENCES VocabularyList(ID),
    FOREIGN KEY(bw_colorID) REFERENCES VocabularyList(ID))
    ENGINE = INNODB;

为了便于使用,可以将films表主键切换为int数据类型。这将确保PK唯一性并减少击键次数。