简体   繁体   English

了解InnoDB外键

[英]Understanding InnoDB foreign keys

I am following one PHP & MySQL tutorial. 我正在关注一个PHP和MySQL教程。 At this point, I have to create a database that should look like this: 此时,我必须创建一个看起来像这样的数据库:

DB Schema

I created the databases by hand, but I do not understand the point of the roll table. 我手动创建了数据库,但我不明白roll表的重点。 For instance, let's say I want to add a movie: how am I going to do it, since I am not allowed? 例如,假设我要添加一部电影:我怎么做,因为我不被允许? Example error: 示例错误:

#1452 - Cannot add or update a child row: a foreign key constraint fails (`test`.`movie`, CONSTRAINT `movie_ibfk_1` FOREIGN KEY (`movieCode`) REFERENCES `roll` (`movieCode`) ON DELETE CASCADE) 

I would personally do something like: 我个人会这样做:

Table artist: artistId , firstname, lastname, nationality, dateOfBirth, otherInfo Table movie: movieCode, title, image, category, description, artistId 表艺术家: artistId ,名字,姓氏,国籍,dateOfBirth,otherInfo表电影:movieCode,title,image,category,description, artistId

Being the one in bold the related foreign keys. 作为粗体的相关外键。 However, I do not understand the concept of using the roll table there. 但是,我不明白在那里使用滚动表的概念。 Can someone clarify this for me, as I'd like to do it like the tutorial pretends to teach? 有人可以为我澄清这个,因为我想像教程假装教的那样做吗?

DB schema I have so far: 到目前为止我有DB模式:

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

CREATE TABLE IF NOT EXISTS `artist` (
  `artistId` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `firstName` char(30) NOT NULL,
  `lastName` char(30) NOT NULL,
  `dateOfBirth` date NOT NULL,
  `nationality` char(30) NOT NULL,
  `otherInfo` text NOT NULL,
  PRIMARY KEY (`artistId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


CREATE TABLE IF NOT EXISTS `movie` (
  `movieCode` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` char(30) NOT NULL,
  `image` varchar(50) NOT NULL,
  `category` char(50) NOT NULL,
  `movieDesc` text NOT NULL,
  PRIMARY KEY (`movieCode`),
  UNIQUE KEY `title` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


CREATE TABLE IF NOT EXISTS `roll` (
  `movieCode` int(10) unsigned NOT NULL,
  `artistId` int(10) unsigned NOT NULL,
  PRIMARY KEY (`movieCode`,`artistId`),
  KEY `artistId` (`artistId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE IF NOT EXISTS `user` (
  `userId` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `firstName` char(30) NOT NULL,
  `lastName` char(30) NOT NULL,
  `username` char(30) NOT NULL,
  `password` char(20) NOT NULL,
  `usertype` int(1) unsigned NOT NULL,
  PRIMARY KEY (`userId`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;



ALTER TABLE `movie`
  ADD CONSTRAINT `movie_ibfk_1` FOREIGN KEY (`movieCode`) REFERENCES `roll` (`movieCode`) ON DELETE CASCADE;

ALTER TABLE `roll`
  ADD CONSTRAINT `roll_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`artistId`) ON DELETE CASCADE;

The roll table (which should probably be called a role table) is what's known as a many-to-many relationship. roll表(可能应该称为角色表)就是众所周知的多对多关系。

It stores a link between a movie and an artist. 它存储电影和艺术家之间的链接 Since a movie can have many artists, and an artist can appear in many movies, you need a separate table to store all those relationships. 由于电影可以有很多艺术家,而艺术家可以出现在很多电影中,因此您需要一个单独的表来存储所有这些关系。 Each row in roll represents an artist appearing in a movie. roll每一行代表一个出现在电影中的艺术家。

To avoid any constraint errors, you would need to insert a movie and an artist in the database first, and then insert a row into the roll table to define that artist appeared in that movie. 要避免任何约束错误,您需要先在数据库中插入电影和艺术家, 然后roll表中插入一行以定义该艺术家出现在该电影中。 So, the roll table would need two foreign key constraints; 因此, roll表需要两个外键约束; one on the artist table, which you have: artist桌上有一个,你有:

ALTER TABLE `roll`
  ADD CONSTRAINT `roll_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`artistId`) ON DELETE CASCADE;

And another on the movie table: 另一个在movie桌上:

ALTER TABLE `roll`
  ADD CONSTRAINT `roll_ibfk_2` FOREIGN KEY (`movieCode`) REFERENCES `movie` (`movieCode`) ON DELETE CASCADE;

With these constraints, you won't be able to define a role unless both that artist and movie exist. 使用这些约束,除非艺术家电影都存在,否则您将无法定义角色

Your foreign key on movieCode should be on the roll table. movieCode上的外键应该在roll表上。 MovieCode is the primary key of the movie table. MovieCode是影片表的主键。

In your given example you have to generate the foreign key constraints from the roll (role) table to the other tables (movie, artist), not the other way around. 在您给出的示例中,您必须从roll(角色)表生成外键约束到其他表(电影,艺术家),而不是相反。

The given error message 给定的错误消息

#1452 - Cannot add or update a child row: a foreign key constraint fails (`test`.`movie`, CONSTRAINT `movie_ibfk_1` FOREIGN KEY (`movieCode`) REFERENCES `roll` (`movieCode`) ON DELETE CASCADE)

implies that you have a foreign key constraint on movie which refers the roll (role) table. 意味着你在电影上有一个外键约束,它引用了roll(role)表。

This would have the semantic that only a movie can be entered for which a role (an entry in roll) exists. 这将具有只能输入角色(滚动条目)存在的电影的语义。

But I guess the semantics should be that you can only add roles for existing movies and existings artists. 但我想语义应该是你只能添加现有电影和现有艺术家的角色。 Therefore the roll (role) table should have foreign keys on the other tables, then you could add artists and movies, and then enter entries in roll (role) for valid artist-movie pairs. 因此,roll(role)表应该在其他表上具有外键,然后您可以添加艺术家和电影,然后在roll(role)中输入有效的艺术家 - 电影对的条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM