【问题标题】:Need to assign multiple attributes to records - should I opt for one table or multiple tables?需要为记录分配多个属性 - 我应该选择一个表还是多个表?
【发布时间】:2017-01-21 04:23:43
【问题描述】:

我正在使用 MVC 模式来表示一个包含许多音乐专辑记录的表格。每个音乐专辑都有属性(流派、艺术家、评级等)。每个属性可以有多个值(例如,一张专辑的流派可以是“流行”和“拉丁”)。我想用表来表示这些属性值。

所以我能想到两种基本方法。我想知道哪种方法更好?

  1. 为每个属性创建一个单独的表(例如,GENREARTIST)。每个表中的列将是 album_id 和 attr_value。

  2. 有一个表ATTRIBUTES,除了album_id 和值之外,它还包括属性名称(“流派”、“艺术家”……)。

通常我会选择方法 1(关系数据库等),但如果我选择方法 2,我的想法是,当我想添加新属性时,我不需要创建新模型、控制器,并查看。

有什么意见吗?

【问题讨论】:

    标签: sql cakephp model-view-controller database-design


    【解决方案1】:

    这与其说是一个 MVC 问题,不如说是一个规范化问题。

    有一个规范化数据库和建立实体(表)的过程。两种典型形式是第三范式或 Boyce-Codd 范式。搜索任何一个都应该提供充足的信息。话虽如此,除了标准标准化之外,您还可以使用其他一些设计。这完全取决于您希望如何平衡错误(更新/插入)和性能。许多人一直在提倡非关系型设计(nosql、couchdb 以及认为空列导致的损坏问题的人们现在不需要了)。然后是序列化阵列开辟了混合设计的可能性的现实。您似乎在讨论 EAV(实体属性值)与附加表。 EAV 以设计速度较慢而著称,但在无法提前知道输入单元时非常有用。因此,对于 EAV,如果我有一个艺术家并且我想添加一个“列”家乡,我不必创建一个新的列表,只需在属性表中创建一个新条目。众所周知,EAV 也很难验证和输入。

    在我的产品中,我谨慎行事并采用关系型(Boyce-Codd 形式)。是的,这意味着更多的模特和更多的关系,但值得多花几个小时。除了在标记为 Cakephp 之类的 MVC 框架中,制作模型再简单不过了。每次我使用 EAV 时,我都希望自己能多花点时间来规划它。

    【讨论】:

      【解决方案2】:

      选项 3:对于显而易见且使用最广泛的属性,使用专用表,并为用户定义的属性使用另一个通用表(例如“惹恼前妻多少”)

      静态表应该有一组相当静态的属性。

      【讨论】:

      • 如果我已经有一个通用表,为什么我不应该用它来做所有事情呢?
      • 更好的性能和更好的验证控制。当然,因为它是正确的规范化形式。
      【解决方案3】:

      我会将 Album 和 Genre 视为两个不同的模型。除了映射它们之间的关系的另一个表之外,您还可以为每个属性/模型创建表。数据库结构如下所示:

      =====
      Table: Albums
      -- id
      -- name
      -- artist
      
      ====
      Table: Genres
      -- id
      -- name
      
      ====
      Table: Album_Genres
      -- id
      -- album_id
      -- genre_id
      

      只需将所有专辑和流派添加到相关表中,然后声明专辑属于特定流派,在 Album_Genres 表中创建一个新行。如果您以后需要添加/删除任何属性,就像创建/删除几个表一样简单。

      【讨论】:

        【解决方案4】:

        只要有能力 - 我使用一张表格来表示一件“真实的事物”,而当这还不够时,例如当您必须关联两个不同的想法/对象/事物时,我会使用多个表格。

        话虽如此,我们都同意使用您的 #1 想法 - 但现在您希望能够添加新属性。这通常使用“元”表最容易处理 - 一个抽象对象及其属性的实际关系的表 - 为您提供所需的 - 动态属性。

        它可能看起来像这样

        =======================
        Table Name: Albums
        ----------------AlbumID
        ----------------GenreID --> foriegn key --> Genre in Genre Table
        ----------------ArtistID --> foriegn key --> Artist in Artist Table
        ----------------Name
        ----------------Etc (attributes that you know you will need)
        =======================
        Table Name: AlbumMeta
        ----------------AlbumID
        ----------------Key
        ----------------Value
        =======================
        

        现在 - 您的专辑可以具有具体属性(即:所有专辑都具有的属性),如果出现新的业务规则,例如仅针对独立专辑 - 您有一个指向新合作伙伴网站“indiealbums.com”的链接 - 您可以为独立流派中的每张专辑创建一个 AlbumMeta 条目...

        【讨论】:

          【解决方案5】:

          你应该使用第三范式来做到这一点

          在 CakePHP 中,您要查找的关系船和必填字段是..

          <?php
              class Album etends AppModel
              {
                  public $name = "Album";
                  public $hasAndBelongsToMany = array( 'Artist', 'Genre' );
              }
          ?>
          <?php
              class Artist extends AppModel
              {
                  public $name = "Artist";
                  public $hasAndBelongsToMany = array( 'Album' );
              }
          ?>
          <?php
              class Genre extends AppModel
              {
                  public $name = "Genre";
                  public $hasAndBelongsToMany = array( 'Album' );
              }
          ?>
          
          // fields for the tables with their table names
          // only the required ones for the relationships rest is up to you
          artists
              --id
          
          albums
              --id
          
          genres
              --id
          
          albums_artists
              --id
              --album_id
              --artist_id
          
          albums_genres
              --id
              --album_id
              --genre_id
          

          这意味着最初需要更多的工作来输入信息。您必须将 Genres 和 Artists 的输入视为数据库中的单独操作。如果您决定将艺术家视为整个“乐队”或单独的表演者,您将能够使用此设置,因为一张专辑可以与任意一组艺术家相关联。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-02-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-17
            • 2015-03-28
            • 1970-01-01
            相关资源
            最近更新 更多