什么是身份列?

Eva*_*oll 12 postgresql identity postgresql-10

我正在查看7/01为 PostgreSQL安排commit-fest,我看到 Pg 可能很快就会获得“身份列”。

我在information_schema.columns 中发现了一些提及但没什么

is_identity         yes_or_no         Applies to a feature not available in PostgreSQL
identity_generation character_data    Applies to a feature not available in PostgreSQL
identity_start      character_data    Applies to a feature not available in PostgreSQL
identity_increment  character_data    Applies to a feature not available in PostgreSQL
identity_maximum    character_data    Applies to a feature not available in PostgreSQL
identity_minimum    character_data    Applies to a feature not available in PostgreSQL
identity_cycle      yes_or_no         Applies to a feature not available in PostgreSQL
Run Code Online (Sandbox Code Playgroud)

维基百科页面也没有说太多

标识列与主键的不同之处在于它的值由服务器管理并且通常不能修改。在许多情况下,标识列用作主键;然而,这并非总是如此。

但是,我在他们身上看不到任何其他东西。标识列如何工作?它们是否提供任何新功能,或者这只是创建序列的标准方法?新功能的任何细分及其工作原理?

ype*_*eᵀᴹ 26

这是为了实现标准中的功能。(抄自草稿,日期:2011-12-21):

4.15.11标识列

基表 BT 的列可以选择包含不超过一个标识列。例如,标识列的声明类型是标度为 0(零)的精确数字类型INTEGER,或者其源类型是标度为 0(零)的精确数字类型的不同类型。标识列具有起始值、增量、最大值、最小值和循环选项。 ……
标识列的定义可以指定GENERATED ALWAYSGENERATED BY DEFAULT

它是列的一个属性,它基本上表示的值将由 DBMS 而不是由用户提供,并以某种特定的方式和限制(增加、减少、具有最大值/最小值、如果最大值/达到最小值)。

序列生成器(通常简称为“序列”)是相关的 SQL 标准功能:它是一种提供此类值的机制 - 并可用于标识列。

请注意细微的差别:aSEQUENCE是一个对象,可用于为一个或多个标识列提供值,甚至可以随意使用。


迄今为止,各种 DBMS 已经以不同的方式和语法(MySQL: AUTO_INCREMENT、SQL Server: IDENTITY (seed, increment)、PostgreSQL: serialusing SEQUENCE、Oracle:使用触发器等)实现了类似的功能,并且最近才添加了序列生成器(SQL Server 2012 版和 Oracle 12c) .

截至目前Postgres的已经实施序列发生器(可用于为列提供值,或者与特殊宏serialbigserialnextval()功能),但尚未实施了标识列的语法,因为它是标准。

定义标识列(从细微的差别serial列)和各种语法(例如GENERATED ALWAYSNEXT VALUE FOR从SQL标准等)是这一功能是什么。可能还需要对序列的实现进行一些更改/改进,因为标识列将使用序列。

如果您遵循链接标识列(从您看到的页面),您会发现:

身份列

发件人:Peter Eisentraut
收件人:pgsql-hackers 主题:身份列
日期:2016-08-31 04:00:42
消息 ID:6adbacbf-73bc-dd1a-2033-63409180fd18@2ndquadrant.com


这是实现标识列的另一种尝试。这是 PostgreSQL 串行列的符合标准的变体。它还修复了串行列具有的一些可用性问题:

  • 除了表(*)之外,还需要对序列设置权限
  • CREATE TABLE/LIKE复制默认但引用相同的序列
  • 无法添加/删除序列性 ALTER TABLE
  • 丢弃默认值不丢弃序列
  • 有点奇怪,因为串行是某种特殊的宏

(*) 还没有真正实现,因为我想利用NEXT VALUE FOR我之前发布的 东西,但我有更多的工作要做。

...

2017 年 9 月更新:似乎该功能将在 Postgres 10 中出现,它将在几天/几周内发布: Postgres 10 的新功能:身份列


Oracle 还在版本 12c 中实现了标识列和序列。据我检查,语法符合标准:
Oracle Database 12c Release 1 (12.1) 中的身份列

12c 数据库引入了针对使用数字类型定义的表列定义标识子句的功能。语法如下所示。

GENERATED
[ ALWAYS | BY DEFAULT [ ON NULL ] ]
AS IDENTITY [ ( identity_options ) ]
Run Code Online (Sandbox Code Playgroud)


Eva*_*oll 7

它们是如何在 PG 10 中实际实现的

您现在可以使用测试套件的预期输出查看它们是如何实际实现的。

一些关键要从这里拿走。

  • 您可以使用表创建或通过的子句指定从哪里开始以及跳过多少ALTER TABLESTART 7 INCREMENT BY 5

  • 插入具有标识列的表现在可以OVERRIDING USER VALUE用于强制替换冲突行的标识列:

    INSERT INTO t OVERRIDING USER VALUE VALUES (10, 'xyz');
    
    -- this isn't currently allowed.
    CREATE TABLE t ( a serial PRIMARY KEY, b text );
    INSERT INTO t (a,b) VALUES (1,'foo');
    INSERT INTO t (a,b) VALUES (1,'bar');
    
    Run Code Online (Sandbox Code Playgroud)
  • 您可以指定GENERATED ALWAYS以确保生成,然后您只需要OVERRIDING SYSTEM VALUE忽略它,否则当您INSERT为标识列指定值的行时,您将收到错误。

    ERROR:  cannot insert into column "a"
    DETAIL:  Column "a" is an identity column defined as GENERATED ALWAYS.
    HINT:  Use OVERRIDING SYSTEM VALUE to override.
    
    Run Code Online (Sandbox Code Playgroud)
  • 标识列必须是 NOT NULL

  • 权限从表中传播,没有更多的底层序列。

  • 身份可以在不同的点完全重置 RESTART

您可以在 PostgreSQL 10 文档中阅读有关这些的更多信息