2

这是一个以前可能已经问过的问题,但是我很难找到我的确切情况,所以我将解释我的情况以寻求一些反馈:

我有一个将注册位置的应用程序,我有几种类型的位置,每种位置类型都有一组不同的属性,但是我需要将注释与位置相关联,而不管它们的类型和其他类型的内容(主要是多媒体条目和评论)到所说的笔记。考虑到这一点,我想出了几个解决方案:

  1. 为每个位置类型创建一个表,并为每个带有外键的位置表创建一个“注释”表,这非常麻烦,因为我必须为每个评论表创建一个多媒体和评论表,例如:

    • 位置类型A

      • ID
      • 属性1
      • 属性2
    • LocationTypeA_Notes

      • ID
      • 属性1
      • ...
      • 位置类型A_fk
    • LocationTypeA_Notes_Multimedia

      • ID
      • 属性1
      • ...
      • LocationTypeA_Notes_fk

    以此类推,这样做会很烦人,但是完成后,在这种结构上进行开发应该不会那么麻烦。

  2. 创建一个具有唯一标识符的表,用于该位置并指向那里的内容,如下所示:

    • 地点

      • ID
    • 位置类型A

      • ID
      • 属性1
      • 属性2
      • 位置_fk
    • 笔记

      • ID
      • 属性1
      • ...
      • 位置_fk
    • 多媒体

      • ID
      • 属性1
      • ...
      • Notes_fk

    如您所见,这要简单得多,也更容易开发,但我只是不喜欢只有 ID 的表的外观(是的,这确实是我对此的唯一反对意见,这是我最喜欢的选项, 老实说)。

  3. 类似于选项 2,但我会有一个巨大的属性表,形状如下:

    • 地点

      • ID
      • 类型
    • 属性

      • 姓名
      • 价值

    以此类推,或者每个属性一个表;一个拉德鲁帕尔。这将是一个痛苦的开发,因为它需要几个插入/更新操作来在一个位置上做一些事情,并且属性表将比位置表大几倍(或者最终有大量的属性表);它也有代理键唯一表的相同问题(只是它现在有一个“类型”,我将使用它来以编程方式定义位置的行为),但这是一个很好的解决方案。

那么,对于这个问题:在性能和可扩展性方面哪个会是更好的解决方案?,您会选择哪种方案,或者您会提出哪些替代方案?我实现这些都没有问题,选项 2 和 3 将是一个有趣的发展,我从来没有做过这样的事情,但我不想选择在内容时会自行崩溃的选项增长一点;你可能在想“如果你知道 Drupal 的工作方式和你期望的一样,为什么不直接使用它?”,我在想“你显然不知道使用 Drupal 有多么困难,或者你是专家,我绝对不是”。

另外,既然我已经写了所有这些,您认为选项 2 总体上是一个好主意吗?您知道分组实体/模拟继承的更好方法吗?(请不要说“只使用继承!”,我仅限于使用 MySQL)。

感谢您的反馈,如果我写的太多而意思太少,我很抱歉。

4

1 回答 1

4

ORM 系统通常使用以下解决方案,大部分与您在此处列出的解决方案相同:

每个层次结构一个表

优点:

  • 简单的方法。
  • 易于添加新类,您只需为其他数据添加新列。
  • 通过简单地更改行的类型来支持多态性。
  • 数据访问速度很快,因为数据在一个表中。
  • 临时报告非常简单,因为所有数据都在一张表中。

缺点:

  • 类层次结构内的耦合增加了,因为所有类都直接耦合到同一个表。
  • 一个类的变化会影响表,然后会影响层次结构中的其他类。
  • 数据库中可能浪费的空间。
  • 当类型之间存在显着重叠时,指示类型变得复杂。
  • 对于大型层次结构,表可以快速增长。

何时使用:

  • 对于简单和/或浅类层次结构来说,这是一个很好的策略,其中层次结构中的类型之间几乎没有重叠。

每个具体类一张表

优点:

  • 易于进行临时报告,因为您需要的有关单个类的所有数据仅存储在一个表中。
  • 访问单个对象数据的良好性能。

缺点:

  • 当你修改一个类时,你需要修改它的表和它的任何子类的表。例如,如果要向 Person 类添加身高和体重,则需要向 Customer、Employee 和 Executive 表添加列。
  • 每当一个对象改变其角色时,也许您雇用了一个客户,您需要将数据复制到适当的表中并为其分配一个新的 POID 值(或者您可以重用现有的 POID 值)。
  • 很难支持多个角色并仍然保持数据完整性。例如,您将在哪里存储既是客户又是员工的人的姓名?

何时使用:

  • 更改类型和/或类型之间的重叠很少见。

每班一桌

优点:

  • 由于一对一的映射,易于理解。
  • 很好地支持多态性,因为您只需在每种类型的相应表中都有记录。
  • 修改超类和添加新的子类非常容易,因为您只需要修改/添加一个表。
  • 数据大小的增长与对象数量的增长成正比。

缺点:

  • 数据库中有很多表,每个类一个(加上维护关系的表)。
  • 使用此技术可能需要更长的时间来读取和写入数据,因为您需要访问多个表。如果您通过将每个表放在不同物理磁盘驱动器盘片上的类层次结构中来智能地组织数据库,则可以缓解此问题(假设磁盘驱动器磁头都独立运行)。
  • 除非您添加视图来模拟所需的表,否则对您的数据库进行临时报告是很困难的。

何时使用:

  • 当类型之间存在显着重叠或更改类型很常见时。

通用架构

优点:

  • 当数据库访问被一个健壮的持久性框架封装时工作得很好。
  • 它可以扩展以提供元数据以支持广泛的映射,包括关系映射。简而言之,它是映射元数据引擎的开始。
  • 它非常灵活,使您能够快速更改存储对象的方式,因为您只需要相应地更新存储在 Class、Inheritance、Attribute 和 AttributeType 表中的元数据。

缺点:

  • 非常先进的技术,起初可能难以实施。
  • 它仅适用于少量数据,因为您需要访问许多数据库行来构建单个对象。
  • 您可能希望构建一个小型管理应用程序来维护元数据。
  • 由于需要访问多行来获取单个对象的数据,因此针对这些数据进行报告可能非常困难。

何时使用:

  • 对于处理少量数据的复杂应用程序,或者对于您的数据访问不是很常见的应用程序,或者您可以将数据预加载到缓存中。
于 2013-12-26T14:40:46.863 回答