【问题标题】:Rails - Should I use boolean fields or relational table?Rails - 我应该使用布尔字段还是关系表?
【发布时间】:2009-01-29 21:58:13
【问题描述】:

用户模型有三个键:is_masteris_standardis_guest 因为我本来想用activerecord的布尔方法比如is_master?或is_power?.

但是,如果创建一个 UserType 关系并创建我自己的方法会更好:

def master?
   return true if self.user_type = 1
end

【问题讨论】:

  • 对不起,我忍不住了,但是你写的代码需要重构。 >>定义大师? >>>> 1 == self.user_type >> end 与您编写的相同,但仅有效。 (Doh!没有办法在 SO 中的 cmets 内格式化代码。代码中的“>”表示缩进。)
  • 仅供参考:执行 self.user_type == 1。这会返回一个布尔值,因此您不必通过 if 测试手动返回布尔值。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

如果主/标准/来宾关系是互斥的(也就是说,您只能是其中之一),那么存储类型的字段(请以人类可读的形式 - 没有不透明的数字)是更好的。你总是可以简单地重新实现is_foo?

另一方面,如果您的帐户可以同时包含多个主/标准/访客/其他帐户,那么请坚持使用单独的布尔字段。

【讨论】:

    【解决方案2】:

    作为一名 DBA,我总是讨厌人们将列用作标志,因为这将是很多额外的列。 如果都是相同的类型(如帐户类型),我会按照第一个答案的建议进行操作(包括使用文本,而不是数字)。

    另一方面,如果您需要它用于单独的标志或多种类型(但数量有限),我实际上会进行二进制计算。

    也就是说,在表格中有一列代表所有标志,然后为每个标志分配一个编号。

    例如

    FLAGS = {:master => 1, :standard => 2, :guest => 4, :power => 8, 
             :another_flag => 32, :yet_another_flag => 64}
    
    def is_master?
        self.flags & FLAGS[:master]
    end
    
    def is_standard?
        self.flags & FLAGS[:standard]
    end
    

    设置值时需要做更多的工作,但不会因为很多列仅用于标志而使表格混乱。

    【讨论】:

    • 由于您使用的是 Rails,我假设您可能使用的是 MySQL。据我所知,MySQL 不支持位图索引。因此,如果您想查找具有给定标志的所有用户,那么您可以执行 SELECT * FROM users WHERE (flags&1 = 1) 之类的查询,该查询不会使用索引并进行全表扫描。
    【解决方案3】:

    如果您查看 RESTful 身份验证插件是如何做到的(包括用户角色),他们会使用连接表。

    我认为联接更具可读性。使用联接可以让您更灵活地使用角色系统。

    如果您要求用户只能拥有一个角色,我会将该逻辑放入您的模型中。

    【讨论】:

      【解决方案4】:

      我将从解决您当前需求的最简单的事情开始。根据需要重构并增加复杂性。听起来一组布尔列正是您所需要的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-02
        • 2012-05-18
        • 2021-12-29
        • 2012-09-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多