【问题标题】:Add AUTO INCREMENT or IDENTITY to existing table in Vertica将 AUTO INCREMENT 或 IDENTITY 添加到 Vertica 中的现有表
【发布时间】:2018-11-20 15:42:47
【问题描述】:

我有一个现有的带有自动递增列的 postgresql 数据库,我想将其迁移到 Vertica。在 Vertica 中,我可以创建具有 IDENTITY 或 AUTO INCREMENT 约束(或数据类型?)的表,但我无法将这些约束添加到包含现有数据的列中。类似问题here 的答案是使用序列的解决方法,这不是一个选项,因为允许重复数字并且可能存在多个节点之间的竞争条件,这由 IDENTITY 实现处理。也不能选择使用 IDENTITY 列创建表,因为不允许插入。

简而言之,我想在现有数据上有一个 IDENTITY 列,同时也是主键。

【问题讨论】:

  • 如果不插入表格,为什么不直接使用row_number()
  • 我希望能够将旧数据插入表中。并将其转换为身份,以便能够使新插入自动递增。 Row_number 与旧表中的唯一 ID 不同。
  • 看看这个数据库变量CopyFromVerticaWithIdentity。您可能需要更改此设置以启用 IDENTITY 中的加载
  • 我不明白这应该如何帮助从 POSTGRESQL 复制数据?

标签: sql auto-increment identity vertica alter-table


【解决方案1】:

您的问题将是您需要在 Vertica 中的副本中为原始 IDENTITY 列具有相同的值 - 同时能够对您现在可能插入新表中的任何新行具有 AUTOINCREMENT 行为。

这可以通过让 Vertica 目标代理键不作为 IDENTITY 而是作为 INT NOT NULL 来实现,而是从手动创建的序列的 nextval 方法中给它一个 DEFAULT。

你有这个表,这个数据(可以来自任何源数据库......),其中包含一个 IDENTITY 列。

-- source (could be from anywhere - why not on my own Vertica sandbox)                                                                                      
CREATE TABLE src (
  src_id     IDENTITY NOT NULL
, first_name VARCHAR(32)
, last_name  VARCHAR(32)
, hire_dt    DATE
) UNSEGMENTED ALL NODES
;

INSERT /*+ DIRECT */ INTO src(first_name,last_name,hire_dt)
          SELECT 'Ford','Prefect',DATE '2017-02-05'
UNION ALL SELECT 'Svlad','Cjelli',DATE '2017-02-05'
UNION ALL SELECT 'Cynthia','Fitzmelton',DATE '2017-02-05'
UNION ALL SELECT 'Stavro','Mueller',DATE '2017-02-05'
UNION ALL SELECT 'Veet','Voojagig',DATE '2017-02-05'
UNION ALL SELECT 'Trin','Tragula',DATE '2017-02-05'
UNION ALL SELECT 'Zarniwoop','Zarniwoop',DATE '2017-02-05'
UNION ALL SELECT 'Rob','McKenna',DATE '2017-02-05'
UNION ALL SELECT 'The Lajestic Vantrashell','of Lob',DATE '2017-02-05'
UNION ALL SELECT 'Paul Neil Milne','Johnston',DATE '2017-02-05'
UNION ALL SELECT 'Lunkwill','Lunkwill',DATE '2017-02-05'
UNION ALL SELECT 'Arthur','Dent',DATE '2017-02-05'
UNION ALL SELECT 'Zaphod','Beeblebrox',DATE '2017-02-05'
UNION ALL SELECT 'Tricia','McMillan',DATE '2017-02-05'
UNION ALL SELECT 'Prostetnic Vogon','Jeltz',DATE '2017-02-05'
UNION ALL SELECT 'Lionel','Prosser',DATE '2017-02-05'
UNION ALL SELECT 'Karl','Mueller',DATE '2017-02-05'
UNION ALL SELECT 'Hotblack','Desiato',DATE '2017-02-05'
UNION ALL SELECT 'Gogrilla','Mincefriend',DATE '2017-02-05'
UNION ALL SELECT 'Slartibartfast','Slartibartfast',DATE '2017-02-05'
UNION ALL SELECT 'Roosta','Roosta',DATE '2017-02-05'
UNION ALL SELECT 'Eccentrica','Gallumbitis',DATE '2017-02-05'
UNION ALL SELECT 'Pizpot','Gargravarr',DATE '2017-02-05'
UNION ALL SELECT 'Vroomfondel','Vroomfondel',DATE '2017-02-05'
UNION ALL SELECT 'Majikthise','Majikthise',DATE '2017-02-05'
UNION ALL SELECT 'Gengis Temüjin','Khan',DATE '2017-02-05'
UNION ALL SELECT 'Know-Nothing-Bozo','the Non-Wonder Dog',DATE '2017-02-05'
UNION ALL SELECT 'Lazlaar','Lyricon',DATE '2017-02-05'
UNION ALL SELECT 'Lintilla','Lintilla',DATE '2017-02-05'
UNION ALL SELECT 'Fook','Fook',DATE '2017-02-05'
UNION ALL SELECT 'Gag','Halfrunt',DATE '2017-02-05'
UNION ALL SELECT 'Benji','Mouse',DATE '2017-02-05'
UNION ALL SELECT 'Frankie','Mouse',DATE '2017-02-05'
UNION ALL SELECT 'Grunthos','the Flatulent',DATE '2017-02-05'
UNION ALL SELECT 'Wowbagger','The Infinitely Prolonged',DATE '2017-02-05'
UNION ALL SELECT 'Wonko','The Sane',DATE '2017-02-05'
UNION ALL SELECT 'Reg','Nullify',DATE '2017-02-05'
UNION ALL SELECT 'Fenchurch','of Rickmansworth',DATE '2017-02-05'
UNION ALL SELECT 'Oolon','Colluphid',DATE '2017-02-05'
UNION ALL SELECT 'Humma','Kavula',DATE '2017-02-05'
UNION ALL SELECT 'Judiciary','Pag',DATE '2017-02-05'
UNION ALL SELECT 'Max','Quordlepleen',DATE '2017-02-05'
;

从该源表中,您确定当前发出的最高 IDENTITY 值:

SQL>select max(src_id) from src;
max
 42

在目标 Vertica 数据库中,您使用该值创建一个全新的手动序列...

CREATE SEQUENCE seq_copy MINVALUE 43;

根据给定的输入值(您将在 INSERT ... SELECT 或 COPY 命令中提供)或新创建的序列的 nextval 来创建具有代理 ID 的目标表:

CREATE TABLE cpy (
  cpy_id     INT NOT NULL DEFAULT(seq_copy.nextval)
, first_name VARCHAR(32)
, last_name  VARCHAR(32)
, hire_dt    DATE
) UNSEGMENTED ALL NODES
;

然后,如果您指定所有列(或根本不指定)

在插入...

INSERT INTO cpy (
  cpy_id
, first_name
, last_name
, hire_dt
)
SELECT * FROM src;

.. 或复制...

COPY cpy (cpy_id,first_name,last_name,hire_dt) 
  FROM LOCAL 'src.csv' DELIMITER ',' ENCLOSED BY '''' ;

...您使用源中的值。

而且如果你插入一个新值,你就不会碰代理键...

INSERT INTO cpy (
  first_name
, last_name
, hire_dt
) VALUES (
  'Thor'
, 'son of Odin'
, '2000-01-01'
;

... 代理键将为您填充。

这就是你所追求的吗?

马可

【讨论】:

  • 我不确定序列是否在 IDENTITY 每个节点都有一些缓存的多节点环境中按预期工作。你有这方面的信息吗?
  • 绝对。默认情况下,(您可以配置不同),序列缓存在节点 1 上从 0 开始,在节点 2 上从 250,000 开始,等等。在每个新会话中,缓存将从每个节点 250,000 的不同新倍数。这有帮助吗?
  • 是的。谢谢你。我将此标记为答案。
  • 关于序列的最后插入 id 的后续问题是 stackoverflow.com/questions/51597088/…
猜你喜欢
  • 1970-01-01
  • 2015-08-03
  • 2022-10-05
  • 2017-05-03
  • 1970-01-01
  • 2022-12-19
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
相关资源
最近更新 更多