database - 功能到关系的映射比对象到关系更容易吗?

标签 database orm functional-programming rdbms

<分区>

对象关系映射已被很好地讨论,包括在这里。我有一些方法以及陷阱和妥协的经验。真正的解决方案似乎需要更改 OO 或关系模型本身。

如果使用函数式语言,是否会出现同样的问题?在我看来,这两种范式应该比 OO 和 RDBMS 更好地结合在一起。在 RDBMS 中按集合思考的想法似乎与功能方法似乎 promise 的自动并行性相吻合。

有没有人有任何有趣的意见或见解?行业现状如何?

最佳答案

ORM 的目的是什么?

使用 ORM 的主要目的是在网络模型(面向对象、图形等)和关系模型之间架起桥梁。两种型号之间的主要区别非常简单。这是 parent 指向 child (网络模型)还是 child 指向 parent (关系模型)。

考虑到这种简单性,我相信 there is no such thing as an "impedance mismatch"两个模型之间。人们通常遇到的问题纯粹是特定于实现的,如果客户端和服务器之间有更好的数据传输协议(protocol),应该是可以解决的。

SQL 如何解决我们在 ORM 方面遇到的问题?

特别是 third manifesto尝试通过允许嵌套集合来解决 SQL 语言和关系代数的缺点,嵌套集合已在各种数据库中实现,包括:

  • Oracle(可能是最复杂的实现)
  • PostgreSQL(在某种程度上)
  • 英飞凌
  • SQL Server、MySQL 等(通过 XML 或 JSON 的“模拟”)

在我看来,如果所有数据库都实现了 SQL 标准 MULTISET() 运算符(例如 Oracle),人们将不再使用 ORM 进行映射(可能仍然用于对象图持久化),因为它们可以直接从数据库中具体化嵌套集合,例如这个查询:

SELECT actor_id, first_name, last_name,
  MULTISET (
    SELECT film_id, title
    FROM film AS f
    JOIN film_actor AS fa USING (film_id)
    WHERE fa.actor_id = a.actor_id
  ) AS films
FROM actor AS a

将所有 Actor 和他们的电影作为嵌套集合生成,而不是非规范化的连接结果(每部电影重复 Actor )。

客户端的函数范式

客户端的函数式编程语言是否更适合数据库交互的问题实际上是正交的。 ORM 有助于对象图持久化,因此如果您的客户端模型是一个图,并且您希望它是一个图,那么您将需要一个 ORM,无论您是否使用函数式编程语言来操作该图。

但是,由于面向对象在函数式编程语言中不那么惯用,因此您不太可能将每个数据项硬塞进一个对象中。对于编写 SQL 的人来说,投影任意元组 是很自然的。 SQL 包含结构类型。每个 SQL 查询都定义了自己的行类型,而无需事先为其分配名称。这与函数式程序员产生了很好的共鸣,尤其是当类型推断很复杂时,在这种情况下您永远不会考虑将 SQL 结果映射到某个先前定义的对象/类。

使用 jOOQ 的 Java 示例from this blog post可能是:

// Higher order, SQL query producing function:
public static ResultQuery<Record2<String, String>> actors(Function<Actor, Condition> p) {
    return ctx.select(ACTOR.FIRST_NAME, ACTOR.LAST_NAME)
              .from(ACTOR)
              .where(p.apply(ACTOR)));
}

与 SQL 语言被某种 ORM 抽象或者使用 SQL 的自然“基于字符串”的特性相比,这种方法导致 SQL 语句的组合性要好得多。现在可以使用上述功能,例如像这样:

// Get only actors whose first name starts with "A"
for (Record rec : actors(a -> a.FIRST_NAME.like("A%")))
    System.out.println(rec);

基于 SQL 的 FRM 抽象

一些 FRM 试图通过 SQL 语言进行抽象,通常出于以下原因:

  • 他们声称 SQL 的可组合性不够(jOOQ 反驳了这一点,它很难做到正确)。
  • 他们声称 API 用户更习惯于“原生”集合 API,例如JOIN被翻译成flatMap()WHERE被翻译成filter()

回答你的问题

FRM并不比ORM“简单”,它解决的是不同的问题。事实上,FRM 并没有真正解决任何问题,因为 SQL 本身就是一种声明式编程语言(与函数式编程没有太大区别),非常适合与其他函数式客户端编程语言相匹配。因此,如果有的话,FRM 只是弥合了 SQL、外部 DSL 和您的客户端语言之间的差距。

(我在 jOOQ 背后的公司工作,所以这个答案有偏见)

关于database - 功能到关系的映射比对象到关系更容易吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/218190/

相关文章:

javascript - 在 MongoDb 中使用 mapReduce 获取文档(行)计数

php - 如果不存在则使用 mysqli + php 创建数据库

php - ORM/DAO/DataMapper/ActiveRecord/TableGateway 的区别?

module - 如何定义模块签名,其模块实现由仿函数参数化

oop - 我应该编写利用 Intellisense 的代码吗?

php - 值未从 Android 设备插入 mysql 数据库

java - JPQL 在 Select 语句中创建新对象 - 避免还是接受?

.net - 哪个 ORM 工具支持 Microsoft Access?

unit-testing - 具有多种结构的 SML 签名

database - Postgres 复制