(将我的答案从Using in-memory PostgreSQL 中移出并对其进行概括):
你不能在进程中运行 Pg,在内存中
我不知道如何运行内存中的 Postgres 数据库进行测试。可能吗?
不,这是不可能的。PostgreSQL 用 C 实现并编译为平台代码。与 H2 或 Derby 不同,您不能只加载jar
并启动它作为一次性内存数据库。
与同样用 C 编写并编译为平台代码的 SQLite 不同,PostgreSQL 也不能在进程内加载。它需要多个进程(每个连接一个),因为它是多处理架构,而不是多线程架构。多处理要求意味着您必须将 postmaster 作为独立进程启动。
而是:预配置连接
我建议简单地编写测试以期望特定的主机名/用户名/密码可以工作,并让测试工具CREATE DATABASE
成为一次性数据库,然后DROP DATABASE
在运行结束时。从属性文件、构建目标属性、环境变量等获取数据库连接详细信息。
只要您提供给单元测试的用户不是超级用户,而是拥有CREATEDB
权限的用户,就可以安全地使用您已经拥有您关心的数据库的现有 PostgreSQL 实例。在最坏的情况下,您会在其他数据库中产生性能问题。出于这个原因,我更喜欢运行一个完全隔离的 PostgreSQL 安装来进行测试。
而是:启动一次性 PostgreSQL 实例进行测试
或者,如果您真的很热衷,您可以让您的测试工具找到initdb
和postgres
二进制文件,运行initdb
以创建数据库,修改pg_hba.conf
为trust
,运行postgres
以在随机端口上启动它,创建用户,创建数据库,然后运行测试。您甚至可以将多个架构的 PostgreSQL 二进制文件捆绑在一个 jar 中,并在运行测试之前将当前架构的二进制文件解压缩到一个临时目录。
我个人认为这是一个应该避免的主要痛苦。配置测试数据库要容易得多。但是,随着对;的include_dir
支持的出现,它变得更容易了。postgresql.conf
现在您可以只追加一行,然后为所有其余部分编写生成的配置文件。
使用 PostgreSQL 进行更快的测试
有关如何安全地提高 PostgreSQL 性能以进行测试的更多信息,请参阅我之前在此主题上写的详细答案:优化 PostgreSQL 以进行快速测试
H2 的 PostgreSQL 方言不是真正的替代品
有些人转而使用 PostgreSQL 方言模式下的 H2 数据库来运行测试。我认为这几乎与使用 SQLite 进行测试和使用 PostgreSQL 进行生产部署的 Rails 人员一样糟糕。
H2 支持一些 PostgreSQL 扩展并模拟 PostgreSQL 方言。然而,它只是 - 一个仿真。您会发现 H2 接受查询但 PostgreSQL 不接受查询的区域、行为不同的区域等。在撰写本文时,您还会发现 PostgreSQL 支持做一些 H2 不能做的事情的很多地方——比如窗口函数。
如果您了解这种方法的局限性并且您的数据库访问很简单,那么 H2 可能就可以了。但是在这种情况下,您可能更适合使用抽象数据库的 ORM,因为您无论如何都不会使用它的有趣功能 - 在这种情况下,您不必再关心数据库的兼容性。
表空间不是答案!
不要使用表空间来创建“内存”数据库。它不仅没有必要,因为它无论如何都不会显着提高性能,而且它也是一种很好的方式来中断对同一 PostgreSQL 安装中您可能关心的任何其他内容的访问。9.4 文档现在包含以下警告:
警告
即使位于主 PostgreSQL 数据目录之外,表空间也是数据库集群的一个组成部分,不能被视为数据文件的自治集合。它们依赖于主数据目录中包含的元数据,因此不能附加到不同的数据库集群或单独备份。同样,如果您丢失了表空间(文件删除、磁盘故障等),数据库集群可能会变得不可读或无法启动。将表空间放置在像 ramdisk 这样的临时文件系统上会危及整个集群的可靠性。
因为我注意到有太多人这样做并遇到了麻烦。
(如果你已经这样做了,你可以mkdir
丢失表空间目录来让 PostgreSQL 重新启动,然后DROP
是丢失的数据库、表等。最好不要这样做。)