我正在看一些PostgreSQL表的创建,我偶然发现了这个:
CREATE TABLE (
...
) WITH ( OIDS = FALSE );
我阅读了postgres提供的文档,我从OOP中了解了对象标识符的概念,但仍然没有把握,
答案 0 :(得分:139)
OID基本上为每行提供一个内置的,全局唯一的id,包含在系统列中(与用户空间列相对)。对于没有主键,有重复行等的表格来说这很方便。例如,如果你有一个包含两个相同行的表,并且你想要删除这两行中最老的那些,你可以使用oid专栏。
根据我的经验,该功能通常在大多数postgres支持的应用程序中未使用(可能部分原因是它们是非标准的),their use is essentially deprecated:
在PostgreSQL 8.1中,default_with_oids是 默认关闭;在以前的版本中 PostgreSQL,它默认开启。
在用户表中使用OID是 被认为已弃用,所以大多数 安装应该离开这个 变量已禁用。应用程序 要求特定表的OID 应该在创建时指定WITH OIDS 桌子。这个变量可以 启用与旧版本的兼容性 不遵循此规定的应用程序 行为。
答案 1 :(得分:12)
OID仍在使用Postgres with大objects(尽管有些人认为大对象通常不是很有用)。它们也被system tables广泛使用。它们例如由TOAST使用,它将大于8KB的BYTEA(等)存储到一个单独的存储区域(透明地),默认情况下由所有表使用。它们与“普通”用户表的直接使用基本上是deprecated。
oid类型目前实现为无符号四字节整数。因此,它不足以在大型数据库或甚至大型单个表中提供数据库范围的唯一性。因此,不鼓励使用用户创建的表的OID列作为主键。 OID最好仅用于对系统表的引用。
显然,如果OID序列超过4B 6,它会“包裹”。所以从本质上讲,它是一个可以包装的全局计数器。如果它确实包装,那么当它被使用并“搜索”唯一值等时,可能会开始发生一些减速。
答案 2 :(得分:2)
要从数据库表中删除所有OID,可以使用此Linux脚本:
首先,以PostgreSQL超级用户身份登录:
copy \\serverlocation\file.txt locallocation\otherFile.txt@@@
copy \\serverlocation\file.txt locallocation\otherFile.txt@@@
.
.
.
and so on...
现在运行此脚本,使用您的数据库名称更改YOUR_DATABASE_NAME:
sudo su postgres
我使用这个脚本删除了所有的OID,因为Npgsql 3.0不能解决这个问题,而且对PostgreSQL来说不再重要。
答案 3 :(得分:1)
负责Postgres的核心团队正在逐步淘汰OID。
现在已从Postgres 12中删除了将OID用作表上的可选系统列。您将无法再使用:
CREATE TABLE … WITH OIDS
命令default_with_oids (boolean)
兼容性设置数据类型OID
保留在Postgres 12中。您可以显式创建类型为OID
的列。
在migrating to Postgres 12之后,任何可选定义的system column oid
在默认情况下将不再可见。现在执行SELECT *
将包括此列。请注意,此额外的“惊喜”列可能会破坏天真的编写的SQL代码。
答案 4 :(得分:0)
如果您仍然使用OID,则最好删除对它的依赖,因为在最新版本的Postgres中不再支持它。 例如,这可能会停止(直到您解决该问题为止),例如从版本10迁移到版本12。
另请参阅: https://dev.to/rafaelbernard/postgresql-pgupgrade-from-10-to-12-566i