0

每次vertica中有插入语句时如何覆盖表?

考虑:

INSERT INTO table1 VALUES ('My Value');

这会给说

| MyCol  |
----------
MyValue

如何在下一个插入语句上覆盖同一个表说

INSERT INTO table1 VALUES ('My Value2');

| MyCol  |
----------
MyValue2
4

3 回答 3

0

如果它是一个单行表,那么正如@Gordon Linoff所建议的那样,用可以为 NULL 的单行填充它是没有任何风险的。

在内部,您应该知道 Vertica 在后台始终将 UPDATE 实现为 DELETE,方法是为行添加删除向量,然后应用 INSERT。

单行表没有问题,作为 Tuple Mover(唤醒所有 5 分钟以对内部存储进行碎片整理的后台守护进程,简而言之,将创建单个数据(读取优化存储 - ROS)容器出:前一个值;指向该前一个值的删除向量,从而停用它,以及它更新到的新插入的值。所以:

CREATE TABLE table1 (
  mycol VARCHAR(16)
) UNSEGMENTED ALL NODES; -- a small table, replicate it across all nodes
-- now you have an empty table
-- for the following scenario, I assume you commit the changes every time, as other connected
-- processes will want to see the data you changed
-- then, only once:
INSERT INTO table1 VALUES(NULL::VARCHAR(16);
-- now, you get a ROS container for one row.
-- Later:
UPDATE table1 SET mycol='first value';
-- a DELETE vector is created to mark the initial "NULL" value as invalid
-- a new row is added to the ROS container with the value "first value"
-- Then, before 5 minutes have elapsed, you go:
UPDATE table1 SET mycol='second value';
-- another DELETE vector is created, in a new delete-vector-ROS-container, 
-- to mark "first value" as invalid
-- another new row is added to a new ROS container, containing "second value"
-- Now 5 minutes have elapsed since the start, the Tuple Mover sees there's work to do,
-- and:
-- - it reads the ROS containers containing "NULL" and "first value"
-- - it reads the delete-vector-ROS containers marking both "NULL" and "first value"
--    as invalid
-- - it reads the last ROS container containing "second value"
-- --> and it finally merges all into a brand new ROS container, to only contain.
--     "second value", and, at the end the four other ROS containers are deleted.

使用单行表,这非常有效。不要为十亿行那样做。

于 2020-08-13T13:45:48.320 回答
0

你可以DELETE或者TRUNCATE你的桌子。Vertica 没有覆盖方法。使用TRUNCATE,因为你只想要一个值。

资源

INSERT INTO table1 VALUES ('My Value');
TRUNCATE TABLE table1;
INSERT INTO table1 VALUES ('My Value2'); 

或者(如果在您提交之前连接丢失,则它不会生效。)

回滚

单个语句返回错误消息。在这种情况下,Vertica 回滚该语句。

DDL 错误、系统故障、死锁和资源限制都会返回 ROLLBACK 消息。在这种情况下,Vertica 会回滚整个事务。

INSERT INTO table1 VALUES ('My Value');
DELETE FROM table1
WHERE MyCol !='My Value2';
INSERT INTO table1 VALUES ('My Value2'); 
COMMIT;
于 2020-08-13T07:36:14.360 回答
0

我可能会建议你不要这样做。

最简单的方法是用一行填充表格,也许:

insert into table1 (value)
    values (null);

然后使用update,而不是insert

update table1
    set value = ?;

这解决了你的问题。

如果您坚持使用insert,您可以插入带有标识列的值并使用视图来获取最新值:

create table table1 (
    table1_id identity(1, 1),
    value varchar(255)
);

然后使用视图访问表:

create view v_table1 as
    select value
    from table1
    order by table1_id desc
    limit 1;

如果视图变得低效,您可以定期清空表。

这种方法的一个优点是表永远不会为空并且不会长时间锁定——因此它通常是可用的。在这方面删除行和插入行可能会很棘手。

如果你真的喜欢触发器,你可以使用上面的表格。然后使用触发器更新具有单行的另一个表中的行。这也最大限度地提高了可用性,而无需获取最新值的开销。

于 2020-08-13T12:06:04.537 回答