数据库设计困境

3
我正在为报告创建一个简单的数据库应用程序。根据数据库设计理论,您永远不应该两次存储相同的信息。对于大多数数据库应用程序来说,这是有道理的,但我需要一些东西,您可以简单地选择一个通用主题,然后保留通用主题的新实例副本不变或更改信息,但是不能通过修改实例副本来修改通用主题,但需要跟踪原始主题和主题实例副本之间的关系。
混乱,我知道。这里有一个可能有所帮助的图表:
我需要基于情况使报告是不可变的或可变的。一个快速的例子是您选择了一个客户,然后完成了报告。一个月后,客户的电话号码发生变化,因此您更新了数据库中的客户部分,但是您不希望打开已完成的报告并将新信息更新到其中。已经完成的报告中。
在这种情况下,最优雅的解决方案是什么?也许这个方案可以工作,但是使用循环语句和条件语句来识别通用、已选和报告之间的关系:
for (NSManagedObject *managedObject in checkedOffTaskObjects) {
    if ([[reportObject valueForKeyPath:@"tasks"] containsObject:managedObject]) {
        if ([[managedObject valueForKeyPath:@"tasks"] containsObject:genericTaskObjectAtIndexPath]) {
            cell.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellbackground.png"]] autorelease];
        }            
    }
}

我知道有更好的解决方案,但我看不到它。

谢谢您的时间。


在你的示例代码中,我理解你是指“in checkedOffTaskObjectS”(复数形式,小写)?如果你用大写字母写实例变量,会让人感到困惑,因为它们看起来像类。 - occulus
而且,如果“task”应该是“tasks”,那么你的代码示例就会更难理解。请问您能否修正一下? - occulus
在你的示例代码中,“...”表示什么?这意味着你正在检查的已勾选任务对象在当前考虑的报告中,并且它是一个通用任务吗? - occulus
1个回答

2
很难在不了解您要建模的内容的情况下非常精确,但是我们可以这样做...
正如您所指出的,至少有两种策略可以实现您想要的“原型可变实例副本”功能:
1) 基于原型创建实例时,完全从原型复制实例数据。之后它们之间没有任何联系。
优点:更快速地访问实例数据,涉及的逻辑较少。
缺点1:对原型进行的任何更新都不会反映在实例中。例如,如果在原型中公司地址错误。
缺点2:您正在复制数据库数据——在某种程度上是浪费的,如果记录很大。
2) 基于原型创建实例时,存储对“父”记录(即原型)的引用,然后仅在实际实例中存储更新的字段。
优点1:原型的更新会反映在所有实例中。
优点2:更有效地使用存储空间(减少数据重复)
缺点:涉及提取来自数据库的实例的更多逻辑。
总之:我无法想到任何神奇的解决方案,可以同时获得这两个世界的最佳解决方案。这两种策略都是有效的,具体取决于您的确切问题和约束条件(例如运行时速度与存储大小)。
如果您选择2),我认为这并不是一场灾难——特别是如果您在核心数据中对事物进行良好建模并找到最佳最有效的结构方式。

我选择了第二个选项。它能够正常工作,并且在大量样本数据的情况下运行速度似乎也是可以接受的。感谢您的时间和建议。知道这种情况下并不存在万能解决方案,这对我很有帮助。 - Unixed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接