在电影数据库中检查 BCNF?

Check BCNF at movie database?

我对如何检查数据库中的 BCNF 感到有点困惑 diagram.I 看过一些关于什么是数据库规范化(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 规范化。

感谢任何帮助!

Entity-Relationship 模型与其说是逻辑模型,不如说是概念模型。它增加了语义,使未受过形式逻辑训练的人更熟悉它,同时将一个限制为关系模型的一个子集并产生合理的规范化关系。我们通常不处理 ER 级别的规范化——实体和关系仅使用单个主键设计,其他所有内容都是这些键的依赖项,没有表示替代候选键或部分或传递函数依赖项的符号。此外,ER 的额外语义在规范化时是一个障碍 - 试图保持实体集和值集之间或实体关系和关系关系之间的差异没有逻辑价值。

将 ER 模型转换为关系模型后,可以更好地检查和应用规范化。通过这个,我的意思是将每个实体和每个关系转换为一个单独的关系并列出它们的功能依赖性和候选键。这些可以大部分直接从 ER 模型派生,但要注意隐藏的自然键(尤其是当您使用代理键时),寻找 non-key 属性之间的依赖关系(尤其是如果您使用 EER 复合属性),以及如果您使用 EER 多值属性,请注意来自多值依赖项的 4NF 违规。

您可以绘制关系图,其中每列都有一个方框,方框之间的箭头表示依赖关系。我更喜欢直接在文本中输入,例如

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

最后一行的空括号表示该关系中没有 non-key 属性。重要的是尝试识别所有候选键和持有的依赖关系以便正确规范化,不要只是假设 ER 模型是正确或完整的。列出所有候选键和功能依赖项后,您就可以通过正常形式检查它们。

顺便说一句,您的人际关系没有在您的身体中正确实施 model/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 图中包含关系的关键属性而创建的?通常我们理解一个关系的键是由参与该关系的实体的键组合而成的,所以我们没有在图中标明。

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

此外,在您的图表中,(0,N) 基数指示符没有意义。 0 通常表示关系的可选组件。 film_genre 实例可以在没有 movie_id and/or 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 子句。如果你删除一个人,它也会从电影中删除相关角色。如果您删除一个角色,它会删除一个人与一部电影的关联。对吗?