我的情况涉及编写项目报告的公司,项目和员工。
公司拥有许多项目,许多报告和许多员工 一份报告是由一名员工为公司的一个项目撰写的。
公司在报告中都需要不同的东西。假设有一家公司希望了解项目绩效和速度,而另一家公司想了解成本效益。有5-15个标准,每个公司设置不同,所有标准都适用于该公司的所有项目报告。
我正在考虑采用不同的方法,但我目前的僵局是:
criteria
,其中包含按顺序排列的所需条件数组。company_id
和一列criterion1
,criterion2
等。我完全清楚这通常被认为是可怕的数据库设计 - 不优雅且不灵活。所以,我需要你的帮助!我怎样才能更好地建立这个?
由于以下原因,我决定使用序列化选项:
答案 0 :(得分:3)
这将是使用NoSQL的绝佳机会!看起来像教科书用例对我来说。所以请转到CouchDB或Mongo并开始黑客攻击。
对于传统的数据库,您会轻微地了解数据规范化的问题:
一种“好”的方式(意思是非常规范化的)看起来像这样:
class Company < AR::Base
has_many :reports
has_many :criteria
end
class Report < AR::Base
belongs_to :company
has_many :criteria_values
has_many :criteria, :through => :criteria_values
end
class Criteria < AR::Base # should be Criterion but whatever
belongs_to :company
has_many :criteria_values
# one attribute 'name' (or 'type' and you can mess with STI)
end
class CriteriaValues < AR::Base
belongs_to :report
belongs_to :criteria
# one attribute 'value'
end
这使得NoSQL中的一个非常简单和快速的东西成为SQL中的三重或四重连接,并且你有很多模型几乎什么都不做。
另一种方法是反规范化:
class Company < AR::Base
has_many :reports
serialize :criteria
end
class Report < AR::Base
belongs_to :company
serialize :criteria_values
def criteria
self.company.criteria
end
# custom code here to validate that criteria_values correspond to criteria etc.
end
与此相关的是至少序列化标准的相当聪明的方法(如果它们都是布尔值,则可能是值)使用位字段。这基本上为您提供了或多或少的轻松迁移(难以删除和修改,但易于添加)和搜索功能,无需任何开销。
实现此目的的一个好插件是Flag Shih Tzu,我已经在一些项目中使用过并且可以推荐。
变量列(例如crit1
,crit2
等)。
我强烈建议不要这样做。你没有获得太多的好处(因为你不知道你的信息在哪一列,它仍然不是很容易搜索)并且它导致可维护性的噩梦。想象一下,你的数据库获得了几百万条记录,突然有人需要16个标准。本来可以完全没有问题的是突然迁移,为数百万条记录增加了一个完全没用的字段。
另一个问题是很多ActiveRecord魔法都无法解决这个问题 - 你必须自己弄清楚crit1
的含义 - 现在如果你不想在这些字段上添加验证,那么这增加了许多毫无意义的工作。
总结一下:看一下Mongo或CouchDB,如果这看起来不切实际,请继续保存你的东西serialized。如果您需要进行复杂的验证并且不太关心数据库负载,那么请将其标准化并选择选项1.
答案 1 :(得分:0)
创建一个criteria
表,其中列出了每家公司的条件(company
1 .. * criteria
)。
然后,创建一个report_criteria
表(report
1 .. * report_criteria
),根据criteria
表({{1}列出该特定报告的条件1 ... * criteria
)。
答案 2 :(得分:0)
好吧,当你说“到公司表时,添加文本字段标准,其中包含一系列所需的标准”,闻起来像公司表想要规范化:你可以在15中的一个中打破每个标准名为“criterion1”,...,“criterion15”的列,其中任何或所有列都可以默认为null。
对我而言,您与报告表一起走在正确的轨道上。该表中的每一行可能代表一个报告;并且可能有相应的列“criterion1”,...,“criterion15”,正如您所说,每个单元格表示公司在该列标准上的表现。每个公司将有多个报告,因此您需要在报告表中显示日期(或报告编号或类似)列。然后日期加上公司ID可以是复合键;并且公司ID可以是非唯一索引。报告日期/号码/某些标识符也是如此。并且不要忘记报告员工ID的列。
报告表中的任何和每个标准列都可以为空,这意味着(可能)员工没有报告此标准;或者该标准(专栏)不适用于本报告(行)。
看起来这样可以正常工作。我没有看到你需要加入。它看起来非常简单,至少对于这些天真无知的眼睛来说。