MySQL 中的查找表

Les*_*Les 3 mysql foreign-keys

我正在用 PHP/MySQL 做我的第一份工作,我需要帮助。我有一张主表:

CREATE TABLE `m4l_movies` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `Title` varchar(250) NOT NULL,
    `Rating` int(11) NOT NULL,
    `Genre` varchar(250) NOT NULL,
    `Actors` varchar(250) NOT NULL,
    `UserID` int(11) NOT NULL DEFAULT '1',
    PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=115 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

接收表单的输入,该表单具有来自这些查找表的值:

CREATE TABLE `m4l_actors` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `Actor` varchar(255) NOT NULL,
    PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=232 DEFAULT CHARSET=utf8;

CREATE TABLE `m4l_genre` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `Genre` varchar(255) NOT NULL,
    PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=202 DEFAULT CHARSET=utf8;

CREATE TABLE `m4l_movierating` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `Movie_Rating` varchar(250) NOT NULL,
    PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

&我创建了一个视图:

SELECT m4l_movies.ID AS ID,
  m4l_movies.Title AS Title,
  m4l_movierating.Movie_Rating AS Rating,
  m4l_movies.Actors AS Actors,
  m4l_movies.Genre AS Genre
FROM m4l_movies
  JOIN m4l_movierating ON m4l_movierating.ID = m4l_movies.Rating
  INNER JOIN m4l_genre ON m4l_movies.Genre = m4l_genre.ID
  INNER JOIN m4l_actors ON m4l_movies.Actors = m4l_actors.ID
ORDER BY m4l_movies.Title
Run Code Online (Sandbox Code Playgroud)

这是我得到的输出:

----------------------------------------------------------------|
  ID      Title       Rating    Actor         Genre             |
  10      Summer      G         (10,15,25)    (45,115,123)      |
   1      About You   G-1       (63,163,405)  (3,16,51)         |
   5      Dog Years   P         (45,65,95)    (98,163,357)      |
----------------------------------------------------------------|
Run Code Online (Sandbox Code Playgroud)

首先这个视图应该返回超过 200 条记录。其次,我需要知道如何创建查找或其他方法将名称和类型转换回相应的文本值。有些 RATING 值是如何正确执行的,但我无法让 NAME 或 GENRE 正确执行。我确信这与我加入表格的方式有关,但我不知道哪里出了问题。有人请帮助我吗?

好吧,尝试遵循菲尔提出的建议,我已经从电影故事中删除了演员、类型并创建了 movie_genre 和 movie_actors

DROP TABLE IF EXISTS `m4l_movies`;
CREATE TABLE `m4l_movies` (
  `ID` int(11) NOT NULL auto_increment,
  `Title` varchar(250) NOT NULL,
  `Year` float NOT NULL,
  `Review` varchar(250) NOT NULL,
  `Rating` int(11) NOT NULL,
  `Image` varchar(250) NOT NULL,
  `Storyline` longtext NOT NULL,
  `Director` varchar(250) NOT NULL,
  `UserID` int(11) NOT NULL default '1',
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


 CREATE TABLE `m4l_movie_actor` (
    movie_id INT(11),
    actor_id INT(11),
    PRIMARY KEY (movie_id, actor_id),
    FOREIGN KEY (movie_id) REFERENCES m4l_movies (ID),
    FOREIGN KEY (actor_id) REFERENCES m4l_actors (ID)
 );


CREATE TABLE `m4l_movie_genre` (
    movie_id INT(11),
    genre_id INT(11),
    PRIMARY KEY (movie_id, genre_id),
    FOREIGN KEY (movie_id) REFERENCES m4l_movies (ID),
    FOREIGN KEY (genre_id) REFERENCES m4l_genre (ID)
);


DROP TABLE IF EXISTS m4l_genre;
CREATE TABLE m4l_genre (
  ID int(11) NOT NULL auto_increment,
  Genre varchar(250) NOT NULL,
  PRIMARY KEY  (ID)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS m4l_actors;
CREATE TABLE m4l_actors (
  ID int(11) NOT NULL auto_increment,
  Actor varchar(255) NOT NULL,
  PRIMARY KEY  (ID)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

但是当我尝试创建 movie_actor 或 movie_genre 时,我得到

09:29:45
创建表 `m4l_movie_actor`(movie_id INT(11)、actor_id INT(11)、
主键(movie_id、actor_id)、
外键(movie_id)引用 m4l_movies(ID)、
外键(actor_id)引用 m4l_actors( ID) )
错误代码:1215。无法添加外键约束
0.000 秒

09:40:56 创建表m4l_movie_genre(movie_id INT(11)、genre_id INT(11)、
主键(movie_id、genre_id)、
外键(movie_id)引用 m4l_movies(ID)、
外键(genre_id)引用 m4l_genre(ID))
错误代码:1215。无法添加外键约束
0.016 秒

据我所知,只有当数据类型不匹配时才会出现这种情况,但我认为我拥有所有 INT 数据类型,那么为什么我会收到此错误?

Phi*_*hil 5

您似乎犯了以不相关的方式存储关系数据的经典错误。

您应该使用连接表而不是逗号分隔值。例如...

CREATE TABLE `m4l_movies` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `Title` varchar(250) NOT NULL,
    `Rating` int(11) NOT NULL,
    -- removed Actors and Genre
    `UserID` int(11) NOT NULL DEFAULT '1',
    PRIMARY KEY (`ID`)
);

CREATE TABLE `m4l_movie_actor` (
    movie_id INT(11) NOT NULL,
    actor_id INT(11) NOT NULL,
    PRIMARY KEY (movie_id, actor_id),
    FOREIGN KEY (movie_id) REFERENCES m4l_movies (ID),
    FOREIGN KEY (actor_id) REFERENCES m4l_actors (ID)
);

-- repeat for genres 
Run Code Online (Sandbox Code Playgroud)

然后,您可以连接到联结表并连接到Actors/Genres表,例如

SELECT ... m4l_actors.Actor ...
FROM m4l_movies
INNER JOIN m4l_movie_actor ON m4l_movies.ID = m4l_movie_actor.movie_id
INNER JOIN m4l_actors ON m4l_movie_actor.actor_id = m4l_actors.ID
Run Code Online (Sandbox Code Playgroud)

如果您希望结果以逗号分隔的列表形式存在,请查看GROUP_CONCAT()