【问题标题】:Modeling polymorphic blog posts建模多态博客文章
【发布时间】:2011-08-29 02:31:10
【问题描述】:

假设我有一个 blog_posts 表。但是,发帖的用户属于群组,每个群组都有自己的博客。

例如:

比如说,一个用户属于 3 个组:Marketing、Project Alpha、Administrators

他创建了一篇博文,但希望该博文出现在“营销博客”和“Project Alpha”博客中。

对此建模的最佳方法是什么?

在 blog_posts 表中有一个字段会不会是个坏主意:group_ids

并存储以逗号分隔的 id 列表:3,7(其中 Marketing Group =3,Project Alpha=7)

或者我应该创建另一个表并存储 blog_posts id 和组?

谢谢。

【问题讨论】:

  • 永远不要在数据库中存储逗号分隔的字符串,尤其是 ID。

标签: ruby-on-rails database-design data-modeling


【解决方案1】:

以@minitech 的回答为基础,我将拥有 3 个模型和 5 个 db 表

模型 rails g model <model_name>

  • 帖子(FK 必须有 user_id 列)
  • 用户

其他表格 rails g migration <table_name>

  • groups_posts(仅列 group_id 和 post_id)
  • groups_users(仅列 group_id 和 user_id)

然后在你的模型中配置如下关系

class Post < ActiveRecord::Base
  has_and_belongs_to_many :groups
  belongs_to :user
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :posts
end

class Group < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_and_belongs_to_many :posts
end

然后根据您的示例,代码变为:

user = User.find(<id of user>)
post = Post.create(:title => 'foo', :content => 'bar', :user => user)
post.groups << Group.find(3)
post.groups << Group.find(7)

【讨论】:

    【解决方案2】:

    我建议创建一个表来保存所有博客的所有帖子,然后创建一个表来存储所有博客的信息,然后创建一个表来存储所有博客的帖子,由 ID 引用。然后你只需添加,例如:

    进入帖子:ID=(自动递增值),Title='标题',Content='内容'
    插入博文:blogID=(要插入博文的博客 ID #1),postID=(上次的自动递增值)
    插入博文:blogID=(插入博文的博客ID#2),postID=(自上次的自增值)

    这样,帖子会被链接,因此当它被编辑或删除时,更改会反映在所有博客上,您还可以使用 SELECT * FROM blogPosts WHERE postID=id_of_post 之类的方式获取帖子所在的所有博客的快速列表。

    【讨论】:

      【解决方案3】:

      使用逗号分隔列表作为使所有数据项原子化的一种方法是一个坏主意。 它基本上是一种获取非第一范式数据并进行转换的方法,使其看起来像第一范式数据,即使它不是。

      如果您这样做,对于某些查询,您将不得不对其中一个表进行全面扫描,而不是索引查找。这将非常缓慢,并且随着数据量的增加而变得更糟。

      更好的解决方案是有一个将 group_id 与 user_id 相关联的联结表。

       Create Table Group_user 
      (group_id,
       user_id primary key is (gorup_id,  user_id))
      

      然后,当您想要将所有数据放在一起时,进行三向连接。这是建模多对多关系的基本方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-06
        相关资源
        最近更新 更多