分享到

简介

连接到数据库服务器通常是设计和配置数据库驱动的应用程序时需要完成的首要任务之一。虽然有很多方法可以为应用程序提供地址、监听端口、凭据和其他详细信息,但连接 URI(有时称为连接字符串或连接 URL)是以紧凑格式指定复杂配置的最强大和灵活的方式之一。

在本指南中,我们将讨论如何使用你的 PostgreSQL 数据库信息和身份验证详细信息格式化连接 URI。连接 URI 分为几个部分,因此我们将逐一介绍每个部分。

百分比编码值

在我们开始之前,我们应该说明 PostgreSQL 连接 URI 期望百分比编码值。这意味着 URL 中具有特殊含义的任何字符都必须转换为其百分比编码的对应项,以确保库和应用程序可以正确解释它们。

你应该进行百分比编码的字符包括

  • (空格):%20
  • %: %25
  • &: %26
  • /%2F
  • :%3A
  • =%3D
  • ?%3F
  • @: %40
  • [%5B
  • ]%5D

这些在连接 URI 中具有特殊含义。

所以如果你的密码是...

pe@ce&lo\/3

...你将希望在连接 URI 中将其指定为

pe%40ce%26lo\%2F3

如果你不确定字符是否应该进行百分比编码,通常最好还是进行编码。例如,如果你不确定 \ 字符是否是保留字符,你可以使用其百分比编码的等效项 %5C 以确保安全

pe%40ce%26lo%5C%2F3

在构建连接 URI 时请记住这一点。

快速概览

在深入细节之前,我们可以查看 PostgreSQL 连接 URI 的规范

postgres[ql]://[username[:password]@][host[:port],]/database[?parameter_list]
\_____________/\____________________/\____________/\_______/\_______________/
| | | | |
|- schema |- userspec | | |- parameter list
| |
| |- database name
|
|- hostspec

方括号中的部分表示可选部分。你可能已经注意到 URI 的大部分部分是可选的。同样显而易见的是,你可以在 URI 中编码许多信息。

每个单独组件的快速描述

  • postgres[ql]:模式标识符。可以是 postgresql 或简单的 postgres
  • userspec:URI 的可选组件,可用于指定要连接的用户名和密码。
    • username:可选的用户名。如果包含,它应该在第二个斜杠 (/) 之后开始,并持续到冒号 (:)(如果也提供了密码)或直到 at 符号 (@)(如果未提供密码)。
    • password:可选的密码。如果包含,它在冒号 (:) 之后开始,并持续到 at 符号 (@)。
  • hostspec:一个可选组件,用于指定要连接的主机名和端口。
    • host:要连接的服务器的可选 IP 地址、DNS 名称或本地可解析名称。主机持续到冒号 (:)(如果包含端口)或直到斜杠(如果未包含端口)
    • port:可选的端口规范,用于指示 PostgreSQL 在服务器上监听的端口。端口以冒号 (:) 开头,并持续到斜杠 (/)
  • database name:要连接的单个数据库的名称。
  • parameter list:可选的其他参数列表,可以影响连接行为。参数列表以问号 (?) 开头。
    • parameter pairs:参数列表由键值对组成。每对中的键和值用等号 (=) 分隔,每对之间用 & 符号 (&) 分隔。

这是一个包含所有这些组件的 PostgreSQL 连接 URI 的示例

postgresql://sally:sallyspassword@dbserver.example:5555/userdata?connect_timeout=10&sslmode=require&target_session_attrs=primary
^ ^ ^ ^ ^ ^ ^
|- schema | |- password |- host | | |- parameter list
| | |
|- username | |- database
|
|- port

指定 URI 类型

连接 URI 中的第一个项目通常是协议规范或应用程序类型。由于 URI 将用于连接和验证到 PostgreSQL 数据库,我们需要使用一个标志符来向我们正在使用的应用程序和库表明这一点。

PostgreSQL 项目同时接受 postgresql://postgres:// 作为有效的 URI 模式指示符。因此,你应该使用这两个字符串之一开始你的连接 URI

postgresql://
postgres://

模式指示符将确保随后提供的信息在正确的上下文中进行解释。

指定用户名和密码

URI 的下一部分是用户凭据。这在规范中称为 userspecuserspec 在技术上是可选的,但如果你不想依赖应用程序或数据库配置的默认值,则通常是必需的。

如果包含 userspec,则它在冒号和双正斜杠 (://) 之后开始,并以 at 符号 (@) 结束。

要仅指定用户名,你可以将其放在这两个符号之间

postgresql://username@

要指定用户名密码,请先提供用户名,后跟冒号 (:),然后是密码和 at 符号

postgresql://username:password@

应用程序能够通过注意包含终止 at 符号 (@) 来将此数据解释为 userspec。如果仅提供一个字段(如果在斜杠和 at 符号之间不存在冒号),则将其解释为用户名。

指定服务器监听位置

userspec 之后是 hostspec,它定义了服务器的监听位置。hostspec 再次是可选的,但如果你不依赖客户端或库中设置的默认值,则几乎总是有用的。

hostspechost 和可选的 port 组成。host 可以是本地可解析的主机名、由外部名称系统(如 DNS)解析的名称,或者 IP 地址或其他直接地址。端口表示 PostgreSQL 正在监听的端口号。

要指定应用程序应尝试连接到本地计算机上的默认 PostgreSQL 端口 (5432),你可以使用

postgresql://localhost

如果你需要包含用户名和密码,则该信息将首先出现,并用 at 符号分隔

postgresql://username:password@localhost

要指定在非标准端口上运行的远程服务器,请用冒号分隔这些详细信息。例如,要连接到主机 198.51.100.22 上端口 3333,你可以使用

postgresql://username:password@198.51.100.22:3333

你实际上可以提供多个主机和端口对,用逗号 (,) 分隔,以告知应用程序如果第一个服务器无法访问,则尝试后面的服务器。例如,要扩展前面的示例以包含在 198.51.100.33 上端口 5555 监听的备用服务器,你可以使用

postgresql://username:password@198.51.100.22:3333,198.51.100.33:5555

符合规范的客户端和应用程序将尝试首先连接到在 198.51.100.22:3333 监听的服务器。如果失败,它们将尝试访问在 198.51.100.33:5555 监听的 PostgreSQL 数据库。

提供数据库名称

hostspec 之后,下一部分数据是数据库名称。虽然并非所有数据库管理系统都是如此,但在 PostgreSQL 中,建立连接时必须连接到特定的数据库。

数据库名称以正斜杠 (/) 开头,并持续到行尾或问号 (?)。如果你不依赖默认值,则必须包含数据库名称。

要连接到托管在 198.51.100.22:3333 上监听的 PostgreSQL 服务器上的名为 sales 的数据库,你可以输入

postgresql://username:password@198.51.100.22:3333/sales

指定其他参数

连接 URI 的最后一部分用于为连接提供其他参数。参数列表由前导问号 (?) 引入,并持续到行尾。

列出的每个参数都定义为用等号 (=) 连接的键值对。在第一个参数对之后,每个附加的键值对都用 & 符号 (&) 分隔。

例如,要指定客户端应为我们先前定义的连接应用 10 秒超时,你可以使用

postgresql://username:password@198.51.100.22:3333/sales?connect_timeout=10

如果你想提供其他参数,你可以在之后添加它们,并在每对之间使用 & 符号 (&)。例如,我们还可以另外指定我们需要 SSL,并且只想在服务器是副本集中的主服务器时连接,我们可以另外添加

postgresql://username:password@198.51.100.22:3333/sales?connect_timeout=10&sslmode=require&target_session_attrs=primary

PostgreSQL 文档有一个完整的参数列表,你可以阅读以了解更多信息。

结论

在本指南中,我们讨论了什么是 PostgreSQL 连接 URI,如何解释各种组件,以及如何在给定一组连接信息的情况下构建你自己的 URI。连接 URI 将连接到给定数据库所需的所有信息编码在一个字符串中。由于这种灵活性以及它们的广泛采用,了解如何解析和构建这些字符串可能非常有用。

关于作者
Justin Ellingwood

Justin Ellingwood

自 2013 年以来,Justin 一直在撰写关于数据库、Linux、基础设施和开发者工具的文章。他目前与妻子和两只兔子住在柏林。他通常不必以第三人称写作,这对所有相关方来说都是一种解脱。