【问题标题】:Devise STI vs. MTI vs. separate tables设计 STI 与 MTI 与单独的表格
【发布时间】:2011-08-14 06:42:18
【问题描述】:

我有一个使用 devise 进行身份验证的 rails 3.1 项目。

我有几种用户类型,每一种都在数据库中使用非常不同的字段。我对每个模型都有不同的模型,但是模型之间有足够的重叠功能,例如消息传递,因此拥有一个模型是有意义的。在处理不同类型用户之间的消息传递时,这尤其是一个问题。

我应该将它们全部保留为单独的表还是将它们移动到单个表中?考虑到我们将一直在查找用户这一事实,多表继承确实没有多大意义。加入明智的做法简直太昂贵了。

将每个用户类型的所有未使用的列都放在表中,感觉真的很脏。

想好了吗?

【问题讨论】:

    标签: ruby-on-rails devise sti


    【解决方案1】:

    我个人认为未使用的列没什么大不了的,但是如果它真的困扰您,您可能想尝试一种非正统的解决方案。您是否考虑过“存储”所有不同类型用户不常见的属性?我说的是使用诸如attr_bucket 之类的插件。

    基本上你会在你的数据库表中添加一个额外的列:

    t.text :non_common_attributes
    

    然后在您的每个不同的用户模型(继承自一个公共类)中,您将拥有如下内容:

    class UserType1 < User
      attr_bucket :non_common_attributes => [:first, :second, :third]
    end
    
    class UserType2 < User
      attr_bucket :non_common_attributes => [:fourth, :fifth]
    end
    

    您可以像以正常方式定义它们一样使用属性,但是当您将模型保存到数据库中时,所有这些属性都将通过 YAML 序列化并存储在 :non_common_attributes 列中。当您再次加载模型时,它们将被透明地反序列化。

    有一些注意事项,例如您不想通过任何分桶属性搜索用户(因为您无法对这些属性进行索引)等。但在您的情况下,它可能只是什么你在追求。我不会太担心序列化和反序列化的成本,这可能不会成为问题,因为您不太可能同时保存/加载数千个用户。

    事实上,我使用了一个类似的解决方案(但手卷而不是使用宝石),其中大多数属性需要加密的模型。我只是将所有属性存储在一起并加密存储桶 - 很有效。

    【讨论】:

    • 以前从未遇到过这种方法。我会看看我们的要求,看看它是否适合。谢谢!
    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    相关资源
    最近更新 更多