繁体   English   中英

您能否以关系数据库可以理解的方式表示应用程序对象?

[英]Can you represent an application object in a way that a relational database can understand?

Bill Karwin的博客文章“ 为什么要使用ORM ?” 在Reddit上进行了讨论,我对以下几点感到困惑。

他在评论部分中说:

OODBMS和ORM仅适用于我们在应用程序层中实例化的对象。 也就是说,无法执行以下查询:

UPDATE Bugs SET status ='CLOSED'WHERE status ='OPEN';

要在ORM或OODBMS中执行此操作,您必须获取所有符合条件的错误并为它们实例化对象。 然后,您可以设置属性,然后将对象一个接一个地保存到数据库中。 与上面显示的等效SQL操作相比,这很昂贵,并且当然需要更多的代码。

这说明了SQL之类的语言的优点,该语言将集合视为一流的数据类型。 在所有情况下,OO范例都不能替代关系范例。 SQL有一些普通的操作可以做得更好。

我加粗了一部分,他说您在使用ORM时必须实例化这些错误的对象,因为那是我感到困惑的部分。

我的问题是你为什么要这么做? 好的,面向对象是一回事,关系是另一回事。 但是,它们之间确实如此不同,以至于没有办法表示对象以便关系数据库可以理解它,这是真的吗? 例如, 我在考虑如何序列化对象,然后将其写入文件可存储格式。 您不能使用这种格式将对象传输到关系数据库吗?

有没有一种方法可以表示对象,以便关系数据库可以理解它?

您错过了我的发言重点。 我并不是说不能在关系数据库中存储对象。 我的意思是OO范例假定您在应用程序空间中具有该对象的实例。 也就是说,您可以调用对象的方法和访问属性:

$bug->status = 'CLOSED';
$bug->save();

但是在我见过的*任何ORM中,您必须先从数据库中获取对象实例,然后才能对它进行操作。 您也不能像使用SQL那样一次处理整个行集。

看到一个对象类型映射到一数据的ORM包会很有趣。 然后,当您更改属性时,该属性将应用于该集中的所有行。 我还没有看到任何ORM尝试这样做。

由于并发问题,这将是非常具有挑战性的。 实例化对象,执行更改或保存更改时,集合中是否包含该集合中的行? 如果它支持所有这些排列作为选项,则使用起来会变得非常复杂,以至于人们可能会认为它与直接使用SQL相比并没有任何实际的改进。

发表您的评论:并不是集合和对象不兼容。 集合可以是一个对象(Java甚至具有Collection和Set的类)。 但是OO范例假设操作适用于一个对象实例,而关系运算符始终适用于集合(一行的集合仍然是集合)。 实际上,当今存在的ORM软件包都做出了相同的假设,即一次只能更改一行的一个实例,并且必须先获取该行才能进行更改。

从理论上讲,扩展ORM的功能以处理集合是可能的-但AFAIK尚无人尝试这样做。 我的主张是,可以执行关系运算符可以执行的所有操作的ORM比使用SQL要差得多。

*我排除了像SQL一样的伪语言,例如HQL,它们恰好是ORM包的一部分(对于HQL,它是Hibernate),但是伪语言本身不符合ORM的条件。

ORM将对象的状态映射到数据库中的等效状态。 因此,如果要使用ORM更改数据库中某些内容的状态,唯一可用的机制是首先操作数据库表示的对象,然后保存它们的状态。

我不确定您的意思是:

我正在考虑如何序列化对象,然后将其写入文件可存储格式。 您不能使用这种格式将对象传输到关系数据库吗?

您是说将一个对象序列化为一个结构,该结构主要可以存储在一个平面文件(例如XML格式)中,然后将该数据存储在数据库中? 如果是这样,可以。 挑战将是您想搜索哪些信息。 假设您要查找所有“已关闭”的错误,则必须阅读每个错误,将其反序列化,然后检查其状态以查看是否应将其包含在列表中。

ORM的基本目的是将数据从一种表示转换为另一种表示。 引用的语气是SQL更适合于批处理,这是正确的-因为ORM会将关系数据表转换为对象图,然后再转换为表。

一个(非常松散)的类比是有一个要染成红色的纸浆桶。 如果大桶代表SQL数据库,则只需将染料倒入其中并进行搅拌。 使用ORM就像将纸浆转化为纸,对单张纸进行染色,然后重新制浆(现已着色)纸以放入大桶中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM