为啥 sql 数据库不允许为所有查询创建函数而不是在调用程序中构造 sql 字符串?

Posted

技术标签:

【中文标题】为啥 sql 数据库不允许为所有查询创建函数而不是在调用程序中构造 sql 字符串?【英文标题】:Why don't sql databases allow creating functions for all queries vs constructing the sql strings in the calling program?为什么 sql 数据库不允许为所有查询创建函数而不是在调用程序中构造 sql 字符串? 【发布时间】:2019-11-28 13:19:04 【问题描述】:

我是 sql 和 rdbms 的新手,我只是好奇为什么用于 python、node、c# 等语言的 sql 数据库驱动程序(例如 postgreSQL、mysql 等)需要您以编程方式使用该语言构造查询字符串,而不是而不是为所有查询调用数据库函数?在数据库中编写所有查询并从代码中调用这些函数不是更好的抽象级别吗?

为什么这样做(伪代码):

var query = "select * from " + table_name + ";"

当你可以做这样的事情时:

var rows = dbInstance.getAll(table_name, max_rows, start);

如果查询是在数据库本身中构建的,岂不是更简洁、性能更高?

【问题讨论】:

你不只是建议句法糖(实际上是句法棒)吗?您的有效建议是将成熟的查询语言 (SQL) 转换为参数化函数的 API。我看不到您在抽象方面获胜,特别是对于比涉及子查询、连接、聚合等的玩具示例更复杂的查询。此外,SQL 与关系代数密切相关,关系代数已经是一个定义明确的数学基础在相当高的抽象层次上。 @u84six 。 . . SQL 查询比这强大得多。 @collapsar 您不必用非 sql 语言构建真正复杂的查询字符串,然后从客户端代码调用它。然而,您可以在数据库中编写复杂的查询并将其标记为从调用程序中调用。 不缓存嵌入在存储函数中的查询的查询计划。每次运行函数时都必须重新评估它。所以,没有。 @u84six 老实说,去吧。经验是最好的老师。 【参考方案1】:

有许多库可以让您更加面向对象地使用数据库查询。例如:

jOOQ 适用于 Java 应用程序 SQLAlchemy 适用于 Python 应用 Doctrine 用于 php 应用程序 ActiveRecord 用于 Ruby 应用程序

这些通常称为 ORM 库。 ORM 表示对象-关系映射,因为关系数据库不是对象数据库,这些库必须获取数据行并将它们映射到应用程序中的对象集合上。反之亦然,当您保存对象时,它会将它们映射到数据行中。

这些 ORM 库使您的代码看起来更漂亮,并且对于某些任务,您可能能够更高效地编写代码,但 ORM 不会使查询在数据库中运行得更快。相反,像 Hibernate 这样的复杂 ORM 因将您的代码转换为低效的 SQL 而臭名昭著,并使查询的性能更差。

无论您如何调用它们,查询仍然在数据库服务器中运行。大部分时间都花在数据库中,而不是在您的应用中。

然而,ORM 包无法支持 SQL 的强大功能。 SQL 本身就是一门语言,它可以做一些在代码中很难表示的事情,就像你展示的那样,它只使用对象和函数。您展示的从单个表中获取所有行的所有列的示例适用于 ORM。 ORM 通常适用于处理单个表的各个行的简单 CRUD(创建、读取、更新、删除)代码,将它们映射到应用程序中的对象集合。

试图模拟更多种类的 SQL 查询的 ORM 包最终难以学习和使用。 Hibernate 的代码是 800,000 行 Java。

您可能还想阅读https://hackerfall.com/story/what-orms-have-taught-me-just-learn-sql

【讨论】:

我可以看到这一切现在是如何进行的。而且我刚刚环顾四周,发现有一些库可以帮助创建 sql 查询(基于字符串)而不是服从 ORM。 是的,有一些“帮助”库可用于更可靠地格式化有效 SQL。但是它们并不能 100% 支持 SQL 语法,而且它们很难用于复杂的 SQL。不过,它们很适合用于简单查询。 我也怀疑由于这种乏味的本质,现在人们倾向于不使用 sql 数据库,所以一切都是应用程序驱动的。 NoSQL 只能做相对简单的查询,并且没有关于如何组织数据库中的数据的指导。不可避免地,当您在 NoSQL 中存储数据时,您会以牺牲其他查询为代价来支持某些查询。旨在符合规范化规则的关系数据库支持最广泛的查询类型,并且不可能创建数据异常。 MongoDB 是一个支持更复杂查询的 NoSQL 数据库示例。阅读这个页面,看看你是否认为它比学习 SQL 更简单:docs.mongodb.com/manual/core/map-reduce

以上是关于为啥 sql 数据库不允许为所有查询创建函数而不是在调用程序中构造 sql 字符串?的主要内容,如果未能解决你的问题,请参考以下文章

SQL,数字辅助表

如果应该准备所有 SQL 查询以防止 SQL 注入,为啥语法允许非准备查询?

为啥我的表单创建一个新的模型对象而不是修改一个?

为啥 SQL Server 不允许我将 '21/04/17' 存储为日期?

为啥 SQL 服务器在我的表中插入 0 值而不是使用函数的正确值

SQL中的WHERE子句中为啥不允许应用聚集函数呢?请通俗的解释一下或者谈谈自己的见解!