当前位置:  开发笔记 > 编程语言 > 正文

关系数据库中面向对象的结构

如何解决《关系数据库中面向对象的结构》经验,为你挑选了3个好方法。

伙计们,

连续第n次,我再次遇到同样的老问题.它是关于"如何以无痛的方式将OOP结构映射到数据库表".

这是一个场景:我的系统中有几种类型的"演员" - 工人,雇主,联系人.它们具有某些共同的功能; 其他作品则截然不同.所有参与者处理的实体都是"通信","笔记"(管理员喜欢给客户留言)等等.每种演员类型处理的其他实体有很多类型,而其他实体则没有.

目前,我的数据库架构包括以下表:

演员:

工人

雇主

联系

实体:

通讯

笔记

等等

实体和参与者之间的关联表:

工人通信ASSN

雇主通信ASSN

工人笔记,ASSN

等等,你得到了演练.

这对我来说就像一个"代码味道".每当客户改变他们的角色(即从"联系人"提升为"雇主")时,就需要运行一堆疯狂的脚本.哎呀...另一方面,如果我在纯粹的OOP驱动的世界中运行,这将更容易 - 为具有共同属性的所有实体提供基类,并完成它...

在DB世界中,这个选项似乎在理论上是可行的,但听起来非常混乱......即如果我理解这一点,我会有一个新的base_actor表,而其他每个actor都会有一个base_actor_id,然后关联将介于两者之间base_actor和实体......但是,我如何进行反向关联查询?即"向我展示与工人类型的演员的所有沟通"?

有什么建议?关于"将OOP结构映射到关系数据库"主题的一般想法?



1> troelskn..:

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

你没有.

面向对象和关系代数是两种根本不同的范例.没有主观解释,你不能在它们之间转换.这被称为阻抗不匹配,被称为计算机科学越南.



2> Scott Evernd..:

它被称为ORM或对象关系映射.有许多产品旨在帮助您将OO结构映射到关系表.例如,Ruby on Rails提供Active Record以帮助弥合鸿沟.对于PHP,您有Propel和Doctrine以及Porte和许多其他人.



3> Ken Fox..:

这是我10年前提出的解决方案.使用此设计的系统仍在运行,因此它的运行时间比我的大多数代码都要长.;)今天我可以使用Scott提到的一个ORM包,但是直接使用SQL确实没有大问题.

    将所有继承关系建模为表之间的连接.系统中的每个表都将包含特定类的属性.

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

    所有继承的类必须使用与其父类相同的oid类型.将oid定义为具有级联删除的外键.父表获取自动增量oid列,子项获取普通的oid列.

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

    跨子类的查询(即父类的查询)可以基于每个实例延迟加载子属性,也可以对与基类连接的每个子类重复查询.基于父类查询的延迟加载子属性要求您知道对象的类型.您可能已经在父类中有足够的信息,但如果没有,则需要添加类型信息.同样,这是ORM包可以提供帮助的地方.

可以在表结构中跳过没有成员属性的虚拟类,但是您将无法基于这些类进行查询.

这就是"向我展示与工人类型的演员的所有沟通"的样子.

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;

最后一件事.确保您拥有良好的数据库和正确的索引.如果数据库无法优化这些连接,则性能可能是一个严重的问题.

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有