在Trafodion中,一个重要的概念叫“聚集键”,“聚集键”是定义了Trafodion按哪一个字段或几个字段顺序存储。“聚集键”一般使用PRIMARY KEY(a,b,c)或STORE BY(a,b,c)语法定义,PRIMARY KEY与STORE BY唯一的区别在于是否具有行唯一性。
“聚集键”经过一定的编码转换后对应HBase的ROWKEY,“聚集键”是唯一的。如果表上定义了PK,那么PK的唯一性保证了“聚集键”的唯一性,如果表上没有定义PK,那么系统会自动在表上添加一个“SYSKEY”,用于保证行的唯一性。
下面例子分别创建两个表Table_a和Table_b,其中Table_a有主键,而Table_b没有,用INVOKE命令可以查看到Table_b上自动创建一个SYSKEY的隐藏列,它具有行唯一性。
>>create table table_a(a int not null, b int) primary key (a);
--- SQL operation complete.
>>create table table_b(a int not null, b int) store by (a);
--- SQL operation complete.
>>invoke table_a;
-- Definition of Trafodion table TRAFODION.SEABASE.TABLE_A
-- Definition current Fri Jun 16 12:02:55 2017
(
A INT NO DEFAULT NOT NULL NOT DROPPABLE NOT
SERIALIZED
, B INT DEFAULT NULL NOT SERIALIZED
)
PRIMARY KEY (A ASC)
--- SQL operation complete.
>>invoke table_b;
-- Definition of Trafodion table TRAFODION.SEABASE.TABLE_B
-- Definition current Fri Jun 16 12:03:01 2017
(
SYSKEY LARGEINT NO DEFAULT NOT NULL NOT DROPPABLE
NOT SERIALIZED
, A INT NO DEFAULT NOT NULL NOT DROPPABLE NOT
SERIALIZED
, B INT DEFAULT NULL NOT SERIALIZED
)
--- SQL operation complete.
由于Table_a具有主键,主键约束保证了无法插入两个相同的行,而Table_b没有主键,虽然可以通过SYSKEY隐藏列来保证每一行是唯一的,但存储在表中的用户数据是无法保证唯一的。
>>insert into table_a values(1,2),(1,2),(1,3);
*** ERROR[8102] The operation is prevented by a unique constraint.
--- 0 row(s) inserted.
>>insert into table_b values(1,2),(1,2),(1,3);
--- 3 row(s) inserted.
>>select * from table_a;
--- 0 row(s) selected.
>>select * from table_b;
A B
----------- -----------
1 2
1 2
1 3
--- 3 row(s) selected.
现在,Table_b就有两条同样的数据了,那么现在的需求是删除重复记录。删除重复记录有多种方法,这里我们利用SYSKEY的唯一来删除重复记录,这有点类似于利用Oracle中的ROWID,如下
>>delete from table_b where syskey not in (select min(b.syskey) from table_b b group by b.a,b.b);
--- 1 row(s) deleted.
>>select * from table_b;
A B
----------- -----------
1 2
1 3
--- 2 row(s) selected.
另外,提醒一下,如果是要在大量数据集上做删除操作,默认的DELETE FROM性能可能会不好,关于删除数据过慢的问题,可以参考我的另外一篇博客:http://blog.csdn.net/post_yuan/article/details/70238828