【问题标题】:Database Design without NULL values and Repeating Data for iOS App没有 NULL 值和重复数据的 iOS 应用程序的数据库设计
【发布时间】:2014-08-27 16:10:38
【问题描述】:

在为一个新的 iOS 应用找到了大部分数据模型之后,我现在遇到了一个我一直在思考的问题。

“实验”具有名称、描述和所有者。它也有一个“动作”和一个“事件”。

“事件”可能是不同的事物:时间、地点或速度。

根据“事件”是什么,它可以有不同的“类型”。例如,时间可以是一次性的、间隔的、日期范围的、重复的或随机的。位置可以是区域或确切位置。

然后,每个“类型”都有一个值,该值具有自己独有的数据类型。 Time One-Off 可以是 12:15 pm 的日期值,而 Location Exact 可以是 (30.0, -20.0) 的 GeoPoint 值。

问题

  • 如何设计数据模型,让数据库不至于千疮百孔 使用 NULL 值?
  • 如果我添加更多“事件”,如何设计可扩展的数据模型 和“类型”。

想法

由于 Experiment 只有一个 Action 和一个 Event,将这两个分隔到不同的表中是错误的,但是不这样做会导致 Experiment 表充满 NULL 值,因为我必须有列事件、事件类型和事件类型值,以补偿可以为事件类型值输入的所有可能数据类型。 (日期、整数、字符串、地理点等)

将事件和事件类型分离到一个单独的表中可能会解决 NULL 值问题,但是我会留下重复数据,特别是在时间作为事件类型为下午 12:00 的事件的情况下,如这将存在于其他实验中,而不仅仅是一个。 (除非我创造了每一种可能性并用这些填充一个单独的表 - 但我怎么能轻松做到这一点?)

也许我把事情复杂化了,也许我错过了一些如此简单的东西,以至于当我看到它时我会踢自己。

【问题讨论】:

    标签: ios database-design persistence


    【解决方案1】:

    您需要根据对象而不是表来考虑您的数据模型。核心数据与对象图一起使用,因此核心数据中的所有内容都是一个对象。在 Objective-c 中,您使用对象。这就是您不需要 ORM 工具的原因。如果您考虑对象,那么我认为下面的模型(显然需要工作,但您应该明白这一点)是有道理的。将你的概念分离成这样的对象的好处是你可以从多个角度看待你的问题。换句话说,您可以从 Experiment 角度或 Event 角度来看它。我怀疑你会想要对数据做一些事情,比如在你的代码中使用你的时间对象来显示在日历上或设置一个提醒。获取特定类型的所有实验的所有事件等。通过将这些数据项封装在核心数据中的对象中,您可以在代码中利用、操作和修改一切。它还消除了您发现的空值问题。因为您不会为空值创建对象,而只会为与您的实验相关的值创建对象。话虽如此,您可能希望根据程序的具体情况进一步分解模型。此外,如果您设计得当,您将不会遇到您提到的重复数据问题。同样,您不是在处理正在处理对象的表中的行。如果您使用“one-off 12:00pm”创建事件类型对象,您可以通过其关系将该事件类型对象分配给任意数量的事件。您无需再次创建对象,只需引用它。当您想到这些关系时,您会认为“X 可以与 Y 相关联”。例如,“一个实验只能与 1 个事件相关联”、“一个事件类型可以与许多事件相关联”、“一个事件只能与 1 个事件类型相关联”。采用这种方法可以让您在未来获得可扩展性。假设您想添加一个新的事件类型。您只需创建一个新的事件实体并将其与您的事件类型实体相关联。

    我的建议是考虑您的对象模型与您预期如何在代码中使用对象(以及您预期如何通过查询访问对象)相关。这应该有助于推动你如何构建它(例如,如果你需要一个时间对象,那么确保你的对象模型中有它。如果你需要一个警报对象,那么确保你的对象模型中有它)。让模型为您完成工作,尽量不要编写大量代码来在 Objective-c 中组装对象模型的等价物,或者开始在代码中创建对象并使用数据存储中的数据填充它们。

    (编辑:用“事件类型”替换图中时间、位置和速度下的“事件”关系)

    【讨论】:

    • Wizkid,谢谢你,这张图很有帮助。但有一件事 - EventType 只有一种类型,而不是全部三种。所以无论是时间、地点还是速度。
    • 这很酷。如果事件类型不仅仅是一个名称(即列表),那么您可能希望将它们表示为模型中的对象(我不确定您想要做什么)。如果如您所说,那么请务必删除这 3 个实体,您应该会很好。我认为这是一个事件的方式可以与 3 种非常不同的事件类型之一相关联。事件类型实体将保存类型的描述性信息,而时间、位置、速度将保存与这些对象相关的详细信息(例如时间:日期、时间、时间范围、时区等)。祝你好运。
    • 问题是 - 我认为它们作为对象更好。问题是在这三个对象和事件类型对象之间创建关系而不创建 NULL 值,因为只有 1 是强制性的,所以其他两个将是 NULL。如何在没有两个 NULL 指针的情况下仅引用 Event Type 对象中的 1 个对象?
    • 好消息是您没有创建空“对象”。当您创建一个新类型时,您不会仅仅因为它们具有关系(即指针)而在数据存储中实例化 4 个对象。例如,只有当你有东西要存储(即不为空)时,你才会创建一个新的 Time 对象。然后,您将时间对象关联到您的事件类型,并将事件类型关联到您的事件。在事件类型中,在没有产生位置对象的获取之后,如果您检查位置关系指针,它将为零。所以“指针”是零。存储库中没有“空对象”概念。
    • 是的。鉴于您的情况,我认为没有办法解决这个问题。如果您创建了一个对象并将所有内容都塞入其中(例如,仅一个事件类型实体并杀死其他 3 个实体),那么您将拥有一堆具有空值的属性)。因此,您将不得不处理空关系 (=2) 或多个空属性 (>2)。我更喜欢第一个,因为至少您的查询具有更大的灵活性。
    猜你喜欢
    • 2014-02-18
    • 2011-12-07
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 2016-03-17
    • 2018-01-31
    相关资源
    最近更新 更多