存储数据库中引用的常数的最佳方法?
在我的数据库中,我有一个模型,该模型具有一个应从选项列表之一中选择的字段。例如,考虑一个需要存储测量值的模型,例如5ft或者13cm或者12.24m3. 实现此目的的明显方法是先保留一个十进制字段,然后再保留一个其他字段来存储度量单位。
那么,存储度量单位的最佳方法是什么?过去,我使用了几种方法:
1)将各种选项存储在另一个数据库表(和关联的模型)中,并将两者与标准外键链接(通常急于加载关联的模型)。这似乎有点矫kill过正,因为我们正在强迫数据库对每个查询执行联接。
2)将选项存储为常量哈希,并加载到初始化程序之一中,哈希中的密钥存储在度量单位字段中。这样,我们可以有效地在Ruby中进行联接(这可能会或者可能不会提高性能),但是我们失去了从"度量单位"侧进行查询的能力。只要我们不太可能需要执行诸如"以cm为单位查找所有测量值"之类的查询,这将不是问题。
这些对我来说都不是特别优雅。.有人可以提出更好的建议吗?
解决方案
我会选择第一种。 UnitOfMeasurement表有多大?而且,如果使用整数主键,为什么还要担心速度呢?
出于设计原因,选择方法1是可行的。只需使用一个整数(甚至是smallint)主键和一个用于单元说明的字段来声明它。
ActiveRecord是否已获得对自然键的支持?如果有的话,我们只需将UnitOfMeasure表的name(或者其他)列作为PK,这样FK列的值将包含我们需要的所有信息,并且我们仍然具有完全标准化的DB一组标准的UnitOfMeasurement值。
我们是否需要对这些值执行查找?如果没有,我们也可以将它们存储为字符串,并稍后在读取值的应用程序中解析该字符串。当我们冒着存储无法解析的数据的风险时,我们可以提高速度并降低数据库的复杂性。有时规范化数据库是没有帮助的。最后,系统中的/ something /需要知道" cm"是长度度量,而" m3"是房间度量,将" 3cm"与" 1m3"进行比较毫无意义。因此,我们也可以将所有这些知识都放在代码中。
假设我们无论如何都只会显示该数据,这对这里的标准化有什么好处?
我们看过constant_cache吗?它是将最好的1和2查找数据组合在一起存储在数据库中的方法,但是它在查找模型中作为类常量公开,并且仅在应用程序启动时才加载,因此我们不会经常遭受连接惩罚。以下示例来自自述文件:
移民:
create_table :account_statuses do |t| t.string :name, :description end AccountStatus.create!(:name => 'Active', :description => 'Active user account') AccountStatus.create!(:name => 'Pending', :description => 'Pending user account') AccountStatus.create!(:name => 'Disabled', :description => 'Disabled user account')
模型:
class AccountStatus < ActiveRecord::Base caches_constants end
使用它:
Account.new(:username => 'preagan', :status => AccountStatus::PENDING)