【问题标题】:How to increment key values by power of two如何通过 2 的幂来增加键值
【发布时间】:2016-06-20 16:11:54
【问题描述】:

我有兴趣在单个列中存储多个值,而不是使用传统的多对多表:

class Beer
  include DataMapper::Resource

  property :id, Serial
  property :name, String
  property :containers, Integer # use bit arithmetic to store multiple values

  validates_presence_of :name, :containers

end

class Container
  include DataMapper::Resource

  property :id, Serial # increment in powers of two?
  property :name, String
  property :volume, Integer

  validates_presence_of :name, :volume

end

容器:

ID  Name    Volume  Unit
1   Growler 64      oz
2   Cowler  32      oz
4   Bomber  750     mL
8   Six-fifty  650  mL
16  4 pack  64      oz
32  6 pack  72      oz

啤酒:

ID  Name Containers
1   LSD  72
2   Düo  16

是否有一种简单的方法可以配置 DataMapper 资源以以 2 的幂递增序列值?我假设该协会将是一个挑战。

【问题讨论】:

  • 这有什么好处?
  • 需要维护的表更少。按位查询快速而强大。也就是说,我可能需要视图中的辅助函数来将 Containers 转换为其字符串表示形式。
  • 这一切都在为失败做好准备。不要这样做。使用序列号和适当的关系表。你在这里以最糟糕的方式违背了规律,要让事情保持在正轨上将是一场持续的斗争。请记住,Postgres 有一个 ARRAY 列,如果您需要任意数据结构,MySQL 和 Postgres 都支持 JSON

标签: ruby ruby-datamapper


【解决方案1】:

Serial 属性类型无法做到这一点,但可以使用 Integer 和 before :create 挂钩:

class Container
  include DataMapper::Resource

  property :id, Integer, key: true # Use whatever options you like
  property :name, String
  property :volume, Integer

  validates_presence_of :name, :volume

  # Create a new id based on the last element
  before :create do |c|
    last_container = Container.last
    # If integer has N bits, then you can only store N containers in your database (normally, 32 or 64 bits).
    c.id = last_container ? (last_container.id * 2) : 1
  end
end

无论如何,您应该使用关系模型,而不是使用这个 hacky-tricks,因为有人已经对您的帖子发表了评论。它比这种解决方案更易于维护、易于阅读和简单。


哦,顺便说一下,如果您需要快速访问数据库,您应该查看Graph databasesneo4jrb,这是Neo4j 的OGM。

【讨论】:

  • 非常漂亮的解决方案。正如大家所建议的那样,我可能会走“标准”路线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 2015-01-06
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
相关资源
最近更新 更多