哪种数据模型存储策略?

时间:2009-08-23 05:37:27

标签: database language-agnostic data-modeling

我正在努力为数据模型的存储提供一个好的设计。语言是python,但我想这是不可知的。

目前我设想了三种可能的策略:

对象数据库

数据模型是一个对象网络。当我创建它们时,我将它们指定为持久性对象的后代。例如:

class Tyres(PersistentObject):
    def __init__(self,brand):
        self._brand = brand

class Car(PersistentObject):
    def __init__(self,model):
        self._model = model
        self._tyres = None
    def addTyres(self,tyres):
        self._tyres = tyres
    def model(self):
        return model

客户端代码不知道持久性,它操纵对象在内存中,并且持久性对象在没有客户端代码知道的情况下处理所有事情。可以通过数据库对象的键控查找来完成检索。这是Zope对象数据库(以及许多其他人)使用的方法。优点是延迟检索,更改仅在更改的对象中操作,而不检索未触及的对象。

搁置物品

上面给出的数据模型在内存中表示,但数据库随后用于推送或拉取数据作为单一实体。例如:

 car = Car("BMW")
 tyres = Tyres("Bridgestone")
 car.setTyres(tyres)
 db.store(car)

这就是基于泡菜的解决方案。从某种意义上说,它与之前的解决方案类似,唯一的区别是您将对象存储为单个包并再次将其作为单个包检索。

门面

具有便捷方法的单个数据库类。客户端代码永远不会处理对象,只处理ID。实施例

class Database:
     def __init__(self):
         # setup connection

     def createCar(self, model):
         # creates the car, returns a numeric key car_id

     def createTyresForCar(self, car_id, brand):
         # creates the tyres for car_id, returns a numeric id tyres_id

     def getCarModel(self, car_id):
         # returns the car model from the car identifier
     def getTyresBrand(self, car_id, tyre_id):
         # returns the tyre brand for tyres_id in car_id.
         # if tyres_id is not in car_id, raises an error.
         # apparently redundant but it's not guaranteed that
         # tyres_id identifies uniquely the tyres in the database.

这个解决方案颇具争议。数据库类可以承担很多责任,但我觉得这是SOAP中使用的哲学:你不能直接操作对象,而是对远程服务器执行对象属性的查询。如果没有SQL,这可能是关系数据库的接口:db.createTable()db.insert()db.select()。 SQL简化了这一过程,以语言(SQL)解析和执行的代价获得一个非常简单的数据库接口db.query(sql_string)。您仍然可以操作您感兴趣的数据模型的子部分,而无需触及其他部分。

我想问一下你对这三种设计的看法,特别是第三种。什么时候它是一个好的设计?如果有的话?

倒置逻辑

这是我在MediaWiki代码上看到的。而不是像

那样的东西
 db.store(obj)

他们有

 obj.storeOn(db)

编辑:我展示的示例数据模型有点简单。我的真正目标是创建一个基于图形的数据模型(如果有人想参与该项目我会很荣幸)。令我担心的是第三个解决方案强烈封装了写入的数据模型(而不是内存中的数据模型)并掩盖了后端,但它有可能爆炸,因为只有一个中心类暴露了所有方法。我必须诚实,我不喜欢第三种情况,但我认为它是一种可能的解决方案,所以我想把它放在问题的盘子上。可能会很好。

编辑2 :添加了反向逻辑条目

2 个答案:

答案 0 :(得分:1)

第一种设计与域驱动设计最兼容。让实现持久性对对象完全私有意味着您可以使用该对象而不考虑其关系表示。对象只能公开与其特定于域的行为相关的方法,而不是低级CRUD操作。高级方法是您希望向该对象的消费者提供的唯一API合约(即您不希望任何人都能够删除该车)。您可以实现复杂的数据关系,只在一个地方编码。

第二种设计可与访客模式一起使用。汽车对象知道它需要持久化的部分,但它没有与数据库的连接。因此,您将car对象传递给数据库连接实例。在内部,db知道如何调用它给出的对象。据推测,这款车实现了一些“db-callable”接口。

第三种设计有助于实现适配器模式。每个数据库品牌的API都不同,每种SQL的风格都略有不同。如果您有普通的API来进行普通数据库操作,您可以封装这些差异,并交换出一个知道如何与相应品牌数据库通信的不同实现。

答案 1 :(得分:0)

很难说,因为你的例子显然是做作的。

需要根据数据模型更改的频率做出决策。恕我直言,汽车不经常收集新零件;所以我会在你希望建模的所有项目的数据库中使用静态模型,然后将所有这些项目链接在一起,但是你实际做什么可能是错误的。

我建议您与我们讨论您需要建模的实际数据。

相关问题