多版本数据管理

本文介绍如何在Lindorm宽表SQL中通过HINT设置时间戳来实现多版本数据管理。

引擎与版本

HINT语法仅适用于宽表引擎,且引擎版本需为2.3.1及以上版本。

说明

如何查看或升级当前版本,请参见宽表引擎版本说明升级小版本

功能介绍

Lindorm宽表引擎中,写入每条数据时每列都会记录时间戳,该时间戳一般记录的是数据写入时的服务器时间。默认情况下,该时间戳会作为每列的版本标识,用户也可以在写入数据时自定义时间戳,时间戳越大说明数据的版本越新。如果宽表的列要存储多个版本的数据,需要在创建表时设置版本属性'VERSIONS' = 'n'(n为正整数,表示每列最多保留的版本数)。通过时间戳查询多版本的数据时需要指定多版本属性,多版本的相关属性如下表:

属性名称

说明

适用语句

_l_ts_(N)

自定义时间戳的值。

UPSERT、SELECT

_l_versions_(N)

表示查询结果中返回最新的N个版本的数据。

SELECT

_l_ts_min_(N)

用于过滤查询结果,表示查询结果中返回时间戳大于等于N的数据。

SELECT

_l_ts_max_(N)

用于过滤查询结果,表示查询结果中返回时间戳小于N的数据。

SELECT

使用方法

设置时间戳并查询数据

Lindorm宽表支持在非主键列中设置时间戳并通过时间戳查询指定版本的数据。

  1. 创建测试表,指定保留的版本数。语句如下:

    CREATE TABLE t_test_versions_2 (c1 INT , c2 INT, c3 VARCHAR(50), PRIMARY KEY(c1)) WITH(VERSIONS='5');
    说明

    您可以执行ALTER TABLE table_name SET 'VERSIONS' = 'num';语句为已创建的数据表指定或修改版本数,其中table_name为数据表名称,num为版本数。

  2. 写入数据。设置时间戳时需要指定多版本属性,语句如下:

    UPSERT /*+ _l_ts_(1000)  */ INTO t_test_versions_2(c1, c3) values (1, '11');
    UPSERT /*+ _l_ts_(2001)  */ INTO t_test_versions_2(c1, c3) values (1, '22');
    UPSERT /*+ _l_ts_(1000)  */ INTO t_test_versions_2(c1, c2) values (1, 1);
    UPSERT /*+ _l_ts_(2001)  */ INTO t_test_versions_2(c1, c2) values (2, 1);
    UPSERT /*+ _l_ts_(2002)  */ INTO t_test_versions_2(c1, c2) values (2, 2);
    UPSERT /*+ _l_ts_(2003)  */ INTO t_test_versions_2(c1, c2) values (2, 3);
    UPSERT /*+ _l_ts_(2004)  */ INTO t_test_versions_2(c1, c2) values (2, 4);
    UPSERT /*+ _l_ts_(2005)  */INTO t_test_versions_2(c1, c2) values (2, 5);
    UPSERT /*+ _l_ts_(2006)  */ INTO t_test_versions_2(c1, c2) values (2, 6);
  3. 通过时间戳查询指定版本的数据。如果要查看时间戳,需要在列名后加上时间戳后缀(即_l_ts)。

    • 示例一:返回指定时间戳为1000的数据。

      SELECT /*+ _l_ts_(1000) */ c1, c3, c3_l_ts FROM t_test_versions_2 WHERE c1 = 1;

      返回结果:

      +----+----+---------+
      | c1 | c3 | c3_l_ts |
      +----+----+---------+
      | 1  | 11 | 1000    |
      +----+----+---------+
    • 示例二:查询时间戳在[1000,2001)范围内的数据。

      SELECT /*+ _l_ts_min_(1000), _l_ts_max_(2001)  */ c1, c3, c3_l_ts FROM t_test_versions_2 WHERE c1 = 1;

      返回结果:

      +----+----+---------+
      | c1 | c3 | c3_l_ts |
      +----+----+---------+
      | 1  | 11 | 1000    |
      +----+----+---------+
    • 示例三:返回最新的N个版本的数据,需要指定_l_versions_(N)属性。

      SELECT /*+ _l_versions_(1) */ c1, c3, c3_l_ts FROM t_test_versions_2 WHERE c1 = 1;

      返回结果:

      +----+----+---------+
      | c1 | c3 | c3_l_ts |
      +----+----+---------+
      | 1  | 22 | 2001    |
      +----+----+---------+
    • 示例四:每列返回最新的两个版本数据,并且按照时间戳相同的列合并为一行返回结果集。查询语句中指定_l_versions_(N)属性会返回所有非主键列的时间戳数据。

      SELECT /*+ _l_versions_(2)  */ c1, c2, c3, c2_l_ts, c3_l_ts FROM t_test_versions_2;

      返回结果如下:

      +----+------+------+---------+---------+
      | c1 |  c2  |  c3  | c2_l_ts | c3_l_ts |
      +----+------+------+---------+---------+
      | 1  | null | 22   | null    | 2001    |
      | 1  | 1    | 11   | 1000    | 1000    |
      | 2  | 6    | null | 2006    | null    |
      | 2  | 5    | null | 2005    | null    |
      +----+------+------+---------+---------+
    • 示例五:由于创建表时设置版本属性仅保留5个版本的数据,所以尽管指定_l_versions_(6)属性也只能返回5个版本的数据。

      SELECT /*+ _l_versions_(6)  */ c1, c2, c2_l_ts FROM t_test_versions_2 WHERE c1=2;

      返回结果如下:

      +----+----+---------+
      | c1 | c2 | c2_l_ts |
      +----+----+---------+
      | 2  | 6  | 2006    |
      | 2  | 5  | 2005    |
      | 2  | 4  | 2004    |
      | 2  | 3  | 2003    |
      | 2  | 2  | 2002    |
      +----+----+---------+