我有一个受控的词汇表,如下所示:
-- 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在电影表中允许空值。
谢谢!
答案 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唯一性并减少击键次数。