• 沒有找到結果。

4.4.1 创建表

背景信息

表是建立在数据库中的,在不同的数据库中可以存放相同的表。甚至可以通过使用模 式在同一个数据库中创建相同名称的表。创建表前请先规划存储模型。

创建表

执行如下命令创建表。

CREATE TABLE customer_t1 ( c_customer_sk integer, c_customer_id char(5), c_first_name char(6), c_last_name char(8)

)with (orientation = column,compression=middle) distribute by hash (c_last_name);

当结果显示为如下信息,则表示创建成功。

CREATE TABLE

其中c_customer_sk 、c_customer_id、c_first_name和c_last_name是表的字段名,

integer、char(5)、char(6)和char(8)分别是这四字段名称的类型。

4.4.2 向表中插入数据

在创建一个表后,表中并没有数据,在使用这个表之前,需要向表中插入数据。本小 节介绍如何使用INSERT命令插入一行或多行数据,及从指定表插入数据。如果有大量 数据需要批量导入表中,请参考导入方式说明。

背景信息

服务端与客户端使用不同的字符集时,两者字符集中单个字符的长度也会不同,客户 端输入的字符串会以服务端字符集的格式进行处理,所以产生的最终结果可能会与预 期不一致。

4-1 客户端和服务端设置字符集的输出结果对比

操作过程 服务端和客户端编码一致 服务端和客户端编码不一致 存入和取出过程中没有

对字符串进行操作

输出预期结果 输出预期结果(输入与显示 的客户端编码必须一致)。

存入取出过程对字符串 有做一定的操作(如字

输出预期结果 根据对字符串具体操作可能 产生非预期结果。

操作过程 服务端和客户端编码一致 服务端和客户端编码不一致

CREATE TABLE table1(id int, a char(6), b varchar(6),c varchar(6)) ; CREATE TABLE table2(id int, a char(20), b varchar(20),c varchar(20)) ;

4-2 示例

ASCII UTF8 是 INSERT INTO table1 VALUES(1,reverse('12

ASCII UTF8 是 INSERT INTO table1 VALUES(2,reverse('12

ASCII UTF8 是 INSERT INTO table1 VALUES(3,'87A

ASCII UTF8 否 INSERT INTO table2 VALUES(1,reverse('12

INSERT INTO customer_t1(c_customer_sk, c_customer_id, c_first_name) VALUES (3769, 'hello', 'Grace');

如果用户已经知道表中字段的顺序,也可无需列出表中的字段。例如以下命令与 上面的命令效果相同。

INSERT INTO customer_t1 VALUES (3769, 'hello', 'Grace');

如果用户不知道所有字段的数值,可以忽略其中的一些。没有数值的字段将被填 充为字段的缺省值。例如:

INSERT INTO customer_t1 (c_customer_sk, c_first_name) VALUES (3769, 'Grace');

INSERT INTO customer_t1 VALUES (3769, 'hello');

用户也可以对独立的字段或者整个行明确缺省值:

INSERT INTO customer_t1 (c_customer_sk, c_customer_id, c_first_name) VALUES (3769, 'hello', DEFAULT);

INSERT INTO customer_t1 DEFAULT VALUES;

● 如果需要在表中插入多行,请使用以下命令:

INSERT INTO customer_t1 (c_customer_sk, c_customer_id, c_first_name) VALUES (6885, 'maps', 'Joes'),

说明

从指定表插入数据到当前表时,若指定表与当前表对应的字段数据类型之间不存在隐式转 换,则这两种数据类型必须相同。

● 删除备份表

DROP TABLE customer_t2 CASCADE;

说明

在删除表的时候,若当前需删除的表与其他表有依赖关系,需先删除关联的表,然后再删 除当前表。

4.4.3 更新表中数据

修改已经存储在数据库中数据的行为叫做更新。用户可以更新单独一行,所有行或者 指定的部分行。还可以独立更新每个字段,而其他字段则不受影响。

使用UPDATE命令更新现有行,需要提供以下三种信息:

● 表的名字和要更新的字段名

● 字段的新值

● 要更新哪些行 说明

● 表名字也可以使用模式名修饰,否则会从默认的模式路径找到这个表。

● SET后面紧跟字段和新的字段值。新的字段值不仅可以是常量,也可以是变量表达式。

● 表中可以含WHERE子句,且是等值测试。

如果省略了WHERE子句,表示表中的所有行都要被更新。

如果出现了WHERE子句,只有匹配其条件的行才会被更新。

在SET子句中的等号是一个赋值,而在WHERE子句中的等号是比较。WHERE条件也可 以是不相等测试,许多其他的操作符也可以使用。

SQL通常不会为数据行提供唯一标识,因此无法直接声明需要更新哪一行。但是可以 通过声明一个被更新的行必须满足的条件。只有在表里存在主键的时候,才可以通过 主键指定一个独立的行。

建立表和插入数据的步骤请参考创建表和向表中插入数据。

更新表中数据具体示例如下:

● 需要将表customer_t1中c_customer_sk为9527的地域重新定义为9876:

UPDATE customer_t1 SET c_customer_sk = 9876 WHERE c_customer_sk = 9527;

● 需要将表customer_t1中c_customer_sk为9527的地域重新定义为c_customer_sk + 100:

UPDATE customer_t1 SET c_customer_sk= c_customer_sk + 100 WHERE c_customer_sk= 9527;

● 需要将Public模式下表customer_t1中c_customer_sk为9527的地域重新定义为 9876:

UPDATE public.customer_t1 SET c_customer_sk= 9876 WHERE c_customer_sk= 9527;

● 不含WHERE子句表示把所有c_customer_sk的值增加100:

UPDATE customer_t1 SET c_customer_sk = c_customer_sk + 100;

● 需要将表customer_t1中c_customer_sk大于9527的地域全部重新定义为9876:

UPDATE customer_t1 SET c_customer_sk = 9876 WHERE c_customer_sk > 9527;

● 用户可以在一个UPDATE命令中更新更多的字段,方法是在SET子句中列出更多赋 值,比如:

UPDATE customer_t1 SET c_customer_id = 'Admin', c_first_name = 'Local' WHERE c_customer_sk = 4421;

批量更新或删除数据后,会在数据文件中产生大量的删除标记,查询过程中标记删除 的数据也是需要扫描的。故多次批量更新/删除后,标记删除的数据量过大会严重影响 查询的性能。建议在批量更新/删除业务会反复执行的场景下,定期执行VACUUM FULL以保持查询性能。

4.4.4 查看数据

● 使用系统表pg_tables查询数据库所有表的信息。

SELECT * FROM pg_tables;

● 使用gsql的\d+命令查询表的属性。

\d+ customer_t1;

● 执行如下命令查询表customer_t1的数据量。

SELECT count(*) FROM customer_t1;

● 执行如下命令查询表customer_t1的所有数据。

SELECT * FROM customer_t1;

● 执行如下命令只查询字段c_customer_sk的数据。

SELECT c_customer_sk FROM customer_t1;

● 执行如下命令过滤字段c_customer_sk的重复数据。

SELECT DISTINCT( c_customer_sk ) FROM customer_t1;

● 执行如下命令查询字段c_customer_sk为3869的所有数据。

SELECT * FROM customer_t1 WHERE c_customer_sk = 3869;

● 执行如下命令按照字段c_customer_sk进行排序。

SELECT * FROM customer_t1 ORDER BY c_customer_sk;

如果要取消运行时间过长的查询,请参考查看系统表的“查看和停止正在运行的 查询语句”。

4.4.5 删除表中数据

在使用表的过程中,可能会需要删除已过期的数据,删除数据必须从表中整行的删 除。

SQL不能直接访问独立的行,只能通过声明被删除行匹配的条件进行。如果表中有一 个主键,用户可以指定准确的行。用户可以删除匹配条件的一组行或者一次删除表中 的所有行。

使用DELETE命令删除行,如果删除表customer_t1中所有c_customer_sk为3869的记 录:

DELETE FROM customer_t1 WHERE c_customer_sk = 3869;

如果执行如下命令,会删除表中所有的行。

DELETE FROM customer_t1;

TRUNCATE TABLE customer_t1;

说明

全表删除的场景下,建议使用truncate,不建议使用delete。

删除创建的表:

相關文件