FAQ/de
常见问题
什么是 PostgreSQL?怎么发音?
英文发音是“Post-Gres-Q-L”。在一般用语中,简称为“Postgres”也很常见。(对于感兴趣的人来说,这里有一个带有美国发音的 MP3 文件:https://postgresql.ac.cn/files/postgresql.mp3
PostgreSQL 是一个对象关系型数据库系统,它将商业数据库系统的优点与开创性的创新相结合。PostgreSQL 是自由软件,其完整源代码是公开可用的。
PostgreSQL 的开发由一个主要由志愿者组成的开发人员团队负责。这个团队负责 PostgreSQL 的整体开发。这是一个社区项目,不受任何特定公司控制。如果您有兴趣参与,请阅读开发人员 FAQ:https://postgresql.ac.cn/docs/faqs.FAQ_DEV.html
谁控制着 PostgreSQL?
如果您正在寻找所有者姓名或任何全能的中央委员会,请放弃寻找,因为根本不存在。虽然存在“核心委员会”和拥有 CVS 写入权限的开发人员,但这些组织仅起着管理作用。这个项目由社区控制,社区由开发人员和用户组成 - 任何人都可以参与其中。(如果您想参与 PostgreSQL 的开发,请阅读开发人员 FAQ:https://postgresql.ac.cn/docs/faqs.FAQ_DEV.html)。
PostgreSQL 受什么版权保护?
PostgreSQL 在传统的 BSD 许可下发布。基本上,这允许用户随意使用代码,即使销售没有源代码的二进制版本也是允许的。唯一的限制是,对于使用该软件产生的任何问题,PostgreSQL 概不负责。此外,所有软件副本中必须包含版权文本。这是 BSD 许可的原始文本
PostgreSQL Data Base Management System Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group Portions Copyright (c) 1994-6 Regents of the University of California Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
请尊重版权信息!
PostgreSQL 在哪些平台上运行?
通常,PostgreSQL 可以运行在任何现代的 UNIX 兼容平台上。在每个版本发布时测试的平台都在安装说明中列出。
PostgreSQL 也运行在基于 Microsoft NT 的操作系统上,如 Windows 2000 SP4、XP 和 Server 2003。可以在 http://pgfoundry.org/projects/pginstaller 下载预先打包的安装程序。基于 DOS 的 Windows 版本(Win95、Win98、WinMe)只能在 Cygwin 环境下运行 PostgreSQL。
从哪里可以获取 PostgreSQL?
通过 Web 浏览器:https://postgresql.ac.cn/ftp/,通过 FTP:ftp://ftp.postgresql.org/pub/。
PostgreSQL 的最新版本是什么?
可以在 网站 上查看 PostgreSQL 的最新版本。
通常每年发布一个新的主要版本,每隔几个月发布一个小的修订版本。较小的更新称为“次要”更新,每年发布的大型更新称为“主要”更新。“次要”更新通常同时发布到所有受支持的“主要”版本中。如果您对此主题感兴趣,请在此处继续阅读。
在哪里可以获得 PostgreSQL 的支持?
PostgreSQL 社区通过邮件列表提供支持。网页 https://postgresql.ac.cn/community/lists/ 提供了一个概述。general 和 bugs 邮件列表是一个很好的起点。
这里有一个德语邮件列表:http://archives.postgresql.org/pgsql-de-allgemein/.
最重要的 IRC 频道是 Libera 上的 #postgresql(irc.libera.chat)。在 UNIX/Linux 上,您可以使用 irc -c '#postgresql' "$USER" irc.libera.chat 加入。Libera 上有以下频道
- #postgresql-es(西班牙语)
- #postgresqlfr(法语)
- #postgresql-br(巴西葡萄牙语)
另外还有一个 EFNet 上的 PostgreSQL 频道。
可以在 https://postgresql.ac.cn/support/professional_support 上查看提供商业支持 PostgreSQL 的公司列表。
如何提交错误报告?
请使用以下表格提交错误报告:https://postgresql.ac.cn/support/submitbug。但在提交之前,请查看ftp://ftp.postgresql.org/pub/,看看是否有更新的 PostgreSQL 版本已经修复了该错误。
通过表格或邮件列表报告的错误通常会得到以下回应:
- 这不是一个错误,并给出原因。
- 这是一个已知错误,已添加到待办事项列表中。
- 该错误已在当前版本中修复。
- 该错误已修复,但尚未包含在正式发布的版本中。
- 需要更详细的信息,例如:
- 操作系统
- PostgreSQL 版本
- 可重复的测试用例
- 调试信息
- 调试器回溯输出
- 这是一个新错误。可能会发生以下情况:
- 将创建补丁并将其包含在下一个版本中。
- 该错误无法立即修复,并将被添加到待办事项列表中。
如何了解已知错误或缺少的功能?
PostgreSQL 支持 SQL:2003 的扩展子集。请查看我们的待办事项列表,网址为https://postgresql.ac.cn/docs/faqs.TODO.html,以获取已知错误、缺少的功能和未来计划的列表。
对新功能的请求通常会得到以下回应:
- 该功能已在待办事项列表中。
- 该功能不受欢迎,因为:
- 它复制了已有的功能,而这些功能已经符合 SQL 标准。
- 它会增加代码库的复杂性,而不会带来明显的好处。
- 它不安全或不可靠。
- 该新功能将添加到待办事项列表中。
PostgreSQL 不使用错误跟踪系统,因为直接回复邮件和维护待办事项列表被证明更有效。在实践中,错误会被很快修复,而那些影响大量用户的错误通常会很快得到修复。所有更改、改进和修复的唯一概述位于 PostgreSQL 版本的 CVS 日志消息中。发行说明也不包含软件中所有更改的列表。
PostgreSQL 提供哪些文档?
PostgreSQL 提供丰富的文档,包括大型手册、man 页面和一些小型测试程序。请参阅 /doc 目录。此外,所有手册都可以在线获取,网址为https://postgresql.ac.cn/docs/。
两本关于 PostgreSQL 的书籍可以在线获取,网址分别为https://postgresql.ac.cn/docs/books/awbook.html 和 http://www.commandprompt.com/ppbook/。
可获取的 PostgreSQL 图书列表位于https://postgresql.ac.cn/docs/books。各种技术文章位于https://postgresql.ac.cn/docs/techdocs。
psql 有一些有用的 \d 命令,用于显示关于类型、运算符、函数、聚合等的信息。
PostgreSQL 网站提供更多文档。
如何学习 SQL?
前面提到的 PostgreSQL 专用书籍可以作为很好的入门资料。许多 PostgreSQL 用户喜欢“The Practical SQL Handbook”(Bowman 等人,Addison Wesley)。而另一些用户则喜欢“The Complete Reference SQL”(Groff 等人,McGraw-Hill)。
还有一些有用的在线教程:
- http://www.intermedia.net/support/sql/sqltut.shtm
- http://sqlcourse.com
- https://w3schools.org.cn/sql/default.asp
- http://mysite.verizon.net/Graeme_Birchall/id1.html
如何加入开发者团队?
请阅读开发者常见问题解答。
与其他数据库系统相比,PostgreSQL 的性能如何?
衡量软件的方法有很多:特性、性能、可靠性、支持和价格。
特性
PostgreSQL besitzt die meisten Eigenschaften - wie Transaktionen, Unterabfragen (Subqueries), Trigger, Views, referenzielle Integrität bei Fremdschlüsseln und verfeinertes Locking - die bei großen kommerziellen DBMS vorhanden sind. Es bietet außerdem einige anderen Eigenschaften, die diese nicht immer haben, wie benutzerbestimmte Typen, Vererbung, Regeln, und die Multi-Versionen-Steuerung zum Verringern konkurrierender Locks.
性能
Die Performanz von PostgreSQL ist mit der von kommerziellen und anderen Open-Source-Datenbanken vergleichbar. In manchen Bereichen ist es schneller, in anderen langsamer. In der Regel beträgt der Unterschied +/-10%.
可靠性
Es ist selbstredend, dass ein DBMS wertlos ist, wenn es nicht zuverlässig arbeitet. Daher bemühen wir uns, nur streng geprüften und beständigen Code freizugeben, der nur ein Minimum an Programmfehlern aufweist. Jede Freigabe hat mindestens einen Monat Betatest-Phase hinter sich, und unsere Freigabehistorie beweist, dass wir stabile und solide Versionen freigeben, die im Produktionsbetrieb genutzt werden können. Wir glauben, dass wir im Vergleich mit anderer Datenbanksoftware vorteilhaft dastehen.
支持
Unsere Mailinglisten bieten die Möglichkeit, gemeinsam mit einer großen Gruppe von Entwicklern und Benutzern mögliche Probleme zu lösen. Wir können nicht immer eine Fehlerbehebung garantieren, kommerzielle DBMS tun dies aber auch nicht. Der direkte Kontakt zur Entwickler- und Benutzergemeinschaft und der Zugriff auf die Handbücher und den Quellcode ermöglicht einen im Vergleich zu anderen DBMS höherwertigeren Support. Es gibt jedoch auch Anbieter von kommerziellen Support-Leistungen (siehe FAQ-Punkt 1.7).
价格
PostgreSQL ist frei verfügbar, sowohl für die kommerzielle wie auch für die nicht-kommerzielle Nutzung. Sie können den PostgreSQL-Code ohne Einschränkungen (außer denjenigen, die in der oben angegebene BSD-artigen Lizenz erwähnt werden) in Ihr Produkt integrieren.
PostgreSQL 可以嵌入吗?
PostgreSQL 基于服务器/客户端架构,它需要为每个客户端和服务器使用单独的进程,此外还需要其他“辅助进程”(例如,用于 autovacuum 和 stats-collector)。虽然一些“嵌入式架构”可以满足这些要求,但如果数据库进程必须在应用程序进程内运行,则无法使用 PostgreSQL。在这种情况下,应该选择更轻量级的数据库。
如何取消订阅邮件列表?如何防止收到重复的邮件?
Majordomo 允许您订阅和取消订阅所有邮件列表,您可能需要先获取您的 Majordomo 密码。您可以访问 PostgreSQL 的 Majordomo。
PostgreSQL 邮件列表的配置方式是,回复将发送给原始发件人和邮件列表。这样是为了确保用户能够尽快收到回复。您也可以通过 Majordomo 的配置更改这些设置,为此请更改 eliminatecc 设置。您还可以设置不将自己的邮件回复发送给自己,为此请更改 selfcopy 设置。您可以访问 PostgreSQL 的 Majordomo。
关于用户程序的问题
PostgreSQL 提供哪些接口?
PostgreSQL 安装仅提供 C 和嵌入式 C 接口。所有其他接口都是独立的项目,需要单独下载。这种分离允许各个开发团队和开发周期用于各自的项目。
一些编程语言,例如 PHP,已经内置了 PostgreSQL 接口。Perl、TCL、Python 和许多其他语言的接口可以在http://gborg.postgresql.org 的 Drivers/Interfaces 部分找到,也可以通过互联网搜索找到。
如何在网站中使用 PostgreSQL?
您可以从http://www.webreview.com(英文)获得有关基于数据库的网站的良好介绍。
对于 Web 集成,PHP 是一个很好的接口。您可以从https://php.ac.cn 获得 PHP。
此外,使用 CGI.pm 或 mod_perl 的 Perl 接口也是一个不错的选择。
PostgreSQL 有图形用户界面吗?
有许多用于 PostgreSQL 的 GUI 程序,包括商业程序和开源程序。您可以访问此处的英文列表。
管理问题
如何在 /usr/local/pgsql 之外安装 PostgreSQL?
在运行 configure 时,使用 --prefix 选项指定目标目录。
如何管理来自其他计算机的访问?
PostgreSQL 默认情况下仅允许本地计算机通过 Unix Domain Sockets 或 TCP/IP 连接。只有在 postgresql.conf 文件中更改 listen_addresses 设置,在 $PGDATA/pg_hba.conf 文件中启用基于主机的身份验证,并重新启动服务器后,才能允许来自其他计算机的连接。
如何提高性能?
可以在三个主要方面进行性能改进:
查询优化
修改查询可以提高性能
- 创建索引,包括部分索引和表达式索引
- 使用 COPY 而不是多个 INSERT 语句
- 将多个查询分组到一个事务中,以减少事务完成的开销
- 使用 CLUSTER 从索引中获取大量数据行
- 使用 LIMIT 返回查询结果的子集
- 使用准备好的语句(prepared queries)
- 使用 ANALYZE 更新数据库统计信息,以便查询计划程序使用
- 定期使用 VACUUM 或 pg_autovacuum(从 8.3 版本开始,autovacuum 默认启用)
- 在进行大量数据更改时,删除索引
服务器配置
postgresql.conf 文件中的某些设置会影响性能。手册中包含https://postgresql.ac.cn/docs/current/static/runtime-config.html 中列出的所有设置。
有关每个设置的说明,请参阅http://www.varlena.com/varlena/GeneralBits/Tidbitsannotated_conf_e.html 和 http://www.varlena.com/varlena/GeneralBits/Tidbits/perf.html。
硬件选择
硬件对性能的影响在http://momjian.us/main/writings/pgsql/hw_performance/index.html 和 http://www.powerpostgresql.com/PerfList/ 中进行了说明。
PostgreSQL 提供哪些调试功能?
服务器配置选项中包含许多 log_*- 变量,这些变量允许输出查询和进程统计信息。这些信息对于调试和性能测试非常有用。
当我尝试建立连接时,收到“Sorry, too many clients”错误。为什么?
您的系统已经达到最大允许的数据库连接数(默认值为 100)。您需要增加可以同时运行的后端进程的最大数量,为此请在 postgresql.conf 中更改 max_connections 值,并重新启动服务器。
如何更新 PostgreSQL?
有关更新 PostgreSQL 的一般信息,请访问https://postgresql.ac.cn/support/versioning。有关详细的技术信息,请访问https://postgresql.ac.cn/docs/current/static/install-upgrading.html
PostgreSQL 是否支持不同国家/地区的夏令时调整?
从 8.0 版本开始,PostgreSQL 使用广泛使用的 tzdata 数据库(也称为“zoneinfo database”或“Olzen timezone database”)来考虑夏令时。
每个 PostgreSQL 更新都包含最新的 tzdata 文件,因此只需关注所用主要版本的次要更新即可。
在操作系统始终保留这些文件的最新版本的假设下,通常使用这些文件。PostgreSQL 提供了一个编译选项。
哪些硬件适合运行 PostgreSQL?
PostgreSQL 几乎可以在所有硬件组合上运行。然而,在 PC 领域,质量差异很大。对于工作站或开发计算机来说,这可能不太重要,但在服务器运行中,投资更昂贵的组件绝对值得(关键词:ECC 内存、SCSI、知名制造商的主板和电源)。使用我们的邮件列表讨论硬件选项。
运行问题
如何使用 SELECT 语句只选择查询中的前几行或任意一行?
如果您在执行查询时已经知道要请求的行数,请使用 LIMIT。如果 ORDER BY 语句与索引一起使用,则可能不需要执行整个查询。如果您不知道要请求的行数,请使用游标和 FETCH。
要选择任意一行,请使用 ORDER BY random()
SELECT spalte FROM tabelle ORDER BY random() LIMIT 1
如何找出数据库中定义了哪些表、索引、数据库或用户?如何获取 psql 使用的查询?
在 psql 中,\dt 命令显示数据库表的列表。其他 psql 命令可以通过 \? 显示。您可以查看 pgsql/src/bin/psql/describe.c 文件,其中包含 psql 的源代码。它包含执行反斜杠命令 (\) 的 SQL 查询。您也可以使用 -E 选项启动 psql。之后,psql 会输出它在执行命令时使用的查询。此外,PostgreSQL 提供了一个 SQL 兼容的 INFORMATION SCHEMA,它提供有关数据库的元信息。
使用 psql -l,您可以显示所有数据库。
pgsql/src/tutorial/syscat.source 文件还包含许多 SELECT 查询,这些查询可以帮助您获取有关系统表的相关信息。
如何更改列的数据类型?
从 8.0 版本开始,可以使用 ALTER TABLE ALTER COLUMN TYPE 更改列的数据类型,前提是新的数据类型可以容纳旧数据类型的值。
在早期版本中,请按照以下步骤操作
BEGIN; ALTER TABLE tabelle ADD COLUMN neue_spalte neuer_datentyp; UPDATE tabelle SET neue_spalte = CAST(alte_spalte AS neuer_datentyp); ALTER TABLE tabelle DROP COLUMN alte_spalte; COMMIT;
要释放已删除列使用的存储空间,请执行 VACUUM FULL。
行、表和数据库的最大尺寸是多少?
存在以下上限
Maximale Größe eine Datenbank? unbeschränkt (es existieren Datenbanken mit 32 TB) Maximale Größe einer Tabelle? 32 TB Maximale Größe einer Zeile? 400 GB Maximale Größe einer Spalte? 1 GB Maximale Anzahl von Zeilen in einer Tabelle? unbeschränkt Maximale Anzahl von Spalten in einer Tabelle? 250-1600 je nach Spaltentyp Maximale Anzahl von Indexen für eine Tabelle? unbeschränkt
当然,这些是理论值,通常受可用磁盘和内存资源的限制。极端的尺寸会导致性能下降。
32 TB 的最大表尺寸不需要操作系统中的大文件支持。大型表将被分成大小为 1 GB 的文件,因此任何文件系统相关的限制都无关紧要。
通过将默认块大小增加到 32 KB,可以将最大表大小和最大列数增加四倍。还可以通过表分区来增加表大小。
一个限制是,只能在大小不超过约 2000 个字符的列上创建索引。要对更大的列设置 UNIQUE 约束,请使用一个包含列的 MD5 哈希值的函数索引。要在一个包含文本的大型列中进行搜索,请使用全文索引。
保存典型文本文件中的数据需要多少磁盘空间?
PostgreSQL 数据库在保存简单文本文件时,可能会占用比文件实际大小多五倍的空间。
考虑一个包含 100,000 行的文本文件,每行包含一个整数和一个文本描述。假设文本描述的平均长度为 20 字节。这个简单文件将占用 2.8 MB 的空间。包含这些数据的 PostgreSQL 数据库文件的大小约为 5.2 MB
24 Bytes: jeder Zeilenkopf (ungefähr)
+24 字节:一个整数字段和一个文本字段 + 4 字节:数据页面上指向元组的指针
52 Bytes pro Zeile
PostgreSQL 中数据页面的大小为 8192 字节(8 KB),因此:每页 8192 字节
= 每页 146 行(四舍五入)
52 Bytes pro Zeile
100,000 行数据
= 685 个数据库页面(四舍五入)
158 Zeilen pro Seite
633 个数据库页面 * 每页 8192 字节 = 5,185,536 字节(5.2 MB)
索引占用的空间并不多。但是,由于它们包含它们索引的数据,它们也可能非常大。
NULL 值以位图的形式存储,因此它们占用的空间非常少。
我的查询很慢或没有使用索引。为什么?
索引不会在每次查询中自动使用。只有当要查询的表超过特定大小且查询仅查询表中一小部分行时,才会使用索引。原因是,索引引起的磁盘访问有时会比简单地读取所有表行(顺序扫描)花费更长时间。
为了确定是否应该使用索引,PostgreSQL 需要有关表的统计信息。这些统计信息通过 VACUUM ANALYZE 或 ANALYZE 命令计算。通过这些统计信息,查询优化器可以知道表中包含的行数,并能更好地决定是否使用索引。统计信息在确定最佳连接顺序和方法时也非常有用。因此,应定期执行这些操作,因为表的内容也会发生变化。
索引通常不会在 ORDER BY 查询或连接中使用。顺序扫描加上显式排序通常比对大型表进行索引扫描更快。但是,在使用 LIMIT 和 ORDER BY 的查询中,通常会使用索引,因为仅返回表的一小部分。
如果看起来优化器错误地执行了顺序扫描,请执行 SET enable_seqscan TO 'off',并检查索引查询是否因此变快。
在使用通配符运算符(如 LIKE 或 ~)时,索引只能在某些情况下使用
- 搜索模式必须位于字符串的开头,即
- LIKE 搜索模式不能以 % 开头;
- ~(正则表达式)必须以 ^ 开头。
- 搜索模式不能以字符类(例如 [a-e])开头。
- 不区分大小写的搜索模式(例如 ILIKE 或 ~*)不使用索引。相反,可以使用 4.8 节中描述的函数索引。
- 标准区域设置“C”必须在数据库初始化时使用 initdb 进行设置,因为其他区域设置无法确定下一个最大的值。不过,可以为此类情况创建一个特殊的 text_pattern_ops 索引。
在 8.0 之前的版本中,如果数据类型不完全匹配,则索引通常不会使用。这尤其适用于 INT2、INT8 和 NUMERIC 数据类型的列上的索引
我如何查看查询优化器如何评估我的查询?
有关此主题的详细说明,请参阅 EXPLAIN 文档。
如何更改类似文本数据的排序行为?
PostgreSQL 使用在 initdb 中设置的区域设置对数据进行排序。(从 8.4 版本开始,可以在每个数据库中定义一个唯一的区域设置)
如果排序行为与预期不符,则需要更改区域设置。除了“C”以外的大多数区域设置都根据相应词典的顺序进行排序。“C”区域设置会忽略所有标点符号和空格。
如何进行正则表达式搜索和不区分大小写的搜索?如何在此类搜索查询中使用索引?
~ 运算符应用正则表达式,而 ~* 运算符应用正则表达式,但不区分大小写。同样,LIKE 区分大小写,而 ILIKE 不区分大小写。
不区分大小写的相等比较通常如下所示
SELECT * FROM tabelle WHERE LOWER(spalte) = 'abc'
这里不会使用普通索引。但是,如果创建一个函数索引,则它一定会被使用
CREATE INDEX tabelle_index ON tabelle (LOWER(spalte))
如果将上述索引作为 UNIQUE 索引创建,则不能将任何仅在大小写方面不同的值插入该列。为了避免错误,必须使用 CHECK 约束或触发器。
如何在查询中确定一个字段是否为 NULL?可以根据 NULL 是否被赋值进行排序吗?
使用 IS NULL 或 IS NOT NULL 测试该列。
SELECT * FROM tabelle WHERE spalte IS NULL
将 NULL 值与其他值连接起来时,结果也将是 NULL。为了避免这种情况,最好使用 COALESCE()
SELECT COALESCE(col1, ) || COALESCE(col2, ) FROM tab;
要根据该列是否被赋值 NULL 进行排序,请在 ORDER BY 子句中使用 IS NULL 或 IS NOT NULL 条件。由于为真的条件比相反的条件排序更高,因此以下查询会使 NULL 列首先列出
SELECT * FROM tabelle ORDER BY (spalte IS NOT NULL)
从 PostreSQL 8.3 版本开始,可以使用标准化的 NULLS FIRST/NULLS LAST 来确定结果中 NULL 值的位置。(FIRST 表示放在开头,LAST 表示放在末尾)
SELECT * FROM tab ORDER BY col NULLS FIRST;
不同 CHAR 类型之间的区别是什么?
类型 | 内部名称 | 备注 |
---|---|---|
VARCHAR(n) | varchar | 大小指定最大长度;不会用空格填充 |
CHAR(n) | bpchar | 用空格填充到指定的长度 |
TEXT | text | 没有长度上限 |
BYTEA | bytea | 可变长度字节数组(也适用于 '\0' 字节) |
"char"(带引号) | char | 一个字符 |
内部名称主要出现在系统目录和一些错误消息中。
前四种类型是“varlena”类型(即前四个字节表示长度,后面跟着数据)。因此,实际占用的空间总是比声明的字段大小略大。但是,某些情况下,这些数据类型可能会使用 TOAST 机制进行数据压缩,这会导致实际占用的空间小于预期。
对于存储可变长度字符串,建议使用 VARCHAR(n)。VARCHAR(n) 字段的最大长度在定义表格时确定。TEXT 没有长度限制,但系统存在 1 GB 的上限。
CHAR(n) 适用于存储长度相同的字符串。请注意,CHAR(n) 会自动用空格填充字符串到定义的字段长度,而 VARCHAR(n) 只会存储实际输入的字符串。
BYTEA 用于存储二进制数据,特别是包含 NULL 字节的值。
这里提到的所有类型都具有相似的性能特性。
如何创建具有自动递增值的序列字段?
PostgreSQL 提供了 SERIAL 数据类型。这不是真正的数据类型,而是创建整数类型列的简写形式,该列由序列填充。
例如
CREATE TABLE person ( id SERIAL, name TEXT )
将自动转换为
CREATE SEQUENCE person_id_seq; CREATE TABLE person ( id INT4 NOT NULL DEFAULT nextval('person_id_seq'), name TEXT );
。
自动生成的序列始终具有以下名称:表格名-列名_seq
CREATE SEQUENCE 的手册页包含更多关于序列的信息。
还有一种 BIGSERIAL 类型,它只是将列的类型改为 BIGINTEGER。如果预计需要使用超过 20 亿个序列值,则应使用 BIGSERIAL。
如何获取 SERIAL 序列的值?
一种方法是使用 nextval() 函数在执行 INSERT 语句之前从序列对象请求下一个 SERIAL 值,然后将其显式插入 INSERT 语句中。根据 4.11.1 中的示例表格,此过程可以用伪代码表示为
new_id = output of execute("SELECT nextval('person_id_seq')"); execute("INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal')");
之后,新的值将保存在 new_id 变量中,可用于其他查询,例如作为 'person' 表的外键。请注意,自动创建的 SEQUENCE 对象的名称为:«table»_«serialcolumn»_seq,其中 'table' 和 'serialcolumn' 分别代表相关表格和列的名称。
另一种方法是在 INSERT 语句之后使用 currval() 函数返回自动插入的 SERIAL 值
execute("INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal')"); new_id = output of execute("SELECT currval('person_id_seq')");
最简单的方法是使用 RETURNING。一个简单的示例如下:INSERT INTO person (name) VALUES ('Blaise Pascal') RETURNING id;
currval() 会导致与其他用户发生竞态条件吗?
不会。currval() 返回一个由您的数据库会话确定的值,其他会话无法访问。
为什么事务中止后序列值不会重置?为什么我的序列/SERIAL 列编号中存在缺口?
为了提高事务的并发处理能力,序列不会被锁定以供其他事务使用,而是立即将序列号分配给正在运行的事务。序列编号中的缺口是由中止的事务引起的。
什么是 OID?
在 PostgreSQL 中,每行数据都会生成一个唯一的 OID,除非表格在创建时使用了 WITHOUT OIDS 选项。OID 是自动分配的 4 字节整数,在整个数据库中是唯一的。但是,当达到大约 40 亿时,它们会溢出。PostgreSQL 使用 OID 来连接其内部系统表格。
但是,为了在数据表格中创建唯一的标识符,建议使用由 SERIAL 序列生成的数值而不是 OID。SERIAL 序列在表格内是唯一的,因此不容易溢出。此外,可以使用 BIGSERIAL (SERIAL8) 生成 8 字节序列值。
什么是 CTID?
CTID 用于通过块和偏移量值识别特定的物理行。当行被修改或重新加载时,CTID 会改变。它们被用于索引条目中,用于指向物理行。
为什么我会收到错误消息:“ERROR: Memory exhausted in AllocSetAlloc()”?
可能是您的系统中没有更多虚拟内存,或者您的内核对某些资源设置了较低的限制。在启动 postmaster 之前,尝试以下操作
ulimit -d 262144 limit datasize 256m
根据您使用的 shell,只有一个命令会成功执行。在任何情况下,这都会增加进程的数据段限制,并可能使查询成功执行。如果您在使用 SQL 客户端时遇到问题,因为后端返回了太多数据,请在启动 SQL 客户端之前尝试以下操作。
如何确定我正在运行的 PostgreSQL 版本?
在 psql 中输入 SELECT VERSION();。
如何创建默认值始终为当前时间的列?
使用 CURRENT_TIMESTAMP
CREATE TABLE test (x INT, modtime TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
如何执行 OUTER JOIN?
PostgreSQL 支持按照 SQL 标准语法执行 OUTER JOIN。以下有两个示例
SELECT * FROM tabelle_1 t1 LEFT OUTER JOIN tabelle_2 t2 ON (t1.spalte = t2.spalte)
或者
SELECT * FROM tabelle_1 t1 LEFT OUTER JOIN tabelle_2 t2 USING (spalte)
这些相同的查询将 tabelle_1 与 tabelle_2 通过 'spalte' 列连接,并返回 tabelle_1 中的所有未连接行(那些在 tabelle_2 中没有匹配项的行)。RIGHT JOIN 会添加 tabelle_2 中的所有未连接行,而 FULL JOIN 会返回所有连接的行以及两个表格中所有未连接的行。指定 OUTER 不是必需的,可以在 LEFT、RIGHT 和 FULL 连接中省略。普通的连接是 INNER JOIN。
如何跨多个数据库执行查询?
没有办法在一个查询中访问多个数据库。由于 PostgreSQL 会加载特定于数据库的系统目录,因此无法进行跨数据库查询。
contrib/dblink 扩展程序允许通过函数调用执行跨数据库查询。
如何让函数返回多行或多列?
函数可以返回多行和多列,参见:https://postgresql.ac.cn/docs/techdocs.17.
为什么当我使用 PL/PgSQL 函数中的临时表格时,我会收到类似“relation with OID ##### does not exist”的错误消息?
在 8.3 之前的 PostgreSQL 版本中,PL/PgSQL 函数在缓存中处理。这会导致一个不好的副作用,即如果 PL/PgSQL 函数访问临时表格,然后该表格被删除或重新创建,该函数将失败,因为缓存的函数内容仍然指向旧的临时表格。解决这些问题的方案是在 PL/PgSQL 函数中使用 EXECUTE 访问临时表格。这将导致每次调用函数时都重新解析相关查询。
此问题在 PostgreSQL 8.3 及更高版本中不再出现。
有哪些复制解决方案?
"复制" 这个词包含多种不同的技术,每种技术都有自己的优缺点。文档中包含关于复制主题的良好介绍
使用"主/从" 复制,可以在主数据库中进行更改,然后将这些更改分发到以只读模式工作的"从属"数据库中。PostgreSQL 最流行的解决方案是 Slony-I。
"多主复制" 允许通过多个数据库服务器进行读写访问。但是,这种复制会对性能产生负面影响,因为它需要在服务器之间同步更改。Pgcluster 是 PostgreSQL 最流行的免费解决方案。
还有一些商业和硬件复制解决方案,用于各种复制类型。
为什么我的查询中没有识别表格和列名?为什么大写字母被转换为小写?
最常见的原因是在创建表格时使用引号,例如
CREATE TABLE "Tabelle" ("SPALTE1" INT)
这会将表格和列名(称为标识符)按原样存储(请参见文档),这意味着您必须始终在引号中使用它们。在上面的示例中,您必须始终使用 SELECT * FROM "Tabelle"。为了避免此问题,您必须始终注意以下几点
- 在创建表格时不要使用引号;
- 在标识符中只使用小写字母;
- 始终用引号括起标识符
译者注释
此 FAQ 的英文模板不断更新。因此,翻译可能不是最新的。
德语翻译的最新版本始终位于 http://sql-info.de/postgresql/FAQ_german.html。此“工作版本”可能包含尚未合并到 PostgreSQL 网站的更改。
欢迎您提供改进建议、更正建议以及对 FAQ 内容的理解问题。我乐于回答关于 PostgreSQL 的一般问题,但会将您引导到邮件列表作为快速可靠的解决途径。