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

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

晚上看到一个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 条回复

可以组合。。。。。。

感觉不是很好理解

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

缺点是不支持非运算

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

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

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

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

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