我正在尝试为数据模型的存储提出一个好的设计。语言是 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 对此进行了简化以获得非常简单的数据库接口,db.query(sql_string)
代价是语言 (SQL) 解析和执行。您仍然可以对您感兴趣的数据模型的子部分进行操作,而无需触及其他部分。
我想问问你对这三种设计的看法,尤其是第三种。什么时候是一个好的设计,如果有的话?
反转逻辑
这是我在 MediaWiki 代码上看到的。而不是有类似的东西
db.store(obj)
他们有
obj.storeOn(db)
编辑:我展示的示例数据模型有点简单。我的真正目标是创建一个基于图形的数据模型(如果有人想参与该项目,我将很荣幸)。第三种解决方案让我担心的是,它强烈地封装了写入的数据模型(与内存中的数据模型相反)并屏蔽了后端,但它有爆炸的风险,因为只有一个中心类暴露了所有方法。老实说,我不喜欢第三种情况,但我认为它是一种可能的解决方案,所以我想把它放在问题的盘子上。它可能有好处。
编辑 2:添加了反转的逻辑条目