0

相当理论的问题,但在长期发展中很重要:

场景A(一般情况):

  • 我在客户端建立我的查询,并将它们发送到服务器。(通过 PHP、Perl 等)
  • 优点:开发更快,因为查询字符串只在客户端构建,并且可以轻松修改(代码必须在客户端修改)。CRUD 可以很容易地开发为 OO(面向对象)。
  • 缺点:在更大和更相似的查询的情况下,我必须发送很长的查询字符串,并且在重复的情况下,我应该更好地准备它们以节省网络负载。(例如,执行大量 INSERT 语句的导入脚本/应用程序)。

场景 B:

  • 我创建了一些常用的过程来为我的表获取或创建数据,这些过程具有一些通用输入参数,并通过它们在服务器端构建查询字符串。
  • 优点:我用参数向服务器发送一个简短的查询字符串,网络负载低。
  • 缺点:开发肯定需要更长的时间,创建泛化查询的概念,客户必须了解程序及其版本。

意见?完全正确/错误,我总结了什么?有人有这方面的经验吗?

4

3 回答 3

2

恕我直言,使用存储过程的理由根本不是查询字符串的大小:即使是非常长的查询字符串也会产生可忽略的网络开销,而不是返回数据时的获取阶段。

这还不是关于查询的实际执行:我还没有看到一个受网络带宽约束的 mysql 服务器,而不是磁盘或 CPU。

存储过程给您的是更高级别的抽象:如果您有存储过程调用CreateFoo()and GetFooById(),您的应用程序不需要知道 afoo是如何存储在您的数据库中的(包括所有关系怪异的东西)。

这有利于维护,最重要的是它有利于健壮性:如果您不需要了解 a 中涉及的表结构foo,那么您的应用程序就没有机会搞砸它 - 例如忘记可连接等。

在本质上,这意味着您的数据库需要更少地信任您的应用程序。在许多情况下,应用程序从来没有直接操作表的权限——它们只能调用存储过程(例如银行)

也就是说,存储过程不是灵丹妙药。为工作使用正确的工具、常识和良好的睡眠似乎有很大帮助。

于 2013-04-27T22:52:43.893 回答
2

如果您正在开发一个应用程序,那么——在最终状态下——我认为应用程序中唯一的查询应该是类似select <list of columns> from view where <whatever>的,唯一的数据操作语句应该是对存储过程的调用,这些存储过程向应用程序返回适当的错误消息。

换句话说,您想为应用程序开发一个 API。SQL 提供了一个 API ( insert/ update/ delete),但我认为原始 SQL 不适用于大多数数据库应用程序。

在开发过程中,我更加灵活。可能需要在应用程序端放置复杂的查询来快速解决某些问题。它们应该只是迁移到数据库中。

为什么?主要原因是可维护性,并且在许多方面。通过将所有查询访问包装到视图中,您可以保护应用程序免受底层数据结构的更改。毕竟,事情在变化,用户需求在增长,有时数据模型必须反映这一点。

其次,DBA 可以在一个地方查看所有查询。这为数据库和查询的改进、整合、简化和优化开辟了空间。

将所有数据操作放入存储过程允许您在没有触发器的情况下实施业务规则。触发器可能非常棘手,尤其是当您开始在实现业务规则的多个表之间使用级联触发器时。这也允许应用程序端日志记录和更易理解的错误消息。

此外,使用视图和存储过程提供了相当自然的防止 SQL 注入的保护——不是完全,但很多。但在许多数据库中,您可以阻止用户直接修改表,同时通过存储过程授予他们修改权限。

于 2013-04-27T22:56:07.433 回答
0

您最初的假设中有两个主要错误。

  1. 事实上,每个 HTTP 请求都带有大量的 HTTP 标头,最多可达几千字节。因此,查询不会造成太大负担。与多个插入相同:一个小的“INSERT INTO t SET”对于文字对 field=value, field=value 来说只是微不足道的开销,无论哪种方式,你在 HTTP 请求中都有。
  2. 您是否考虑过这两种情况下的安全问题?

而且,JFYI:

我创建了一些常用的过程来为我的表获取或创建数据,这些表具有一些通用输入参数,并通过它们在服务器端构建查询字符串

这就是至少 99% 的 php/mysql 网络应用程序(坦率地说 - 网站)的工作方式。可能他们这样做是有原因的。

于 2013-04-28T06:32:22.467 回答