2

对不起,如果这是一个愚蠢的问题。我已经有一段时间没玩了。

我正在决定是否将 PostgresSQL 用于 Web 应用程序。我以前从未使用过它。完成研究后,我真的很喜欢它用于存储函数的 PGSQL 语言。

通常在我的网络应用程序代码中,我会保存一条记录。这包括检查记录是否已经存在 - 如果存在则更新它,否则插入新记录。

使用 PGSQL - 我可以在一个查询中完成所有这些操作(而不是 Mysql,我很确定你不能)

他们对此有优势吗?或者这个逻辑是否应该保留在 web 应用层而不是数据库上的存储函数中。

这是 PGSQL 中的一个粗略示例。它只是说明性的,并不意味着是安全或好的代码。

CREATE OR REPLACE FUNCTION save_client(IN strforename character varying, IN strnew character varying)
  RETURNS TABLE(forename character varying, surname character varying) AS
$BODY$

    DECLARE myrec int;

    BEGIN   

        SELECT idx_clients INTO myrec from "Clients" WHERE LOWER("Clients".forename)=$1;


        IF NOT FOUND THEN
            RAISE NOTICE 'No results found.%',myrec;

            INSERT INTO "Clients" (forename,surname) VALUES (strnew,strforename);
        ELSE
            RAISE NOTICE 'YES results found.%',myrec;

            IF myrec NOTNULL THEN
                UPDATE "Clients" SET forename=$2 WHERE idx_clients=myrec;
            END IF;

        END IF;

    END;

$BODY$
4

2 回答 2

3

我更喜欢将其放入数据库中,原因如下:

  1. 它允许您将数据库封装在 API 后面。您甚至可以使您的 API 可被发现(参见http://ledgersmbdev.blogspot.com上的许多帖子以了解一种方法),以便应用程序可以在合理的范围内在运行时发现调用语法。再次封装有助于确保多个应用程序可以安全地访问同一个数据库,因为 rdbms 最终会成为具有明确定义的 API 的服务器。

  2. 它本质上确保了一种依赖倒置,您可以使用它来创建更稳定的接口。

  3. 它允许您在大多数情况下将 SQL 排除在应用程序文件之外(因为调用接口本身可以抽象为单个 API)。

  4. 更好地控制事务逻辑和性能(但见下文)

话虽如此,有几个陷阱需要注意:

  1. 存储过程是最易于维护的,它们是带有一些次要支持逻辑的单个大型查询。

  2. 小心锁

  3. 不要混合事务和非事务逻辑。事务逻辑属于数据库。任何非事务性的东西都属于它之外。例如,不要从存储过程发送电子邮件。不要暂停数据库事务以尝试与用户建立网络连接,询问他或她是否要继续。不要将这些直接从存储过程中挂钩到具有实际影响的脚本中......

  4. 小心合同。人们在存储过程开发中遇到的大问题之一与模式更改有关。您添加了一个需要收集的附加列,而不是两个您的代码更改的地方,您至少有三个。这是我非常强调可发现性的原因之一,因为这使您可以构建更灵活的合约并仅在需要更改的地方更改代码。换句话说,事情可以优雅地失败。

我说这大部分是作为数万行 PostgreSQL 存储过程的作者,主要是在 sql 和 pl/pgsql 中。存储过程会带来管理挑战,但是一旦你驯服了它们,它们就值得付出努力。

于 2013-04-19T12:25:09.027 回答
0

我通常宁愿在应用程序中拥有这种功能,原因如下:

  1. 服务器负载 无论如何,您的数据库服务器通常会承受很大的负载,而应用程序服务器的负载通常较少。
  2. 技术它使您的实现数据库不可知,因此如果您以后决定迁移到 MySQL 或 Oracle,您不会丢失这些功能或必须重新设计它们。
  3. 可维护性将您的代码抽象到数据库中将不那么直观,如果其他人必须在您之外维护它。他们会花时间寻找不存在的功能。

您的主要考虑可能与我的不同。我希望在数据库中完成这一切会带来一些性能提升,所以这可能会影响它,但我总是尽量让我的实现与技术无关。

于 2013-04-19T09:42:40.740 回答