数据库逻辑VS应用逻辑


Database Logic VS Application Logic

很抱歉,如果这是一个愚蠢的问题。我已经有一段时间不玩这个游戏了。

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

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

使用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$

我更喜欢把它放在数据库中,原因如下:

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

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

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

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

这就是说,有几个陷阱要注意:

  1. 存储进程是最容易维护的,当它们是一个单一的大查询和一些次要的支持逻辑。

  2. 小心锁

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

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

我说的大部分是作为成千上万行PostgreSQL存储过程(主要是sql和pl/pgsql)的作者。存储过程在管理方面存在一些挑战,但是一旦您驾驭了它们,那么这些努力是值得的。

我通常更愿意在应用程序中使用这种功能,原因如下:

  1. 服务器负载你的数据库服务器将经常处于高负载下,无论如何,应用程序服务器通常较少。
  2. Technology它使你的实现数据库不可知,所以如果你以后决定迁移到MySQL或Oracle,你不会失去功能或不得不重新设计它们。
  3. 可维护性如果你的代码抽象到数据库中,除了你之外,其他人必须维护它,那么你的代码将不那么直观。他们会花时间寻找不存在的功能。
你的主要考虑可能与我的不同。我希望在数据库中完成这一切会有一些性能提升,所以这可能是一个因素,但我总是尽量保持我的实现与技术无关。