插入数据 ========= 在创建完一个表的时候,用户可以插入数据。 用户可以每次插入一行或多行。使用INSERT命令创建一个新行。 这条命令要求提供表名字以及列值。比如, 考虑来自 `表的基本概念 <./table-definition.html>`_ 的产品表: :: CREATE TABLE products ( product_no integer, name text, price numeric ); 下面是一个向表中插入一行的例子: :: INSERT INTO products VALUES (1, 'Cheese', 9.99); 数据值是按照这些列在表中出现的顺序列出的,并且用逗号分隔。通常,数据值是常量,但也允许使用标量表达式。 上述语法的缺点是你必须知道表中列的顺序。 你也可以明确地列出列名以避免这个问题。比如,下面的两条命令都和上面的那条命令效果相同: :: INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99); INSERT INTO products (name, price, product_no) VALUES ('Cheese', 9.99, 1); 许多用户认为明确列出列名是个好习惯。如果你不知道所有列的数值,那么可以省略其中的一些。这时候,这些未知列将被填充为它们的缺省值。比如 :: INSERT INTO products (product_no, name) VALUES (1, 'Cheese'); INSERT INTO products VALUES (1, 'Cheese'); 第二种形式从左向右用给定的值尽可能多的填充列,剩余的填充缺省值。 为了保持清晰,你也可以对独立的列或者整个行明确使用缺省值: :: INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', DEFAULT); INSERT INTO products DEFAULT VALUES; .. note:: HORC和MAGMA格式的表均支持设置缺省值。 你可以在一条命令中插入多行: :: INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99), (2, 'Bread', 1.99), (3, 'Milk', 2.99); 当插入分区表的时候,用户可以直接插入父表。也可以直接插入特定的子表(注意,该子表必须是叶子表,也就是它没有再次分区)。当数据不符合要插入的分区的条件时,会报错。 .. tip:: 要一次插入大量数据,可以看看COPY命令,外部表导入等,详情请参考数据导入导出章节。 这些方法性能要优于INSERT语句。 INSERT只适用于插入少量的数据。 MAGMA表upsert优化 +++++++++++++++++ OushuDB 可以通过设置 magma_conflict_mode 这个 guc 值来控制唯一性约束的键插入重复值时的错误处理过程,有三种模式 * do_conflict: 事务终止,并报告出现的duplicate key错误(这也是默认模式下magma_conflict_mode的值) * do_nothing: 不写入该行,也不报错,事务中其余语句仍然正常继续执行 * do_replace: 插入的这行将覆盖原先的那行 下面举例说明: :: -- 创建一个拥有唯一索引的主键表 CREATE TABLE test(a int UNIQUE, b int); INSERT INTO test VALUES (1, 10); 测试do_conflict模式 :: -- 设置成do_conflict模式,遇到违反唯一性约束的错误会报错,并且事务终止 SET magma_conflict_mode = 'do_conflict'; -- 插入一个违反唯一性约束的数值 INSERT INTO test VALUES (1, 100); ERROR: duplicate key value violates unique constraint -- test表中数据仍不变 SELECT * FROM test; a | b ---+---- 1 | 10 (1 row) :: -- 设置成do_nothing模式,遇到违反唯一性约束的错误不报错,只不过不插入 SET magma_conflict_mode = 'do_nothing'; -- 插入一个违反唯一性约束的数值 INSERT INTO test VALUES (1, 100); INSERT 0 0 -- test表中数据仍不变 SELECT * FROM test; a | b ---+---- 1 | 10 (1 row) :: -- 设置成do_replace模式,遇到违反唯一性约束的错误的数值,就覆写 SET magma_conflict_mode = 'do_replace'; -- 插入一个违反唯一性约束的数值 INSERT INTO test VALUES (1, 100); INSERT 0 1 -- test表中对应行的数据已覆写 SELECT * FROM test; a | b ---+---- 1 | 100 (1 row)