SQL,Postgres OIDs,它们是什么,为什么它们有用?

7 浏览
0 Comments

SQL,Postgres OIDs,它们是什么,为什么它们有用?

我正在查看一些PostgreSQL表的创建过程,偶然发现了这个:\n

CREATE TABLE (
...
) WITH ( OIDS = FALSE );

\n我阅读了postgres提供的文档,了解了面向对象编程中的对象标识符的概念,但我仍然不明白:\n

    \n

  • 为什么数据库中需要这样的标识符?
  • \n

  • 是为了使查询更简洁?
  • \n

  • 应该在什么情况下使用?
  • \n

0
0 Comments

SQL中的OID(Object Identifier)是PostgreSQL数据库中的一种数据类型,用于标识数据库中的对象。在PostgreSQL中,OID主要用于大型对象(large objects)和系统表(system tables)。

大型对象是一种特殊类型的数据,通常包含大量二进制数据,如图像、音频或视频文件。PostgreSQL使用OID来引用和管理大型对象。大型对象存储在与普通表数据分离的存储区域中,这个存储区域称为TOAST(The Oversized-Attribute Storage Technique)。TOAST允许将超过8KB的BYTEA(二进制字符串)等较大的数据类型存储在独立的存储区域中,这样可以节省磁盘空间并提高查询性能。

在系统表中,OID被广泛使用。系统表是PostgreSQL内部使用的表,用于存储数据库元数据和其他系统信息。OID可以用于引用系统表中的行。

然而,在普通用户表中直接使用OID列作为主键是不推荐的。因为OID是一个无符号的四字节整数,不足以在大型数据库中提供全局唯一性。当使用OID作为主键时,可能会导致性能下降,并且在超过4B的情况下,OID序列会循环。

总结起来,OID在PostgreSQL中仍然用于大型对象和系统表。对于普通用户表,直接使用OID作为主键已不再推荐。

参考链接:

- [PostgreSQL官方文档 - 大型对象](http://www.postgresql.org/docs/9.4/static/largeobjects.html)

- [PostgreSQL官方文档 - 大型对象接口](http://www.postgresql.org/docs/9.4/static/lo-interfaces.html)

- [PostgreSQL官方文档 - TOAST](http://www.postgresql.org/docs/8.4/static/storage-toast.html)

- [PostgreSQL官方文档 - OID数据类型](http://www.postgresql.org/docs/9.4/static/datatype-oid.html)

- [PostgreSQL Wiki - FAQ](https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F)

0
0 Comments

OIDs被逐步淘汰

Postgres的核心团队正在逐步淘汰OIDs。

Postgres 12取消了OID列的特殊行为

在Postgres 12中,将不再使用OID作为表格的可选系统列。您不能再使用以下命令:

  • CREATE TABLE … WITH OIDS命令
  • default_with_oids (boolean)兼容性设置

数据类型OID仍然存在于Postgres 12中。您可以显式地创建一个OID类型的列。

迁移到Postgres 12后,任何可选定义的系统列oid将不再默认隐藏。执行SELECT *将包括此列。请注意,这个额外的"surprise"列可能会破坏简单编写的SQL代码。

0
0 Comments

SQL中的OID(对象标识符)是一种系统列,为每一行提供了内置的标识符。对于没有主键、有重复行等情况的表格来说,这非常方便。举个例子,如果你有一张包含两行完全相同的表格,并且你想删除其中较早的那一行,你可以使用OID列来实现。

OID使用4字节的无符号整数实现。它们不是唯一的,OID计数器在达到2³²-1后会循环。OID还用于标识数据类型。

根据我的经验,在大多数使用Postgres的应用程序中,这个功能基本上是不被使用的(可能部分原因是因为它们是非标准的),而且它们的使用已经被弃用了。在PostgreSQL 8.1中,默认情况下关闭了default_with_oids选项,而在之前的版本中,默认情况下是开启的。使用OID在用户表中被认为是不推荐的做法,因此大多数安装应该禁用这个变量。对于需要在特定表格中使用OID的应用程序,在创建表格时应该指定WITH OIDS选项。这个变量可以用于与不遵循此行为的旧应用程序的兼容性。

OIDs不能保证唯一性。根据文档:"在一个大型或长期运行的数据库中,计数器可能会循环。因此,假设OID是唯一的是不好的做法,除非你采取措施确保这一点。"

循环使用还意味着不能仅仅基于OID删除两行中的较旧行,因为较低的OID可能是循环的结果。

OIDs不是全局唯一的,正如上述评论所述,即使在2011年撰写这篇回答时也是如此。此外,系统对象需要使用OID,因此在行计数器上使用所有OID并不能帮助数据库为新表格(而不仅仅是表格的行)分配OID。此外,考虑一下,一个4字节的整数计数器是否足以满足数据库中每个表格的需求。

值得一提的是,在大多数phpPgAdmin的实现中,创建表格时,默认情况下选中了禁用选项,实际上意味着这个选项已经被弃用了。

如果你不知道OID的用途,那么你可能不应该使用它们。

对于你的论点,不适用。确保唯一性与字段长度无关。通过拒绝以控制的方式分配已经被使用的值,比如抛出错误,固定长度字段可以被保证是唯一的,而不仅仅是静默地循环计数器。我们在DDL中有一个唯一关键字的原因,我们可以选择使用它或不使用它。

0