每次vertica中有插入语句时如何覆盖表?
考虑:
INSERT INTO table1 VALUES ('My Value');
这会给说
| MyCol |
----------
MyValue
如何在下一个插入语句上覆盖同一个表说
INSERT INTO table1 VALUES ('My Value2');
| MyCol |
----------
MyValue2
如果它是一个单行表,那么正如@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.
使用单行表,这非常有效。不要为十亿行那样做。
你可以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;
我可能会建议你不要这样做。
最简单的方法是用一行填充表格,也许:
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;
如果视图变得低效,您可以定期清空表。
这种方法的一个优点是表永远不会为空并且不会长时间锁定——因此它通常是可用的。在这方面删除行和插入行可能会很棘手。
如果你真的喜欢触发器,你可以使用上面的表格。然后使用触发器更新具有单行的另一个表中的行。这也最大限度地提高了可用性,而无需获取最新值的开销。