Sql 使用串行主键列安全地重命名表

Sql 使用串行主键列安全地重命名表,sql,postgresql,database-design,ddl,Sql,Postgresql,Database Design,Ddl,我知道,使用串行主键的PostgreSQL表最终由PostgreSQL创建了一个隐式索引、序列和约束。问题是在重命名表时如何重命名这些隐式对象。下面是我在最后用具体问题来解决这个问题的尝试 给出如下表格: CREATE TABLE foo ( pkey SERIAL PRIMARY KEY, value INTEGER ); 研究生产出: 注意:CREATE TABLE将为序列列“foo.pkey”创建隐式序列“foo_pkey_seq” 注意:CREATE TABLE/主键将

我知道,使用
串行
主键的PostgreSQL表最终由PostgreSQL创建了一个隐式索引、序列和约束。问题是在重命名表时如何重命名这些隐式对象。下面是我在最后用具体问题来解决这个问题的尝试

给出如下表格:

CREATE TABLE foo (
    pkey SERIAL PRIMARY KEY,
    value INTEGER
);
研究生产出:

注意:CREATE TABLE将为序列列“foo.pkey”创建隐式序列“foo_pkey_seq”
注意:CREATE TABLE/主键将为表“foo”创建隐式索引“foo_pkey”
查询已成功返回,52毫秒内没有结果

pgAdmin III SQL窗格显示表的以下DDL脚本(已分离):

现在重命名该表:

ALTER table foo RENAME TO bar;
查询已成功返回,17毫秒内没有结果

pgAdmin III:

CREATE TABLE bar (
  pkey integer NOT NULL DEFAULT nextval('foo_pkey_seq'::regclass),
  value integer,
  CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
CREATE TABLE bar (
  pkey serial NOT NULL,
  value integer,
  CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
注意额外的
默认nextval('foo\u pkey\u seq'::regclass),
这意味着重命名表不会重命名主键的序列,但现在我们有了这个显式的
nextval()

现在重命名序列:

ALTER table foo RENAME TO bar;
我想保持数据库命名的一致性,因此我尝试:

ALTER SEQUENCE foo_pkey_seq RENAME TO bar_pkey_seq;
查询已成功返回,17毫秒内没有结果

pgAdmin III:

CREATE TABLE bar (
  pkey integer NOT NULL DEFAULT nextval('foo_pkey_seq'::regclass),
  value integer,
  CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
CREATE TABLE bar (
  pkey serial NOT NULL,
  value integer,
  CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
默认的nextval('foo_pkey_seq'::regclass)已消失

问题
  • 为什么默认的nextval('foo_pkey_seq':regclass)语句出现和消失
  • 是否有方法重命名表,同时重命名主键序列
  • 当客户端连接到数据库时,重命名表然后排序是否安全?是否存在任何并发问题
  • 博士后如何知道使用哪个序列?是否有内部使用的数据库触发器?除了表和序列,还有什么需要重命名的吗
  • 那么由主键创建的隐式索引呢?应该改名吗?如果是的话,如何做到这一点
  • 上面的约束名称是什么?它仍然是
    foo\u pkey
    。约束如何重命名

  • serial
    不是实际的数据类型:

    数据类型
    smallserial
    serial
    bigserial
    不是真正的类型, 但这仅仅是创建唯一标识符列的一种符号方便

    通过执行以下所有操作来解析伪数据类型:

    • 创建名为
      tablename\u colname\u seq的序列

    • 创建类型为
      integer
      (或
      int2
      /
      int8
      的列,分别用于
      smallserial
      /
      bigserial

    • 将列
      设为非空默认值nextval('tablename\u colname\u seq')

    • 使列拥有序列,以便自动删除它

    系统不知道您是手动还是通过伪数据类型
    serial
    完成所有这些操作。pgAdmin检查列出的功能,如果满足所有要求,则使用匹配的
    serial
    类型简化反向工程DDL脚本。如果不满足其中一个特征,则不会进行此简化。这是pgAdmin所做的。对于基础目录表,这一切都是一样的。不存在类似的
    串行
    类型

    无法自动重命名拥有的序列。您可以运行:

    ALTER SEQUENCE ... RENAME TO ...
    
    就像你那样。系统本身并不关心名称。列
    DEFAULT
    存储一个(
    'foo\u pkey\u seq'::regclass
    ),您可以更改序列的名称而不中断该名称-OID保持不变。数据库中的外键和类似引用也是如此

    主键的隐式索引绑定到PK约束的名称,如果更改表的名称,该名称将不会更改

    也要纠正这一点

    还可以引用表名命名索引:

    可以对表名进行各种非正式引用。系统无法强制重命名可以随意命名的对象。它不在乎

    当然,您不希望使引用这些名称的SQL代码无效。显然,当应用程序逻辑引用名称时,您不想更改名称。通常情况下,索引、序列或约束的名称不会有问题,因为它们通常不被名称引用

    Postgres还可以在重命名对象之前获得对象的锁定。因此,如果有并发事务处于打开状态,并且对所讨论的对象有任何类型的锁定,则您的
    重命名
    操作将暂停,直到这些事务提交或回滚

    系统目录和OID 数据库架构存储在系统架构
    pg_catalog
    中的系统目录表中。如果你不知道自己在做什么,你就不应该把那些桌子弄得乱七八糟。一个错误的移动,你可以打破你的数据库

    对于一些最重要的表,Postgres提供并键入cast以获取OID的名称,反之亦然。比如:

    SELECT 'foo_pkey_seq'::regclass
    
    如果架构名称位于
    搜索路径中,并且表名称是唯一的,则给出的结果与:

    SELECT oid FROM pg_class WHERE relname = 'foo_pkey_seq';
    

    大多数目录表的主键是oid,在内部,大多数引用都使用oid。

    我猜想命名序列具有神奇的语法意义,Postgres知道使用一个所谓的序列作为表的主键序列,而不显式地将其作为表的主键列的默认值列出。不过,我并不知道这一点,也没有任何证据。如果这个问题到那时还没有答案,我们将在下班后进一步调查。“ALTER TABLE…RENAME CONSTRAINT…”需要PostgreSQL 9.2+可能会有所帮助