Postgresql - `serial`专栏&继承(序列共享政策)

时间:2016-05-16 10:34:04

标签: postgresql inheritance

在postgresql中,当从父表继承serial列时,序列由父&儿童餐桌。

是否可以继承serial列,同时让2表具有分隔的序列值,例如两个表的列都可以具有值1

这是可能的吗?合理的,如果是的话,怎么做?

@Update

我想避免序列共享的原因是:

    1. 通过多个表共享单个int范围可能会耗尽 MAX_INT,使用bigint可以改善这一点,但需要更多空间 太
    1. 当多个表同时进行插入时会有一种资源锁定,所以我猜这是一个性能问题。
    1. id从1跳到5然后可能会变成1000看起来不那么漂亮。

@Summary

解决方案

  • 如果想要子表有自己的序列,同时仍然保持父和子之间的全局序列;儿童表。 (如[{1}}的回答中所述。

    然后可以为每个子表添加@wildplasser列。

  • 如果想要子表有自己的序列,而不需要父和子之间的全局序列。子表,

    有两种方式:

    1. 使用sub_id serial代替int。 (如[{1}}的回答中所述。

      步骤:

      • 在父表中将type定义为int或bigint,
      • 为每个父母和&子表,创建一个单独的序列,
      • 使用自己序列的nextval为每个表指定int类型的默认值, 在重新创建表时,不要忘记维护/重置序列,
    2. 直接在子表中定义serial,而不是在父表中定义。

2 个答案:

答案 0 :(得分:2)

DROP schema tmp CASCADE;
CREATE schema tmp;
set search_path = tmp, pg_catalog;

CREATE TABLE common
        ( seq SERIAL NOT NULL PRIMARY KEY
        );

CREATE TABLE one
        ( subseq SERIAL NOT NULL
        , payload integer NOT NULL
        )
        INHERITS (tmp.common)
        ;

CREATE TABLE two
        ( subseq SERIAL NOT NULL
        , payload integer NOT NULL
        )
        INHERITS (tmp.common)
        ;

/**
\d common
\d one
\d two
\q
***/

INSERT INTO one(payload)
SELECT gs FROM generate_series(1,5) gs
        ;

INSERT INTO two(payload)
SELECT gs FROM generate_series(101,105) gs
        ;

SELECT * FROM common;
SELECT * FROM one;
SELECT * FROM two;

结果:

NOTICE:  drop cascades to table tmp.common
DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
CREATE TABLE
CREATE TABLE
INSERT 0 5
INSERT 0 5
 seq 
-----
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
(10 rows)

 seq | subseq | payload 
-----+--------+---------
   1 |      1 |       1
   2 |      2 |       2
   3 |      3 |       3
   4 |      4 |       4
   5 |      5 |       5
(5 rows)

 seq | subseq | payload 
-----+--------+---------
   6 |      1 |     101
   7 |      2 |     102
   8 |      3 |     103
   9 |      4 |     104
  10 |      5 |     105
(5 rows)

但是:实际上你不需要subseq列,因为你总是可以通过row_number()来枚举它们:

CREATE VIEW vw_one AS
SELECT seq
        , row_number() OVER (ORDER BY seq) as subseq
        , payload
FROM one;

CREATE VIEW vw_two AS
SELECT seq
        , row_number() OVER (ORDER BY seq) as subseq
        , payload
FROM two;

[结果相同]

并且,您可以向子表添加UNIQUE AND PRIMARY KEY约束,例如:

CREATE TABLE one
        ( subseq SERIAL NOT NULL UNIQUE
        , payload integer NOT NULL
        )
        INHERITS (tmp.common)
        ;    
ALTER TABLE one ADD PRIMARY KEY (seq);

[类似于表二]

答案 1 :(得分:1)

我用这个:

Parent table definition:

CREATE TABLE parent_table (
  id bigint NOT NULL,


Child table definition:


CREATE TABLE cild_schema.child_table
(
  id bigint NOT NULL DEFAULT nextval('child_schema.child_table_id_seq'::regclass),

我通过使用序列号作为默认值来模拟序列号。