我是mysql的新手,所以非常感谢帮助: - )
让我们看电影db示例:
movie_td (mov_id auto_increment pk, title, year, duration)
actor_td (act_id auto_increment pk, name)
director_td (dir_id auto_increment pk, name)
movie_actor_td (movie_id fk, actor_id fk)
movie_director_td (movie_id fk, director_id fk)
我理解如何将.csv类型的文件插入到单个td中,其中所有名称都存储在一列中,但是以标准化格式执行此操作有点令人困惑。如果我已经将所有数据存储在一个表中,那么首先创建静态mov_id是否有意义,以便我可以引用其余的列?或者有更好的方法吗?
谢谢!
答案 0 :(得分:0)
如果您将所有数据存储在一个表格中,如果您的任何电影中有多个演员或拥有多个导演,您将面临问题。
这种规范化的数据库方法最好避免在数据库表中插入,更新和删除冗余数据的异常。
此外,如果同一个演员与许多电影有关,你必须为电影的每一行写同一个名字(演员/导演)。因此,更新特定行而不是其他行中的actor / director名称将导致表中actor / director名称的不一致。
答案 1 :(得分:0)
如果按定义去,如果每个属性的域仅包含原子值,并且每个属性的值仅包含该域中的单个值,则关系处于第一范式。 (来源:wikipedia.org)。
因此,当您在行中插入由逗号分隔的多个值时,您违反了第一个NF本身!这是因为数据之间存在多对多关系,并且您没有正确映射它。
此外,您提出了一个非常基本的问题 - If I already have all the data stored in one table, does it make sense to create a static mov_id first so that I can reference the rest of columns to it?
- 好吧,如果您只想将所有数据存储在一个表中,为什么不选择XML呢?您将拥有一个存储所有相关数据的文件。但事实是,您无法使用XML运行完整的应用程序。 XML有不同的用途,数据库表有不同的用途。您确实需要一个可以根据需要查询的数据结构,而不必担心存储的发生方式。我建议你阅读Korth关于数据库设计的书。
转而设计数据库和表结构,无论您是否知道如何将.csv文件存储到列中都无关紧要。重要的是开发复杂代码以从CSV列中获取值需要多长时间。编写一些简单的查询比使用复杂的搜索循环来获取值总是更好。
让我们看一下您发布的示例。我只拿了三张桌子。
考虑表movie_td
(我不明白_td
部分背后的原因,但我会坚持它,因为你发布了它。)这个表存储有关电影的信息。现在,在现实世界中,电影可能有多个属性(列),如标题,发布日期(现在,这也取决于它发布的区域,它可能有多个发布日期,因为每个区域,这是一个完全不同的故事),运行时间,导演的名字(到目前为止,我只看了一个导演或导演二人组的电影。我还没看过多导演的电影;)等等。
我们必须在此考虑两个事实:
这为我们提供了演员和电影之间的多对多关系,这就是表格movie_actor_td
出现的地方。此表存储哪个电影在哪个电影中投放,其中movie_id
和actor_id
均为foreign key。电影可能在此表中有多个条目,针对那些演员。演员也可能在这张表中有多个条目来对付那些电影,因此这些电影之间保持着相互的多对多关系。
拥有这种结构的一个主要原因是查询表格。如果您存储在电影表中分隔的演员逗号的名称,则无法使用actor_id深入了解演员的数据 - 您无法获取演员的其他详细信息,例如他们的出生日期和其他生物数据。
如果有人问你演员foo
完成了多少部电影怎么办?你会去每行的CSV列中寻找演员的名字吗?它会有多快?
但是现在您已经拥有了给定的表结构,您可以通过这样的简单查询找到它:
SELECT count(*)
FROM movie_actor_td
WHERE actor_id = (SELECT actor_id
FROM actor_td
WHERE name = 'foo');
让我们考虑一个更复杂的例子。为此,我可以自由地向表character_name
添加列movie_actor_td
,因为演员通常在电影中扮演单个角色。所以你的movie_actor_td
表看起来像是:
movie_actor_td (movie_id, actor_id, character_name)
现在,有一位演员在1996年发行的电影James Bond
中扮演Goldeneye
。我不知道他的名字。我想知道他在2002年完成了多少部电影。我只想简单地提出一个问题:
SELECT COUNT(*)
FROM movie_actor_td
WHERE actor_id = (SELECT actor_id
FROM movie_actor_td
WHERE movie_id = (SELECT movie_id
FROM movie_td
WHERE name = 'Goldeneye'
AND release_year = 1996)
AND character_name = 'James Bond');
如果您将所有数据存储在一个CSV列中,是否可以轻松获取?我不信。 我建议您继续使用当前架构。
修改强>
您首先要求创建静态mov_id
并将所有其他列引用到它。我认为您需要先阅读有关primary keys,foreign keys和数据库约束的更多信息。然后阅读MySQL中自动增加的列值。