PostgreSQL 中Identity Columns生成一个唯一的标识符

在 PostgreSQL 中,从版本 10 开始引入了“身份列”(Identity Columns)的概念,这是一种简化和标准化主键生成的方式,类似于其他数据库系统(如 SQL Server)中的 IDENTITY 属性。身份列允许数据库自动为表中的每一行生成一个唯一的标识符,通常用于主键字段。

使用身份列

要在 PostgreSQL 中创建一个带有身份列的表,你可以使用 GENERATED ALWAYS AS IDENTITY 子句。这里有一个简单的例子:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,  -- SERIAL 是一种简化的方式,等同于使用 IDENTITY
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

或者,更明确地使用 IDENTITY 关键字:

To create an identity column, use the GENERATED ALWAYS AS IDENTITY clause in CREATE TABLE

CREATE TABLE users (
    id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

To create an identity column, use the GENERATED BY DEFAULT AS IDENTITY clause in CREATE TABLE

CREATE TABLE users (
    id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

在这个例子中,id 列被设置为身份列,这意味着每当向 users 表中插入一行新数据时,id 列的值会自动递增。

superdb=# insert into users(username,email) values('A001','SZ');
INSERT 0 1
superdb=# insert into users(username,email) values('A002','GZ');
INSERT 0 1
superdb=# select * from users;
 id | username | email
----+----------+-------
  1 | A001     | SZ
  2 | A002     | GZ
(2 rows)

-- 指定关键字DEFAULT代替值以显式请求序列生成的值

superdb=# insert into users(id,username,email) values(DEFAULT,'A003','BJ');
INSERT 0 1
superdb=# select * from users;
 id | username | email
----+----------+-------
  1 | A001     | SZ
  2 | A002     | GZ
  3 | A003     | BJ
(3 rows)

自定义序列

默认情况下,身份列使用默认的序列生成器,但你也可以指定一个自定义的序列:

CREATE SEQUENCE custom_seq START WITH 1000 INCREMENT BY 1;

CREATE TABLE users (
    id INT GENERATED ALWAYS AS IDENTITY (SEQUENCE = custom_seq) PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

在这个例子中,id 列将使用 custom_seq 序列来生成值,从 1000 开始,每次递增 1。

注意事项

  1. 兼容性:虽然 SERIAL 类型在 PostgreSQL 中已经存在很长时间了,并且它实际上也是基于序列的自动递增列,但 IDENTITY 提供了更标准和灵活的语法。

  2. 事务回滚:如果在一个事务中插入了行但由于某种原因事务被回滚,那么这些行生成的序列值将不会被重用。这意味着序列值可能会有间隙。

  3. 性能:对于大多数应用来说,使用身份列的性能是非常好的。然而,在高并发环境下,可能需要考虑序列的性能调优。

  4. 手动插入:虽然身份列通常用于自动生成值,但你也可以手动插入值。如果尝试插入一个已经存在的值,将会导致一个唯一性约束错误。

  5. 迁移:如果你正在从旧版本的 PostgreSQL 迁移到支持身份列的新版本,你可能需要更新你的表定义以使用 IDENTITY 属性。

通过使用身份列,PostgreSQL 提供了一种简洁而强大的方式来管理主键和其他需要唯一标识符的列。

### 关于 PostgreSQL 对象唯一标识符与 `pg_class` 中 `oid` 的联合使用 #### 作用 在 PostgreSQL 数据库中,`oid` 是一种特殊的对象标识符类型,用于唯一标识数据库中的各种对象。`pg_class` 系统目录存储了所有关系的信息(如表、索引等),其中每一项都有一个唯一的 `oid` 值[^1]。通过将 `oid` 和其他系统视图或函数结合使用,可以实现多种功能。 以下是几个常见的应用场景及其示例: --- #### 示例 1: 查找特定表对应的 `oid` 可以通过查询 `pg_class` 来获取某个表的 `oid` 值。这有助于进一步操作该表的相关元数据。 ```sql SELECT oid FROM pg_class WHERE relname = 'tb1'; ``` 此查询返回名为 `tb1` 的表所对应的 `oid` 值。 --- #### 示例 2: 获取表的数据类型对象 `oid` 如果需要了解某张表关联的数据类型对象,则可以通过 `reltype` 字段来查询其 `oid` 值。 ```sql SELECT reltype FROM pg_class WHERE relname = 'tb1'; ``` 上述语句会返回与表 `tb1` 相关联的数据类型对象的 `oid` 值。 --- #### 示例 3: 结合 `pg_roles` 查询表的所有者信息 为了查看谁拥有某一具体表,可利用 `pg_class` 和 `pg_roles` 表之间的连接完成这一需求。 ```sql SELECT c.relname AS table_name, r.rolname AS owner_name FROM pg_class c JOIN pg_roles r ON c.relowner = r.oid WHERE c.relkind = 'r' AND c.relname = 'tb1'; ``` 这段 SQL 将展示名称为 `tb1` 的表以及它的所有者的用户名[^3]。 --- #### 示例 4: 使用 `pg_relation_filepath` 找到表的物理文件路径 借助 `pg_relation_filepath` 函数并提供目标表的 `oid` 或直接指定表名作为参数,能够定位到实际磁盘上的存储位置。 ```sql SELECT pg_relation_filepath('tb1'); -- 或者基于已知OID SELECT pg_relation_filepath(32896); ``` 这里假设 `tb1` 已经存在,并且我们知道它对应的是之前提到的那个具有 `oid=32896` 的实例[^4]。 --- #### 示例 5: 检查当前数据库内的锁定情况 当遇到性能瓶颈或者死锁等问题时,分析锁状态是非常重要的一步。下面的例子展示了如何依据给定数据库的名字过滤出相关的锁记录。 ```sql SELECT * FROM pg_locks l WHERE l.database = ( SELECT d.oid FROM pg_database d WHERE d.datname = 'your_database_name' ); ``` 这里的子查询部分负责检索指定名字 `'your_database_name'` 下面所属的数据库 ID (`oid`) ,从而缩小范围只显示属于这个特殊上下文中发生的任何加锁事件[^5]。 --- ### 总结 以上就是围绕 PostgreSQL 中的对象唯一标识符(`oid`) 及其同 `pg_class` 配套运用的一些典型例子说明。这些技巧可以帮助开发者更深入理解内部机制的同时也提供了实用工具去诊断问题或是优化设计架构等方面的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值