PostgreSQL 企业级商业应用

来自 PostgreSQL wiki
跳转到导航跳转到搜索

简介

关于 PostgreSQL 以及开源数据库的一个常见问题是它们是否适合要求苛刻、价值高昂的商业应用。虽然许多程序员都信任 PostgreSQL 用于简单的公告板、网站计数器和小型的订购系统,但并没有多少关于更复杂商业系统部署的公开描述,也没有针对想要构建此类系统的用户提供有用的设置指南。

在构建一些真正的企业级系统(400 多个网站,每月 60 万美元的货币交易量,以及 200 多个物理卫星位置每天与系统和数据交互)的过程中,我使用的是 PHP/Apache/PostgreSQL 组合,从中我学到了一些东西。其中一些适用于工作方法,一些适用于大型企业实践,还有一些只是为了调整系统以获得最高效率。

Ron Chmara (2002-01-29)

我的学习心得

  1. 将其视为任何其他会计程序。将用户输入的数据与系统记录的数据分开。使用单独的表,以及外部或内部(针对 PostgreSQL)逻辑来验证数据。如果您的正常业务逻辑和会计实践基于双重记账,也将其镜像。如果您的系统有仅限录入的表和每月记录锁定,您可能会发现将归档表用于存储现在锁定的数据是可取的。
  2. 使用事务。这将节省时间、金钱和麻烦。例如,对于大型循环插入,它会显著减少磁盘写入所需的时间,如果您的程序发生故障,或者需要中止数据输入,您不会留下半输入的数据表。
  3. 调整和优化您的代码,以便在一个 pg_exec() 语句中尽可能多地执行操作。应尽可能避免使用多个语句。(让数据库引擎而不是 PHP 来完成这项工作)。这允许更快的数据库交互,保持数据库通信(和 Apache CPU 时间)的开销很低。由于应用程序和表通常是分段构建的,因此重新审视较旧的代码(可能包含超过 15 个数据库交互)并将其减少到一两个语句是一个好主意。
  4. 提前确定数字精度(小数位数)并为此编码。始终。不遗余力。不同的公司和行业有不同的要求,但通过在代码生命周期的早期设定此规则集,可以避免在代码生命周期的后期遇到难以处理的精度和舍入问题。
  5. 根据需要频繁地执行 pgdump,并将其复制到安全的服务器上。这不是因为它会宕机(我有一个熟悉另一个开源数据库 (*咳嗽*) 的程序员问我数据库是否宕机,他困惑了一阵子……因为 PostgreSQL *从未* 宕机),而是因为您始终希望能够在给定断点隔离数据库。虽然您也可以对仅限录入的数据库系统(其中更新实际上是记录的“后期”版本)执行相同操作,但它没有相同的级别……我是否提到了要有备份服务器?无论应用程序有多好,闪电都会损坏最好的应用程序。系统越关键,您就越需要离线或多站点备份数据库(和 Web)服务器。
  6. 您可能需要重新编译或调整内核以获得更大的共享内存 (shm) 和/或信号量 (sem) 空间。否则,当 PostgreSQL 需要它们时,您会因为后端而耗尽内存。例如,RedHat 6.2 上的默认值只允许 32 个。pg_pconnect php 函数每个 Apache 进程每个连接都需要一个后端,这意味着对于 50 个 Apache 进程到一个数据库,您需要 50 个 postmaster 后端。如果您正在运行十个数据库,并且有 20 个活动的 Apache 进程,那么您将需要 200 个后端。解决此问题的一种方法是将 httpd.conf 中的 'MaxRequest' 计数器设置得很低,以便循环使用池,这会频繁关闭 Apache 进程(确保您利用持久连接获得一些速度,但连接会在一定时间后关闭)。另一种解决方案是只连接到一个数据库(其中包含所有表),以减少所需的后端数量。另见:https://postgresql.ac.cn/docs/current/interactive/kernel-resources.html
  7. 调查 AOLserver 作为连接池功能的替代方案(它解决了上述问题)。
  8. 如果您正在移植旧的 PHP 代码,请获取最新的 CVS 副本或 >= 4.0.7 版本,它应该在 PG 函数中具有行抓取选项,这使得生活变得容易得多。它没有完全记录(截至 2001 年 6 月 30 日),但它的工作方式与 php mysql 函数一样。pg_close 函数也起作用,这有助于管理 Apache 的连接池问题。
  9. 关于 oid/currval/nextval 的说明:如果您使用的是最新版本的 pg,请忽略旧文档。当这些函数的行为方式不同时,已经写了许多网站和书籍。仍然适用的一件事是,使用 currval 和 nextval 无法保证完美的序列化(如果某些交互中止、停止或未被使用,可能存在空洞)。如果您需要完美的序列化,您可以执行插入操作并根据 oid 检索记录序列号,或者如上所述,使用一个录入表(预期存在序列空洞),然后线性地将其馈送到另一个表(没有空洞)。
  10. 如果您以前从未做过会计应用程序,请雇佣一名会计师/程序员。他们的服务可能很昂贵,直到您学会了诀窍,但之后,这些知识将是无价的。即使让一名非编码会计师“合作者”来查看代码图表和结果,也有助于确保产品更稳定、更面向业务规则。根据所需的会计逻辑级别,拥有 GAAP(公认会计准则)标准手册也可能会有所帮助。
  11. 我是否提到了备份?即使在 PG 内部也是如此?设置仅限开发的表或仅限开发的机器,以便您的构建和测试以独立于实时数据的方式进行。在实时服务器上将数百万个客户订单更新为 $0.00 不是您想体验的事情。随着代码复杂性的增加,您可能希望拥有两台测试服务器,一台用于代码开发,另一台用于版本(Apache、PHP、PostgreSQL 等)测试。这样,您就可以在正在进行的开发环境之外测试应用程序软件的新版本。
  12. 注意二进制数学。许多系统和函数调用默认情况下使用它,因此相应地进行补偿(和/或转换)。一种方法是只使用整数数学,然后向后工作到您的十进制位,另一种方法是在更高的精度(8 个小数位)下工作并将数据返回到更低的、所需精度(4 个小数位)。
  13. 注意不良数据。在任何情况下,切勿、绝不、决不向 Web 服务器用户授予过多的权限……或者更糟糕的是,将 SQL 语句放在 GET 中。过滤所有输入数据的大小、字符串类型、预期用户等。过滤、过滤、再过滤。然后再次过滤。与使用 PHP 或其他基于 Web 的数据系统的编程相关的多数安全警告来自数据在使用前没有得到适当验证的问题。
  14. 将小数据字段强制为过滤的一部分。虽然将所有字段设为 TEXT 很诱人,但从长远来看它会创建巨大的数据库行,并且会减慢整个系统的速度。它还在不良(超大)数据可能无意中输入并使用的情况下强制执行另一层过滤。
  15. 对每条记录进行时间戳。当您需要查找精确范围(例如,星期二完成的所有操作,因为您的代码有问题,或者星期二的导出有问题……)时,这会真正节省您的时间。我发现对创建日期和修改日期进行时间戳很有用。如果您使用某种形式的内部用户授权(例如 mod_ldap),用创建者的 uid 和修改者的 uid 对记录进行时间戳也是很有价值的。
  16. 对于某些系统,您永远不应该使用“更新”,只需插入一个反向记录。(参见技巧 #1 和 #11。)这允许您维护所有事务的详细记录,防止历史数据的丢失。这完全取决于所需的会计实践以及需要保存多少数据。例如,您不会将购买金额归零或删除发票号,而是会为其他记录插入一个负购买。
  17. 经常执行 vacuum 操作。每天,或者根据需要更频繁地执行。在进行大量记录更改后,VACUUM 和 VACUUM ANALYZE 可以将性能提高 1000% 或更高。

希望这能有所帮助。