在SQL中将提供的模式转换为“等效”关系模式(表)

时间:2018-12-06 10:41:27

标签: sql db2

人员(p#,姓名,出生日期,国籍,性别)

演员(p#,aguild#)     FK(p#)推荐人

导演(p#,dguild#)     FK(p#)推荐人

作家(p#,wguild#)     FK(p#)推荐人

工作室(名称)

ScreenPlay(标题,年份)

已授权(标题,年份,作者)     FK(标题,年份)引用ScreenPlay     FK(作家)裁判作家(p#)

电影(标题,工作室,年份,类型,导演,长度)     FK(工作室)引用Studio(名称)     FK(标题,年份)引用ScreenPlay     FK(导演)裁判总监(p#)

播送(标题,工作室,年份,角色,演员,分钟)     FK(title,studio,year)引用电影     FK(演员)引用演员(p#)

下属(导演,工作室)     FK(导演)裁判总监(p#)     FK(工作室)引用Studio(名称)

我无法为作者创建表格,我收到一条错误消息,内容为“与描述不符 表或昵称的父键”

CREATE TABLE person (
p# int,
name varchar(255),
birthdate DATE,
nationality varchar(255),
gender varchar(255), 
constraint person_pk
primary key (p#)
);

CREATE TABLE actor (
p# int,
aguild varchar(255),
constraint actor_pk    
primary key (p#),
constraint actor_fk_person
foreign key (p#) references person
);

CREATE TABLE director (
p# int,
dguild varchar(255),
constraint director_pk    
primary key (p#),
constraint director_fk_person
foreign key (p#) references person
);

CREATE TABLE writer (
p# int,
wguild varchar(255),
constraint writer_pk    
primary key (p#),
constraint writer_fk_person
foreign key (p#) references person
);

CREATE TABLE studio ( 
name varchar(255) not null,
constraint studio_pk    
primary key (name)
);

CREATE TABLE screenplay ( 
title varchar(255) not null,
year varchar(255) not null,
constraint screenplay_pk    
primary key (title, year)
);

CREATE TABLE authored ( 
title varchar(255) not null,
year varchar(255) not null,
writer varchar(255) not null,
constraint authored_pk
primary key (title,year,writer),
constraint authored_fk_titleyear
foreign key (title, year) references screenplay,
constraint authored_fk_writer
foreign key (writer) references writer (p#) on delete no action
);

CREATE TABLE movie (
title varchar(255) not null,
studio varchar(255) not null,
year varchar(255) not null,
genre varchar(255),
director varchar(255),
length varchar(255),
constraint movie_pk    
primary key (title, studio, year),
constraint movie_fk_studio
foreign key (studio) references studio(name),
constraint movie_fk_titleyear
foreign key (title, year) references screenplay,
constraint movie_director
foreign key (director) references director(p#)
);

CREATE TABLE cast (
title varchar(255) not null,
studio varchar(255) not null,
year varchar(255) not null,
role varchar(255) not null,
actor varchar(255) not null,
minutes varchar(255),
constraint cast_pk    
primary key (title, studio, year, role, actor),
constraint cast_fk_titlestudioyear
foreign key (title, studio, year) references movie,
constraint cast_fk_actor
foreign key (actor) references actor(p#)
);

CREATE TABLE affiliated (
director varchar(255) not null,
studio varchar(255) not null,
constraint affiliated_pk    
primary key (director, studio),
constraint affiliated_fk_director
foreign key (director) references director(p#)
constraint affiliated_fk_studio
foreign key (studio) references studio(name)
);

2 个答案:

答案 0 :(得分:1)

您有几个基本错误。您似乎正在学习,所以花点时间研究RDBMS的基本规则和数据建模/标准化。

使用带有特殊字符(如#)的列名是不明智的,因为这会带来维护和可用性问题。您正在使用“ p#”指示作为代理的主键,但这是不明智的,请考虑使用命名约定代替代理键的列名。例如:person_pk,actor_pk,director_pk,writer_pk。

您的某些表使用代理键(p#),而其他表则使用自然键(例如studio.name)。如果您使用较长的自然键(例如varchar(255)),则使用这些自然键的子表将比使用整数或bigint类型的替代键来占用更多空间,并且搜索效率会降低PK。

下一步,如果您希望将列用作主键,则该列必须为NOT NULL。您的某些表违反了此规则,因此将无法创建。

具有外键时,其列的数据类型必须与相关父表列的数据类型匹配。您的示例违反了该规则,因此您将收到语法错误。

authored_fk_writer需要引用writer的键,但是您省略了任何键字段,并且相关的外键列为varchar(255),它与writer的主键(即int)不对应。

对于某些使用自然键的复合外键,复合长度超过了记录的限制。考虑对模型进行规范化,以便为外键列使用正确的数据类型(即,不要在子表中复制自然键,而应使用父表的代理键列)。

答案 1 :(得分:0)

在DB2中,子句'references writer()'不正确。您必须不指定任何包含括号的列(在这种情况下,父表必须具有PK),或者必须在括号内显式指定父表的对应列(父表必须具有PK或唯一约束)。

检查CREATE TABLE语句的REFERENCES子句语法。