连续第n次,我再次遇到同样的老问题.它是关于“如何以无痛的方式将OOP结构映射到数据库表”.
这是一个场景:我的系统中有几种类型的“演员” – 工人,雇主,联系人.他们有一些共同的功能;其他的作品有很大的不同.所有演员处理的实体是“通信”,“笔记”(管理员喜欢留下客户的笔记)等等.每个演员类型处理的其他实体有多种类型,而其他实体则不同.
演员:
>工人
>雇主
>联系
实体:
>沟通
>笔记
>等
实体和演员之间的关联表:
>工人沟通
雇主通讯委员会
工人笔记
等等,你得到钻头.
这感觉像是一个“代码气味”给我.每当客户改变角色(即从“联系人”提升为“雇主”)时,需要运行一堆疯狂的脚本. Yuck …另一方面,如果我在纯粹的OOP驱动的世界中运行,这将会更容易 – 拥有所有具有共同属性的实体的基类,并且可以完成它…
在数据库世界中,这个选择似乎在理论上是可能的,但听起来很混乱.如果我理解这个权限,我会有一个新的base_actor表,每个其他actor都有一个base_actor_id,然后这个关联将在base_actor和实体之间…然后,我如何进行反向关联查询?即“告诉我所有与类型工作者的沟通”?
>将所有的继承关系建模为表之间的连接.系统中的每个表都将保存特定类的属性.
>使用合成对象id(oid)作为所有对象的主键.需要一个序列生成器或自动增量列来生成oid值.
>所有继承的类必须使用与父类相同的oid类型.将oid定义为带有级联删除的外键.父表获取自动增量oid列,子代获取纯oid列.
>最终类的查询在相应的表上进行.您可以将所有父类表加入到查询中,或者只是延迟加载所需的属性.如果您的继承层次结构很深,并且您有很多类,则ORM包可以真正简化代码.我的系统有不到50个类,最大继承深度为3.
>跨越子类的查询(即父类的查询)可以延迟加载每个实例的子属性,也可以重复对与基类连接的每个子类的查询.基于父类查询的Lazy加载子属性需要知道对象的类型.您可能已经在父类中有足够的信息,但如果不是,您需要添加类型信息.再次,这是一个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,shoutout s where c.actor=w.oid and c.oid=s.oid;