账本数据库概述

背景信息

账本数据库融合了区块链思想,将用户操作记录至两种历史表中:用户历史表和全局区块表。当用户创建防篡改用户表时,系统将自动为该表添加一个hash列来保存每行数据的hash摘要信息,同时在blockchain模式下会创建一张用户历史表来记录对应用户表中每条数据的变更行为;而用户对防篡改用户表的一次修改行为将记录至全局区块表中。由于历史表具有只可追加不可修改的特点,因此历史表记录串联起来便形成了用户对防篡改用户表的修改历史。

用户历史表命名和结构如下:

表 1 用户历史表blockchain.__hist所包含的字段

字段名

类型

描述

rec_num

bigint

行级修改操作在历史表中的执行序号。

hash_ins

hash16

INSERT或UPDATE操作插入的数据行的hash值。

hash_del

hash16

DELETE或UPDATE操作删除的数据行的hash值。

pre_hash

hash32

当前用户历史表的数据整体摘要。

表 2 hash_ins与hash_del场景对应关系

-

hash_ins

hash_del

INSERT

(√) 插入行的hash值

DELETE

(√) 删除行的hash值。

UPDATE

(√) 新插入数据的hash值

(√) 删除前该行的hash值。

操作步骤

1.创建防篡改模式。

​ 例如,创建防篡改模式ledgernsp。

  1. openGauss=# CREATE SCHEMA ledgernsp WITH BLOCKCHAIN;

2.在防篡改模式下创建防篡改用户表。

​ 例如,创建防篡改用户表ledgernsp.usertable。

  1. openGauss=# CREATE TABLE ledgernsp.usertable(id int, name text);

​ 查看防篡改用户表结构及其对应的用户历史表结构。

  1. openGauss=# \d+ ledgernsp.usertable;
  2. openGauss=# \d+ blockchain.ledgernsp_usertable_hist;

​ 执行结果如下:

  1. openGauss=# \d+ ledgernsp.usertable;
  2. Table "ledgernsp.usertable"
  3. Column | Type | Modifiers | Storage | Stats target | Description
  4. --------+---------+-----------+----------+--------------+-------------
  5. id | integer | | plain | |
  6. name | text | | extended | |
  7. hash | hash16 | | plain | |
  8. Has OIDs: no
  9. Distribute By: HASH(id)
  10. Location Nodes: ALL DATANODES
  11. Options: orientation=row, compression=no
  12. History table name: ledgernsp_usertable_hist
  13. openGauss=# \d+ blockchain.ledgernsp_usertable_hist;
  14. Table "blockchain.ledgernsp_usertable_hist"
  15. Column | Type | Modifiers | Storage | Stats target | Description
  16. ----------+--------+-----------+---------+--------------+-------------
  17. rec_num | bigint | | plain | |
  18. hash_ins | hash16 | | plain | |
  19. hash_del | hash16 | | plain | |
  20. pre_hash | hash32 | | plain | |
  21. Indexes:
  22. "gs_hist_16388_index" PRIMARY KEY, btree (rec_num int4_ops) TABLESPACE pg_default
  23. Has OIDs: no
  24. Distribute By: HASH(rec_num)
  25. Location Nodes: ALL DATANODES
  26. Options: internal_mask=263

账本数据库概述 - 图1 说明:

  • 防篡改表不支持非行存表、临时表、外表、unlog表、非行存表均无防篡改属性。
  • 防篡改表在创建时会自动增加一个名为hash的系统列,所以防篡改表单表最大列数为1599。

3.修改防篡改用户表数据。

例如,对防篡改用户表执行INSERT/UPDATE/DELETE。

  1. openGauss=# INSERT INTO ledgernsp.usertable VALUES(1, 'alex'), (2, 'bob'), (3, 'peter');
  2. INSERT 0 3
  3. openGauss=# SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
  4. id | name | hash
  5. ----+-------+------------------
  6. 1 | alex | 1f2e543c580cb8c5
  7. 2 | bob | 8fcd74a8a6a4b484
  8. 3 | peter | f51b4b1b12d0354b
  9. (3 rows)
  10. openGauss=# UPDATE ledgernsp.usertable SET name = 'bob2' WHERE id = 2;
  11. UPDATE 1
  12. openGauss=# SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
  13. id | name | hash
  14. ----+-------+------------------
  15. 1 | alex | 1f2e543c580cb8c5
  16. 2 | bob2 | 437761affbb7c605
  17. 3 | peter | f51b4b1b12d0354b
  18. (3 rows)
  19. openGauss=# SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
  20. id | name | hash
  21. ----+-------+------------------
  22. 1 | alex | 1f2e543c580cb8c5
  23. 2 | bob2 | 437761affbb7c605
  24. 3 | peter | f51b4b1b12d0354b
  25. (3 rows)
  26. openGauss=# DELETE FROM ledgernsp.usertable WHERE id = 3;
  27. DELETE 1
  28. openGauss=# SELECT *, hash FROM ledgernsp.usertable ORDER BY id;
  29. id | name | hash
  30. ----+------+------------------
  31. 1 | alex | 1f2e543c580cb8c5
  32. 2 | bob2 | 437761affbb7c605
  33. (2 rows)