在我的数据库中,我有一个模型,其中有一个字段应该从一个选项列表中选择。例如,考虑需要存储测量的模型,例如5英尺或13厘米或12.24立方米。实现这一目标的显而易见的方法是使用十进制字段,然后使用其他字段来存储测量单位。
那么存储测量单位的最佳方法是什么?我过去曾使用过几种方法:
1)将各种选项存储在另一个数据库表(和相关模型)中,并将两者与标准外键相关联(通常需要加载相关模型)。这似乎有些过分,因为你强迫数据库在每个查询上执行连接。
2)将选项存储为常量哈希值,加载到其中一个初始值设定项中,其中哈希值中的键存储在度量单位字段中。这样,您可以有效地在Ruby中进行连接(可能会或可能不会提高性能),但是您无法从“度量单位”方面进行查询。这不会是一个问题,前提是你不太可能需要进行“以cm为单位找到所有测量值”的查询。
这些对我来说都不是特别优雅..有人能提出更好的建议吗?
答案 0 :(得分:6)
你见过constant_cache吗?它是1和2中最好的组合 - 查找数据存储在数据库中,但它在查找模型上作为类常量公开,仅在应用程序启动时加载,因此您不会经常遇到连接惩罚。以下示例来自README:
迁移:
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)
答案 1 :(得分:3)
我会选择选项一。 UnitOfMeasurement表有多大?而且,如果使用整数主键,为什么你这么担心速度呢?
选项1是出于设计原因的方法。只需使用整数(即使是smallint)主键和单位描述字段声明它。
答案 2 :(得分:1)
ActiveRecord是否获得了对自然键的支持?如果有,你可以将name
表的UnitOfMeasure
(或其他)列设为PK,这样FK列的值就具有你需要的所有信息,你仍然有一个完全规范化的DB,具有规范的UnitOfMeasurement
值集。
答案 3 :(得分:0)
您是否需要对这些值执行查找?如果没有,您可以将它们存储为字符串,稍后在读取值的应用程序中解析字符串。虽然存在存储不可解析数据的风险,但您可以提高速度并降低数据库复杂性。有时规范化数据库没有帮助。最后/你的系统中的东西/需要知道“cm”是一个长度尺度,“m3”是房间尺寸,比较“3cm”到“1m3”无论如何都没有任何意义。所以你也可以将所有知识都放在代码中。
假设你只是要展示那些数据,这里的正常化是什么?