代码之家  ›  专栏  ›  技术社区  ›  Alex Weinstein

关系数据库中的类对象结构[已关闭]

  •  8
  • Alex Weinstein  · 技术社区  · 17 年前

    各位,

    这里有一个场景:我的系统中有几种类型的“参与者”——工人、雇主、联系人。它们具有某些共同的功能;其他作品则大不相同。所有参与者处理的实体都是“通信”、“笔记”(管理员喜欢在客户身上留下笔记)等等。每种参与者类型都会处理大量其他类型的实体,而其他参与者类型则不会。

    演员:

    • 工人
    • 联系

    实体:

    • 等等

    • 员工沟通助理

    在DB世界中,这种选择在理论上似乎是可能的,但听起来非常混乱。..也就是说,如果我理解正确,我会有一个新的base_actor表,每个其他参与者都有一个base_actor_id,然后这些关联将在base_ator和实体之间。..但是,我该如何进行反向关联查询呢?即“只向我展示与类型工作者的演员的所有沟通”?

    9 回复  |  直到 17 年前
        1
  •  8
  •   troelskn    17 年前

    ..这是关于“如何以无痛的方式将OOP结构映射到数据库表。”

    你没有。

    面向对象代数和关系代数是两种根本不同的范式。如果没有主观的解释,你就无法在它们之间转换。这被称为阻抗失配,并被称为 The Vietnam of Computer Science .

        2
  •  7
  •   Scott Evernden    17 年前

    它被称为 ORM or Object Relational Mapping 有几十种产品声称可以帮助您将OO结构映射到关系表。例如,Ruby on Rails提供了Active Record来帮助弥合分歧。对于PHP,你有 Propel Doctrine Porte

        3
  •  6
  •   Ken Fox    17 年前

    这是我大约10年前提出的一个解决方案。使用这种设计的系统仍在运行,因此它运行良好,可以比我的大多数代码存活更长时间。;)今天我可能会使用Scott提到的ORM包之一,但直接使用SQL真的没有什么大问题。

    1. 使用合成对象id(oid)作为所有对象的主键。生成oid值需要序列生成器或自动递增列。

    2. 对最终类的查询是在相应的表上进行的。您可以将所有父类表连接到查询中,也可以延迟加载所需的属性。如果你的继承层次结构很深,而且你有很多类,那么ORM包真的可以简化你的代码。我的系统只有不到50个类,最大继承深度为3。

    这就是“只向我展示与类型工作者的演员的所有沟通”的样子。

    select * from comm c, worker w where c.actor=w.oid;
    

    如果你有通信的子类,并且你想立即加载所有子类属性(也许你的系统不允许部分构造),最简单的解决方案是急于加入所有可能的类。

    select * from comm c, worker w, missive m where c.actor=w.oid and c.oid=m.oid;
    select * from comm c, worker w, shoutout s where c.actor=w.oid and c.oid=s.oid;
    

    最后一件事。确保你有一个好的数据库和正确的索引。如果数据库不能优化这些连接,性能可能会成为一个严重的问题。

        4
  •  3
  •   Community Mohan Dere    9 年前

    你建议的方法在我看来是合理的。你可以在你的actor基表中添加一个actortype列,以区分不同类型的actor。每个特定actor表的PK将是actorbase表的FK,以避免“多毛”查询,并模拟类似“is-a”关系的继承。

        5
  •  3
  •   Manu JCasso    17 年前

    http://en.wikipedia.org/wiki/The_Third_Manifesto

    不幸的是,这并不是stackoverflow上一个单一答案的范围。我将在这里尝试缩写它,但我警告你,这样的缩写并不能准确反映第三份宣言。请将所有对这个解决方案的批评重新定向到实际阅读这个该死的东西上,而不是假设你从阅读缩写中完全理解了它。好的,开始吧。

    定义三种新的列类型,分别命名为worker、employer和contact。将每种类型的对象存储在各自类型的列中。遵循数据模型其余部分的标准化规则。

        6
  •  2
  •   Breton    17 年前

    如中所述,熟悉对象角色建模可能值得您花时间 this question 我看到的最大问题是,目前还没有公认的方法来对关系数据进行概念设计讨论。你能做的最好的事情就是逻辑建模(通常是ERM)。对象角色建模为该讨论提供了基础。我希望你能从类似的OOP设计讨论中看到可识别的工件。

        7
  •  1
  •   Community Mohan Dere    9 年前

    许多RDBMS提供表继承功能,该功能将父表链接到子表,其方式与类继承非常相似。不同供应商的实现略有不同,但它可以减轻实现类似概念的一些痛苦。

    此外,大多数RDBMS都有触发器、存储视图和存储过程的组合,可以将行为与实现分开。在许多情况下,例如PostgreSQL的规则(视图的泛化)提供了非常复杂的封装,并且非常易于使用。

        8
  •  0
  •   SingleNegationElimination    17 年前

    有几个人注意到对象关系阻抗不匹配。最好的解决方案就是放弃 RDBMS 赞成 OODBMS ,最近重新流行起来。

    也就是说,据我所知,在纯PHP中没有任何带有API的对象数据库。快速搜索生成 this result 但它已经多年没有更新了。另一方面,我听说有很多其他语言的对象数据库,包括 Hibernate , db4o ZODB .

        9
  •  0
  •   Nikhil    17 年前

    在我看来,你的数据模型似乎缺少了一个层次。我会把它设置得更像这样:

    角色 表-(人们可以担任的角色类型,即工人、雇主、联系人-以及该角色特有的信息)

    人员角色 表-(people_id、role_id,可能是开始/修改日期等)

    表-(角色_id、实体_id等)

    然后,将一个人从一个角色更改为另一个角色(或允许他们拥有多个角色)是一个简单的更新。

        10
  •  0
  •   LEMUEL ADANE    15 年前
        11
  •  0
  •   Tim Cooper    14 年前