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

我正在看一些PostgreSQL表创build,我偶然发现:

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

我读了postgres提供的文档,我知道面向对象标识符的概念,但我仍然没有把握,

  • 为什么这样的标识符会在数据库中有用?
  • 使查询更短?
  • 何时应该使用?

OID基本上为您提供了一个内置的,全球唯一的id,包含在系统列中(而不是用户空间列)。 对于那些没有主键,有重复行等的表格来说,这很方便。例如,如果你有一个有两个相同行的表,而你想删除两个最老的表,你可以用oid列。

根据我的经验,这个特性在大多数postgres-backed应用程序中通常是没有用的(可能部分是因为它们是非标准的), 它们的使用基本上被弃用了 :

在PostgreSQL 8.1中,default_with_oids默认是closures的; 在之前的PostgreSQL版本中,默认情况下是打开的。

在用户表中使用OID被认为是不推荐使用的,所以大多数安装应该禁用这个variables。 需要特定表的OID的应用程序在创build表时应指定WITH OIDS。 可以启用此variables以兼容不遵循此行为的旧应用程序。

PostgreSQL 的大对象仍然在使用OID(尽pipe有些人认为大对象通常不会有用)。 它们也被系统表广泛使用。 它们用于例如TOAST ,其将大于8KB的BYTEA(等)存储到单独的存储区域(透明地), 所有表被默认使用。 与“普通”用户表关联的直接使用基本上被弃用 。

oidtypes当前是作为一个无符号的四字节整数实现的。 因此,在大型数据库甚至大型单个表中提供数据库范围的唯一性还不够大。 因此,不鼓励使用用户创build的表的OID列作为主键。 OID最好只用于引用系统表。

显然,如果超过4B 6 ,OID序列就会“包裹” 所以在本质上这是一个可以换行的全局计数器。 如果它包装,一些减速可能会开始发生,当它被使用和“search”的唯一值,等等

另见https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

要从数据库表中删除所有的OID,你可以使用这个Linux脚本:

首先,以PostgreSQL超级用户身份login:

 sudo su postgres 

现在运行这个脚本,用你的数据库名称更改YOUR_DATABASE_NAME:

 for tbl in `psql -qAt -c "select schemaname || '.' || tablename from pg_tables WHERE schemaname <> 'pg_catalog' AND schemaname <> 'information_schema';" YOUR_DATABASE_NAME` ; do psql -c "alter table $tbl SET WITHOUT OIDS" YOUR_DATABASE_NAME ; done 

我使用这个脚本删除了所有的OID,因为Npgsql 3.0不能用于这个,对PostgreSQL来说也不重要。