JSON 关系二元性(JSON Relational Duality)是 Oracle Database 23ai 中的一项里程碑式功能,它为 Oracle 数据库开发人员提供了改变游戏规则的灵活性和简单性。这一突破性创新克服了开发人员在构建应用程序时(无论是使用关系模型还是使用文档模型)所面临的历史挑战。有关 Oracle Database 23ai 正式发布及其关键功能的更多信息,请参阅 Oracle Database 23ai 相关公告。
JSON Relational Duality 提供的解决方案既具有关系表和 JSON 文档的优点,又无需权衡任一模型。
开发中使用关系模型和文档模型的限制
关系方法非常强大,但对于应用程序开发来说并不总是简单的
关系模型非常强大且高效,因为它使用数据规范化来确保数据完整性,同时避免数据重复。关系操作使建模和访问数据非常灵活,但在某些情况下,它对开发人员来说并不总是容易的:
-
开发人员通常根据应用层模型对象来构建应用程序,而关系数据库则将数据存储为表、行和列。构建单个应用层对象通常需要访问多个表。
-
为了解决这些困难,开发人员经常使用对象关系映射(ORM)框架。虽然 ORM 可以简化应用程序开发,但它们也带来了巨大的开销:它们通常需要多次数据库往返来操作单个应用程序层对象,它们效率低下,因为它们没有充分利用数据库引擎的功能,它们不能很好地管理并发控制,应用程序需要针对不同的语言使用不同的ORM框架。它们在必须插入或修改许多应用程序层对象的批处理或批量操作方面也非常糟糕。
-
应用层 ORM 框架还引入了跨模块及微服务时语义不同的可能性,除非它们都共享完全相同的映射信息。
因此关系模型是一种非常有效的数据存储格式,但在用作数据访问格式时有时会给开发人员带来挑战,而 ORM 会带来效率低下和其他的取舍。
JSON 文档数据库有其自身的缺点
文档数据库深受开发人员的欢迎,因为它们可以轻松检索和存储与应用层模型对象相对应的分层组织数据。JSON 文档模型允许应用程序将对象直接映射到分层 JSON 格式,从而避免对数据进行分解或重构,以及由此带来的相关复杂性。然而 JSON 文档模型作为存储格式远非理想,主要有以下几点:
-
文档经常需要存储重复的数据。例如不同的“订单”文档可能会冗余地存储相同的“客户”信息。数据重复会导致效率低下和潜在的不一致,因为共享信息(例如客户电话号码)的更新可能需要自动更新许多“订单”文档。
-
为了解决这个问题,一些文档数据库建议使用引用来规范化文档:“订单”文档可以只包含“客户”文档的 ID ,而不是将“客户”文档包含在“订单”文档中。然而规范化文档完全违背了文档模型的简单性,效果适得其反!
-
使用文档模型来建模多对多关系也非常困难。试图对关系进行建模会导致更多的数据重复和产生更多不一致的可能性。
因此Documents/JSON 是一种对开发人员友好的数据访问格式,使开发人员可以轻松上手,但作为数据存储格式具有很大的局限性,尤其是随着应用程序复杂性的增加。
Oracle Database 23ai JSON关系二元性如何彻底改变应用程序开发
Oracle Database 23ai JSON关系二元性将关系模型和文档模型的优势统一在单个数据库中,而无需进行前面讨论的任何权衡。Oracle Database 23ai 中启用此功能的新功能称为JSON 关系二元性视图(JSON Relational Duality)。
图 1:JSON 关系二元性:两全其美
使用JSON关系二元性视图,数据仍然以高效的规范化格式存储在关系表中,但应用程序以 JSON 文档的形式访问数据(图 2)。因此,开发人员可以考虑使用 JSON 文档进行数据访问,同时使用高效的关系模型进行数据存储,而无需牺牲简单性或效率。除此之外,JSON关系二元性视图还向用户隐藏了数据库级并发控制的所有复杂性,从而提供了文档级可串行性。
图 2:存储为行 - 作为 JSON文档访问
可以使用直观的GraphQL语法在任意数量的表上声明二元性视图。例如以下二元性视图以 order、orderitem和customer底层关系表中的数据构造与应用层订单对象相对应的 JSON 文档:
图 3:声明JSON关系二元性视图
开发人员可以轻松地在同一组关系表集上定义不同的二元性视图,从而轻松支持同一数据上的多个用例(例如OrderObj 和ShipmentObj 二元性视图可共享通用表orderitem 和customer)。使用二元性视图,开发人员现在拥有更大的灵活性:
-
使用 SQL JSON 扩展对所有数据进行 SQL 访问,包括 JSON 列中的数据;
-
使用二元性视图对所有数据进行 JSON 文档访问,包括对存储在关系表中的数据的访问。
开发人员可以使用他们常用的驱动程序、框架、工具和开发方法,以他们习惯的方式操作JSON关系二元性视图生成的 JSON 文档。
为开发人员提极致易用性和灵活性
可以通过单个数据库操作检索和存储单个应用程序层对象所需的所有数据,这种简单性使开发人员受益匪浅。使用二元性视图的应用程序现在可以简单地从视图中读取文档,进行所需的任何更改,然后写回文档,而无需担心底层关系结构。您可以使用常用的驱动程序、框架、工具和开发方法,以您习惯的方式操作由二元性视图实现的文档:
-
二元性视图消除了对 ORM 框架的需求。
-
以文档为中心的应用程序可以使用文档 API,例如 Oracle Database API for MongoDB 和 Oracle REST Data Services (ORDS),也可以使用 SQL/JSON 文档函数。
-
二元性视图的读取和写入可以使用熟悉的 HTTP 操作,例如 GET、PUT 和 POST。
-
更喜欢 API 而不是 HTTP 的应用程序可以使用 Oracle Database API for MongoDB。
-
针对二元性视图的应用程序操作可以在数据库内以合适的方式执行,因为它们可以在单个数据库访问中获取和存储应用程序层对象所涉及的所有行,这与ORM 生成的低效数据库访问代码形成鲜明对比。
因此JSON 关系二元性提供了关系模型的存储、一致性和效率优势,同时还提供了 JSON 文档模型的简单性和灵活性。
23ai实现无锁并发控制
JSON 关系二元性视图还受益于 Oracle Database 23ai 中新颖的无锁或乐观并发控制架构,该架构使开发人员能够跨越无状态操作管理数据一致性。
-
传统锁不适用于 REST GET 和 PUT 等无状态操作,因为锁是有状态的,不能在无状态调用之间保持。
-
Oracle Database 23ai 中新的无锁并发控制算法允许跨无状态操作进行一致更新。
-
无锁方案将实体标签(ETAG)概念从 HTTP 协议扩展到核心数据库,ETAG 是检索到的网页内容的哈希值或签名。
-
当对二元性视图执行 GET 时,返回的 JSON 文档还包含构建文档所用数据集的 ETAG。
-
当该文档被修改并随后将其 PUT 回数据库时,提供的 ETAG 将与原始数据当前的 ETAG 进行比较。如果 ETAG 不同,则目标数据在 GET 和 PUT 之间已经被修改,这次 PUT 操作将被拒绝。
-
然后应用程序可以重新获取文档及新的 ETAG,修改后重试PUT
-
如果 PUT 成功,我们可以保证对象没有发生任何中间更改,并确保文档级的原子性和一致性。
-
使用无锁并发控制的文档级可串行性使开发人员能够专注于他们的应用程序,而不是在应用程序层内实现并发控制并解决数据一致性问题。
总结:JSON 关系二元性简化了应用程序开发
-
开发人员现在可以获得 JSON 文档模型的灵活性和数据访问优势以及关系模型的存储效率和强大功能。
-
二元性视图是关系数据上完全可更新的 JSON 视图。应用程序可以简单地读取与应用程序层对象相对应的文档,进行必要的更改,然后将文档写回,而无需担心底层关系结构、类型映射或数据一致性。
-
可以基于一组关系表创建多个二元性视图,从而能够针对相同数据灵活开发多个应用程序用例。
-
使用二元性视图的应用程序操作可以在数据库内以合适的方式执行。
-
新的乐观并发控制算法允许高并发的更新与交互应用,同时提供强大的文档级可串行性。
您的后续步骤:免费尝试 JSON 关系二元性 与 Oracle Database 23ai
通过 Oracle Database 23ai 的几个免费使用途径,开发人员可以开始使用 Oracle Database 23ai 功能(例如 JSON 关系二元性)构建应用程序。我们让您轻松体验二元性视图在构建应用程序方面的强大功能和灵活性。我们在 GitHub 上提供详细且易于学习的教程。您可以下载教程并将其与您选择的免费 Oracle Database 23ai 一起使用。在教程中,开发人员可以使用 SQL、REST 和 Oracle Database API for MongoDB 来尝试二元性视图相关的特性、功能和示例。
文档来源:https://blogs.oracle.com/database/post/json-relational-duality-app-dev
编辑:殷海英