统一编程和数据库查询


11

考虑一下面向对象的编程语言(如C ++或Java)的通用教程:创建一个简单的订单处理系统,其中的对象代表帐户,订单,项目等(或多或少的等效对象)。完全具有直觉意义,但餐桌上的大象认为它不是真实的,因为它们是内存中的对象。在实际系统中,帐目,订单等实际上并没有真正存在于内存中,而是存在于数据库中,而内存表示只是它们的短暂镜像。

您可以自己编写很多代码来读取和写入数据库,但这是如此乏味且容易出错,实际上没有人这样做。

每个人最终都使用ORM,但是它们本身就存在问题,以至于著名的论文称它们为“我们行业的越南”。

我认为这不是对象和关系之间的不匹配,而是编程语言和数据库之间不匹配,因为它们是彼此不了解的独立事物。猜想:解决方案是使用一种既是编程语言又是数据库查询语言的语言,这又将要求语言运行时也是数据库,而JIT编译器也必须是查询优化器。

这就是我所看到的问题的摘要。我的问题是,有没有人,

  1. 实际上建立了这样一个统一的系统

  2. 尝试过但未能建立这样的统一系统

  3. 关于如何构建这样的主题,或者为什么或为什么不这样做,写了很多实质性的文章

  4. 提出解决问题的替代方法?


5
一旦有了一种统一数据库和代码的语言,接下来您需要发明一种统一数据库,代码和HTML的语言。然后,您需要与JSON统一。然后,您需要以比perl更亲密的方式与regexp统一。然后,您需要与LDAP之类的分层数据库统一(例如,Microsoft Active Directory,是的,这是一个数据库)。然后,您需要与键值数据库(例如Mongo或Cassandra)统一。然后,您需要与3D渲染等结合起来。等等。您似乎在
索要

1
似乎您提出的解决方案应用程序将无法访问远程数据库,或者我是否误解了您?因为应用程序和数据库都使用运行时的相同实例。
停止伤害Monica's

2
这与技术无关,而与数据集有关。我曾经不得不优化一段代码,因为正则表达式需要3分钟才能执行。原来,人们在回复电子邮件时会引用整条消息,并且电子邮件有时可能会增长到5mb。regex可能仅阻塞5mb。因此,SQL足够快。我们需要优化正则表达式
slebetman

2
还值得指出的是,即使在RDBMS中,“优化”的含义也有所不同,具体取决于应用程序的目标。你索引什么?什么时候?怎么样?您在索引中包括哪些字段?您是针对高写入速度或高查询速度进行优化还是使事务完整性最大化?贸易空间不会通过使其成为本地语言的一部分而改变,如果有的话,它将变得更加复杂,并使开发人员比他/她现在所需要的对持久层的了解更多(假设您有一个团队而没有只是一个人)
保罗

1
我想提的LINQ这里至少是涉及到1
卡西Kuball

Answers:


7

这是我的意见。虽然我确实知道您来自哪里,但从设计的角度来看却无法实现。

数据持久性是极其复杂的主题。编程语言也是如此。将两者结合将导致复杂性爆炸。要真正使两者都足够好,使人们真正想要使用它,将需要大量的努力。我认为已经提到的MUMPS是一个很好的例子。或者,您可以查看各种SQL变体,这些变体在其之上附加了完整的语言。它们可能有用,但我认为人们不会愿意使用它们。

因此,将它们分开是解决该复杂性的明确方法。同样,通过不将它们捆绑在一起,它可以随时间变化和发展。例如,SQL很老,自创建以来并没有太大变化。但是在同一时期,用于运行应用程序的语言发生了巨大变化。而现在,情况正相反。在更改和发展数据库时,语言基本保持不变。

运行时部署是另一个问题。将两者结合起来将意味着数据库和应用程序或Web服务器都必须在同一进程中运行。从维护的角度以及从在单独的计算机上或以多对一关系运行它们的能力来看,这都是极其有限的。

将二者分成清晰的API分成单独的模块是降低复杂性的最佳方法,它使您可以灵活选择要使用的技术以及最终产品的部署方式。


TL; DR“这不是一个好主意,因为统一它们违反了关注点分离”
值得

5

看来您正在做一些主要假设。例如,您假设每个人都在写关系数据库。事实并非如此,有许多其他风格的数据库示例(对象数据库,文档数据库等)使用本机编程语言编写所有代码并管理持久性。

例如,Db4O与Java和C#,Java中的ObjectDB,多种语言的VelocityDB兼容。MongoDB的驱动程序最终都需要您用本机编程语言编写内容(如果您使用JavaScript,则要加分,因为这也意味着Shell也使用相同的语法),依此类推。

在各个地方都有很多讨论,其中讨论哪种DB引擎在哪种情况下更好,以及为什么对此答案的范围太大而无法在此站点中包含一个封闭的问题。结果是它们分别针对不同的事物进行了优化,直到最近,SQL仍被认为是业务应用程序的“最低公分母”,因为在ACID和性能方面您可以免费获得很多(尽管两者都在变化)最近随着架构和需求的变化而变化)。

还值得注意的是,以前实际上已经有很多“全合一”的方法。大型机语言通常内置有自己的持久性逻辑,并且像Smalltalk这样的语言根本无法区分代码和数据。同样,它们通常对某些用例有用,但并非对所有用例都有利。


5
  1. 是的(不是我)。它被称为MUMPS

  2. 根据这个以前的SE.SE问题本文,MUMP的设计不是很好。但是确实在医疗行业中使用过(我想仍然存在使用它的现有系统),所以并不是完全失败。

  3. 现在,您肯定会找到有关此信息的信息,从而知道要搜索的内容。从上面的Wikipedia链接开始。

  4. 搜索面向对象的数据库,其中许多是特定于语言的。他们试图以比ORM更简单的方式解决对象关系不匹配问题。


8
以腮腺炎方式访问数据库.... SK = 0 FSK = $ O(^ VA(200,K))Q:'KW $ P(^ VA(200,K,0),U,1),! 从众所周知的腮腺炎系统打印患者姓名。问题解决了?没那么多。
joshp

我有一位同事对MUMPS发誓。它的更高版本(Cache)具有更易于理解的语法。
阿列克谢

2
@Alexey:我对MUMP不太了解,但是似乎比语法更大的问题是易于出错的作用域规则,这使大型程序的开发和维护成为噩梦。
布朗

@DocBrown那里正好有它。作用域规则有点像汇编语言。通常,腮腺炎的书写方式存在很多问题,以至于分散了OP的注意力。
joshp

5

实际上,有多个系统将数据库和编程语言统一到一个环境中。

Smalltalk可能是最接近您所描述的内容。内存中的对象保留在“图像”中,因此可以直接使用语言环境和(对象)数据库。而且,大多数现代语言都具有某种内置的持久性机制,这意味着可以使用语言本身对语言环境中的对象进行持久化和查询。

这对于单用户应用程序非常方便。但是该方法无法扩展到多个用户,因为他们将需要共享相同的内存空间,这显然限制了用户数量。可伸缩的解决方案需要单独的数据库服务器来管理并发性。即使这样,还是有多个NoSql数据库与特定的语言环境集成在一起,并允许您持久存储和查询语言本身中的对象。

从关系的角度来看,我们有T-SQL之类的语言,它是一种成熟的编程语言,是SQL的超集,因此查询和DML可以与任意复杂的过程逻辑混合在一起。已经使用T-SQL构建了复杂的业务应用程序,因此这当然是可行的,但是当前的趋势是将业务逻辑从数据库中移开

在这些情况下,将数据库与编程语言集成在一起并避免“阻抗不匹配”确实非常优雅和方便。那么,为什么人们仍然使用与编程环境不同的关系数据库,并尝试与一些ORM-kludge建立桥梁?

事实证明,将数据和查询与任何特定的编程语言和环境分开具有许多优点。

  • 数据独立性。在大多数组织中,数据实际上是由多个应用程序访问的。商店可能有一个数据库,供Web前端,客户支持工具,报告引擎等使用。数据本身通常是长期存在的,而应用程序时有发生。将数据耦合到一个特定的编程环境将锁定到一个特定的编程环境。但是编程语言来来往往,而数据却永远存在。
  • 临时查询。能够打开数据库提示并编写查询非常方便。如果查询与编程环境紧密耦合,那么这将是一项编程任务,只有开发人员才能执行。
  • 避免锁定。由于SQL是标准,因此多个供应商可以提供或多或少可互换的数据库管理系统。这避免了供应商的锁定,并使比较产品变得更加容易。
  • 松耦合。在应用程序层和数据库之间具有明确定义的接口,可以独立于应用程序逻辑来调整和优化数据库。
  • 共享接口。由于数据库接口独立于应用程序逻辑,因此可以使用现成的工具进行概要分析,复制,分析等。

2

我在脑子里处理了很多次,这是一个很好的问题。解决问题的现有解决方案的一个示例是图形数据库ArangoDB,其中您使用JavaScript(在内部引擎上运行)编写可以生成整个网页的控制器。数据使用JSON传递到存储,或从JSON传递到存储,因此可以在JavaScript中本地访问,并且查询以嵌入式查询语言完成。因此,本例是扩展JavaScript以在数据库中运行的示例。

实际上,出于安全原因,不应将此类控制器公开,因为数据库配置中的缺陷或错误将导致您的宝贵数据公开。

我个人认为这是一个好方法,并考虑数据库是否支持一种映射/归约功能,该功能将实时更新聚合的数据/文本索引和其他经常查询的数据,从而在两者之间添加了薄安全层(称为负载)平衡器)将使功能正常的应用程序在分布式数据库中运行。


1
  1. 实际上建立了这样一个统一的系统

是的,我在Sciter做到了

Sciter的脚本是具有内置持久性的“ JavaScript ++ ”:

var ndb = Storage.open(pathname);
ndb.root = { ... root object ... };

ndb.root用JS表示普通对象在哪里。它的所有属性和可从中访问的子对象都是可持久存储的-在需要时存储和提取到数据库中-对于代码是透明的:

ndb.root.accounts[2].firstName = "John";
var name = ndb.root.accounts[3].firstName;

数据会在GC周期,内存不足或显式ndb.commit()调用时存储在DB中。

Storage是伴随着Index阶级 -具有独特的/非唯一键可持久有序的对象集合。

功能集类似于MongoDB或其他NoSQL数据库,但id不需要单独的ORM-数据库访问完全是通过脚本方式进行的。


0

我绝对是这样,我也不知道从哪里开始。SQL可能很出色,我想在您的通用编程语言中拥有所有这些功能和事务保证会很棒(而不是必须将查询写为字符串集合或使用ORM禁止)。

接近你的想法,我知道被称为aquameta唯一的系统(口号:“建于PostgreSQL的web开发堆栈”;见https://github.com/aquametalabs/aquametahttp://aquameta.org)。有一些介绍性视频,其创意不亚于想法本身(youtube.com/watch?v=jz74upW7TN0、youtube.com/watch?v=cWGm9eYUYUk&t=29s、youtube.com/watch?v=xRoUQGUmiMg),当我说疯了时,我的意思是说他们在Postgres中实现了自己的编辑器和版本控制系统。


0

我认为这正是微软发明LINQ的理由。它已经在大规模生产中使用了几年,因此很容易找到有关它的文献以及来自现实世界的正面和负面经验的反思。(大多数.net开发商店都接受它。)

LINQ的一个很好的起点:https : //docs.microsoft.com/en-us/dotnet/csharp/linq/



Linq-to-SQL是ORM的组件,而这并不是OP所要求的。
JacquesB

我没有说linq-to-sql。我只是在谈论linq本身,后者是编程语言中内置的,与它背后的数据存储区无关,而这正是OP所要求的。
克莱·福勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.