【问题标题】:One to Many Relationship Design一对多关系设计
【发布时间】:2013-05-27 22:37:43
【问题描述】:

我正在处理一个我正在处理的数据库问题,尽管它很简单。我习惯于使用 ORM 来为我取消后端 SQL,但这不是这里的选择。

我需要创建一个将流派映射到多部电影的数据库。例如,动作将映射到终结者、印第安纳琼斯和尖峰时刻。喜剧将映射到 The Big Lebowski 和 High Fidelity。我知道在一个真正强大的解决方案中,一部电影可以有多种类型,但现在让我们先忽略它。

解决此问题的最佳方法是什么,以便我可以按电影类型查询数据库并接收多部电影的列表?

【问题讨论】:

    标签: sql database postgresql


    【解决方案1】:

    如果您不关心连接,那么最简单的方法是创建一个像这样的 3 列表:

    UID、流派、FK_Movie

    FK_Movie 显然是 Movie 表中行的外键。使用这种方法,您实际上可以将多种类型附加到电影中。要按类型选择电影,只需“选择”类型并进行内部连接....

    【讨论】:

    • 所以我会插入同一个类型的次数与该类型的电影一样多吗?这比执行SELECT * from movies where genre = x 查询更有效吗?我试图避免每次都对数据库进行大量查询,因为这应该每次都加载一个经常访问的页面。
    • 除非您不需要 UID 列。将流派和 MovieId 两列设为复合主键。
    【解决方案2】:

    w3schools 教授 sql 基础知识。我肯定会从那里开始。然后您可能想要搜索 DDL(数据定义语言)教程来学习如何正确创建表 - 每个数据库的语法各不相同。我进行了快速搜索,这看起来很有用:http://facility9.com/2010/07/postgresql-tutorial-creating-the-pagila-schema/。您不想“忽略”多体裁问题,这是使数据库有用的原因。

    根据您的具体情况,基本上您需要一个 movie 表、一个 genre 表和一个 movie-genre 表。 (您需要更多批量,但这些应该涵盖您问题中的信息。)电影在字段(标题、年份、导演等)中包含电影信息,其中一个是 主键。流派表,同样包含流派信息,也有一个主键。魔法发生在具有主键和 2 个 外键 字段的电影类型表中。一个用于电影主键,一个用于流派主键。例如,如果终结者电影的主键是 1,动作类型的主键是 3,科幻类型的主键是 8,那么您可以通过在电影类型中插入 1、3 来为终结者 动作添加一条记录表,并通过在表中插入 1、8 来添加终结者 科幻记录。

    然后,您的查询将查看此表以查找哪些电影属于哪些类型(反之亦然),并使用其他两个表来提供冗长的信息。

    【讨论】:

    • w3schools 在他们的网站上有很多错误(他们拒绝修复),我永远不会推荐他们做任何事情。手册中的 Postgres 教程在教授 SQL 基础知识方面做得好多
    【解决方案3】:

    这是一个 SQL fiddle 演示:SQL Fiddle

    我同意其他人的观点,W3schools 也可以学习基础知识:W3Schooles Learn SQL

    【讨论】:

    • w3schools 很糟糕而且充满了错误。 sqlzoo.com 好很多(或者 Postgres 手册中的教程)
    • 我不同意,w3 是我最喜欢的各种功能的快速参考。
    • 适合您自己,但您应该注意该站点上的所有错误。
    【解决方案4】:

    这是一个多对多的关系。它是通过一个查找表来实现的,其中一个字段用于 CategoryID,一个字段用于 MovieID。您应该获取您感兴趣的类别的ID,然后对查找表和Category="x" 的电影表执行简单的一对多连接类型查询。 SELECT * FROM LookupTable 为 LT,电影为 M WHERE LT.Category = "x";

    只需简单查找即可获取 CatID。这两个查询可以组合起来,但为了简单起见,我在这里只展示第二部分。

    【讨论】:

      【解决方案5】:

      创建所谓的关联或多对多表,其中包含两列,一列用于流派,一列用于 MovieId

      Create Table MovieGenres(
          Genre varchar(10),
          MovieId integer Not Null,
          Primary Key (Genre, MovieId)
      )
      

      现在每部电影都可以有零到多个流派,并且一个流派可以用于零到多个电影。

      【讨论】:

        【解决方案6】:

        如果你使用 EF,你可以这样做:

        public class Movie
        {
            [ScaffoldColumn(false)]
            public int Id {get; set;}
            public string Name {get; set;}
            // ... other movie properties ...
        
            public virtual Genre Genre{get; set;}
        }
        
        
        
        public class Genre
        {
            [ScaffoldColumn(false)]
            public int Id {get; set;}
            public string Name {get; set;}
        
            // if you want to Genre has at least on Movie, 
            // add [Required] attribute at top of Movies property
            public virtual List<Movie> Movies {get; set;}  // its used as FK
        }
        

        现在在控制器中,为了获取类型,包括它的电影,使用下面的代码:

        public ActionResult Browse(string genre)
        {
            var genreModel = storeDB.Genres.Include("Movies").Single(g => g.Name == genre);
        
            return View(genreModel);
        }
        

        我希望它可以使用 --> Radmehr

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-12-30
          • 1970-01-01
          • 2010-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多