使用 python 进行 Bigtable 数据建模和查询

Bigtable data modeling and query with python

这是我第一次使用 BigTable 我不知道我是否不了解 bigtable 建模或如何使用 python 库。

我存储的一些背景信息:

我正在存储时间序列事件,假设有两列名称和消息,我的行键是“#200501163223”,所以行键包含这种格式的时间“%y%m%d%H%M%S”

假设稍后我需要添加另一个名为 "type" 的列。

另外,有可能同时发生两个事件。

所以这就是我存储 2 个事件的结果,第二个事件具有额外的 "type" 数据:


account#200501163223
  Outbox:name                               @ 2020/05/01-17:32:16.412000
    "name1"
  Outbox:name                               @ 2020/05/01-16:41:49.093000
    "name2"
  Outbox:message                            @ 2020/05/01-17:32:16.412000
    "msg1"
  Outbox:message                            @ 2020/05/01-16:41:49.093000
    "msg2"
  Outbox:type                               @ 2020/05/01-16:35:09.839000
    "temp"


当我使用 python bigtable 库查询此 rowkey 时,我得到了一个字典,其中列名作为键,数据作为 Cell 对象列表

"name" 和 "message" 键将有 2 个对象,而 "type" 将只有一个对象,因为它只是第二个事件的一部分。

我的问题是,我如何知道 "type" temp 值属于哪个事件,1 或 2?这个模型是不是错了,我必须确保只有一个事件可以存储在一个行键下,这很难做到……或者我在库中缺少一个能够相应地关联事件数据的技巧?

塔莎,这是一个很好的问题,我以前也遇到过,所以感谢你提出这个问题。

在 Bigtable 中,没有从同一个写入中连接列的概念。这对某些人非常有帮助,因为您可以灵活地处理各种列和版本,但在您的情况下,它会导致此问题。

处理此问题的最佳方法是分两步。

  1. 确保each time you write to a row您为该写入使用相同的时间戳。看起来像这样:

        timestamp = datetime.datetime.utcnow()
    
        row_key = "account#200501163223"
    
        row = table.direct_row(row_key)
        row.set_cell(column_family_id,
                     "name",
                     "name1",
                     timestamp)
        row.set_cell(column_family_id,
                     "type",
                     "temp",
                     timestamp)
    
        row.commit()
    
  2. 然后当您查询数据库时,您可以应用过滤器以仅获取最新版本或最新 N 个版本,或者基于时间戳范围进行扫描。

    rows = table.read_rows(filter_=row_filters.CellsColumnLimitFilter(2))

这里是 few snippets with examples on how to use a filter Bigtable 读取。它们应该很快添加到文档中。