检查电影数据库中的BCNF?

时间:2016-12-28 12:01:36

标签: database entity-relationship database-normalization bcnf

我有点困惑如何在数据库图表中检查BCNF。我看到了一些关于什么是数据库规范化(1NF,2NF ......)的YouTube视频,但是当我们将这些规则应用到我的项目时,我不知道我不知道该怎么做。

My ER diagram for a movie database

ER图表到postgre sql代码:

CREATE TABLE People ( 
    birth_date  DATE    NOT NULL,
    last_name   CHAR(30)    NOT NULL,
    name    CHAR(30)    NOT NULL,
    person_id   INTEGER NOT NULL,
PRIMARY KEY (person_id) );

CREATE TABLE Roles ( 
    role_id INTEGER NOT NULL,
    role_name   CHAR(30)    NOT NULL,
PRIMARY KEY (role_id) );

CREATE TABLE genre ( 
    genre_id    INTEGER NOT NULL,
    genre_name  INTEGER NOT NULL,
PRIMARY KEY (genre_id) );

CREATE TABLE Movies ( 
    movie_id    INTEGER NOT NULL,
    title   CHAR(30)    NOT NULL,
    rating  REAL    NOT NULL,
    release_date    DATE    NOT NULL,
PRIMARY KEY (movie_id) );

CREATE TABLE film_people ( 
    role_id INTEGER NOT NULL,
    person_id   INTEGER NOT NULL,
    movie_id    INTEGER NOT NULL,
    FK1_movie_id    INTEGER NOT NULL,
    FK2_person_id   INTEGER NOT NULL,
    FK3_role_id INTEGER NOT NULL,
PRIMARY KEY (FK1_movie_id, FK2_person_id, FK3_role_id),
UNIQUE (role_id),
UNIQUE (person_id),
UNIQUE (movie_id) );

CREATE TABLE film_genre ( 
    movie_id    INTEGER NOT NULL,
    genre_id    INTEGER NOT NULL,
    FK1_movie_id    INTEGER NOT NULL,
    FK2_genre_id    INTEGER NOT NULL,
PRIMARY KEY (FK1_movie_id, FK2_genre_id),
UNIQUE (movie_id),
UNIQUE (genre_id) );

ALTER TABLE film_people ADD FOREIGN KEY (FK1_movie_id) REFERENCES Movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE film_people ADD FOREIGN KEY (FK2_person_id) REFERENCES People (person_id) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE film_people ADD FOREIGN KEY (FK3_role_id) REFERENCES Roles (role_id) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE film_genre ADD FOREIGN KEY (FK1_movie_id) REFERENCES Movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE film_genre ADD FOREIGN KEY (FK2_genre_id) REFERENCES genre (genre_id) ON DELETE CASCADE ON UPDATE CASCADE;

电影数据库设计的主要来源: How to design a movie database?

因此,在给定的ER图中,我的目的是找到功能依赖关系并应用BCNF规范化。

感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

实体 - 关系模型更像是概念模型,而不是逻辑模型。它增加了语义,使得在正式逻辑中未经训练的人更熟悉,同时将一个限制为关系模型的子集并产生合理规范化的关系。我们通常不处理ER级别的规范化 - 实体和关系仅使用单个主键设计,而其他所有内容都是这些键的依赖关系,没有表示备用候选键或部分或传递功能依赖关系的表示法。此外,ER的额外语义在规范化时是一个障碍 - 试图维持实体集和值集之间或实体关系和关系关系之间的差异没有逻辑价值。

在将ER模型转换为关系模型后,可以更好地检查和应用规范化。通过这种方式,我的意思是将每个实体和每个关系转换为单独的关系,并列出它们的功能依赖关系和候选关键字。这些可以主要直接来自ER模型,但要注意隐藏的自然键(特别是当你使用代理键时),寻找非键属性之间的依赖关系(特别是如果你使用了EER复合属性),并注意如果您使用了EER多值属性,那么对于来自多值依赖项的4NF违规。

您可以绘制关系图,其中包含每列的框和框之间的箭头,以指示依赖关系。我更喜欢用文字输入,例如

genre: genre_id -> genre_name
movies: movie_id -> title, release_date, rating
film_genre: movie_id, genre_id -> ()

最后一行中的空括号表示该关系中没有非键属性。尝试识别所有候选键和依赖关系以便正确标准化非常重要,不要只假设ER模型正确或完整。一旦列出了所有候选键和功能依赖项,您就可以通过常规表单进行检查。

顺便说一句,您的关系关系未在物理模型/ SQL中正确实现。他们应该是:

CREATE TABLE film_people ( 
    role_id INTEGER NOT NULL,
    person_id INTEGER NOT NULL,
    movie_id INTEGER NOT NULL,
    PRIMARY KEY (movie_id, person_id, role_id),
    FOREIGN KEY (movie_id) REFERENCES Movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (person_id) REFERENCES People (person_id) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (role_id) REFERENCES Roles (role_id) ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE TABLE film_genre ( 
    movie_id INTEGER NOT NULL,
    genre_id INTEGER NOT NULL,
    PRIMARY KEY (movie_id, genre_id),
    FOREIGN KEY (movie_id) REFERENCES Movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (genre_id) REFERENCES genre (genre_id) ON DELETE CASCADE ON UPDATE CASCADE
);

我删除了重复的列,例如movie_idFK1_movie_id。也许这些是由于您的ER图中的关系中包含关键属性而创建的?通常我们理解,关系的密钥是从参与关系的实体的密钥组合而来的,因此我们不会在图上指出它。

我还删除了每个列的唯一约束。想一想 - 每部电影只有一个角色吗?每个人在他/她的生活中只能扮演一个角色吗?每个角色只能执行一次吗?每部电影只属于一种类型吗?每种类型只包含一部电影吗?这些限制没有意义。

此外,在您的图表上,(0,N)基数指标没有意义。 0通常表示关系的可选组件。可以在没有film_genre和/或movie_id的情况下记录genre_id个实例吗?不,每个关系实例都需要两个实体。除非另有说明,否则通常假设ER关联不受约束,因此当关系中的实体依赖而不是密钥的一部分时,我指示的唯一基数是1。对于可选关联,我使用虚线。

回到你的问题,花点时间考虑film_people关系,这里可能存在BCNF违规,具体取决于你如何解释这种情况。是否有隐藏的重叠候选键?例如,(movie_id, person_id)(movie_id, role_id)都是唯一的吗?换句话说,一个人在电影中只能扮演一个角色,而且只能有一个人在电影中扮演每个角色吗?以同样的方式考虑(movie_id, role_id)(role_id, person_id)

最后,还要考虑一下你的ON DELETE CASCADE条款。如果删除某个人,它还会删除电影中的关联角色。如果删除某个角色,它将删除一个人与电影的关联。这是对的吗?