Rails 利用位运算在一个字段存多个属性值有什么弊端?

wfwdex · 发布于 2017年11月17日 · 最后由 hging 回复于 2017年12月15日 · 728 次阅读
19842

晚上看到一个gem, bit_settings, 文件

核心代码:

def add_settings(settings:, column: :settings, prefix: nil)
  prefix = prefix ? "#{prefix}_" : ''
  if settings.size > 32
    raise 'You can NOT have more than 32 settings (max unsigned int with 4 bytes is 2^32-1)'
  else
    settings.each_with_index do |setting, i|
      define_method "#{prefix}#{setting}" do
        self.send(column) & (1 << i) > 0
      end
      alias_method "#{prefix}#{setting}?", "#{prefix}#{setting}"
      define_method "#{prefix}#{setting}=" do |value|
        if ActiveModel::Type::Boolean.new.cast(value)
          self.send("#{column}=", self.send(column) | (1 << i))
        else
          self.send("#{column}=", self.send(column) & ~(1 << i))
        end
      end
    end
  end
end

这个gem主要实现在一个字段存多个(最大32个)bool型的属性。

这样做看起来很酷,想知道如果在现实的项目中这样用,有没有什么弊端?或者不方便的地方?

我能想到有一个场景不方便,比如按指定的多个属性做group by操作。

共收到 7 条回复
9800

可以组合。。。。。。

8744

感觉不是很好理解

15073

这就是bitmap的实现吧,好处是可以节省内存,位运算性能高。

缺点是不支持非运算

30379

违反了关系型数据库的一范式。

17004

你一定要做group by 并且用这种方案 感觉适合列式存储 并不适合一般的数据库

4002

我们就是这样做的,场景是在一个数字字段里存储多选框。目前遇到的问题是,作为查询条件时速度慢

11562

有一个好处 就是很好做扩展 有一个坏处 就是很难做扩展。 好做扩展就是加一个值的事儿。。 难扩展是因为这个数值的增量是指数级的。。 实际很多时候控制权限会用这个。 比如linux的权限用的应该就是位运算

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册