0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

課題

DynamoDB で時系列データを扱うときに参考になる記事は、まず DynamoDB で時系列データを処理するベストプラクティス ですが、降順にデータを取り出そうとするとパーティションキーを指定する必要があり、クエリ実行にひと手間必要です。

Primary Key Attributes
Partition Key Sort Key Attr1 Attr2 ...
2024-01-01 00:00:00.000 ... ... ...
2024-01-01 00:00:01.000 ... ... ...
2024-01-02 00:00:00.000 ... ... ...
2024-01-02 00:00:01.000 ... ... ...
... ... ... ... ...
  • 降順ソート可能な Query はパーティションキーの指定が必要
  • Scan は降順ソートできない

ひと手間とは、パーティションキーに現在日を指定し、1日づつ過去日に遡って複数回 Query を実行することです。ちょっと面倒ですね。

RDBMS だと...

RDBMS だと、以下のような日時とメッセージを持つテーブルに対して

create table logs (
  partition_key date not null,
  sort_key time not null,
  attribute_1 text
);

日時の降順でデータを取り出す SQL は、次のように簡単なんですけどね。

select * from logs order by parition_key desc, sort_key desc;

解決策

ではどのように DynamoDB で時系列の降順スキャンを実現するか、1つの解決策を紹介します。

メインの Key Schema か Global Secondary Index で次の 3点を行います。

  • パーティションキーを数字、ソートキーを文字列で定義する
  • パーティションキーには、日でまるめた負の UnixTime を保存する
  • ソートキーには UUID V7 の XOR 値を保存する

これだけで Scan が降順になります!

実行例

Partition Key(日で丸めた負の UnixTime) Sort Key (UUID V7 の XOR)
-1704034800 fe6f5b49-df3a-8ecf-596f-e78e69ad53c2
-1704034800 fe6f5b49-5c9e-8e33-61fe-813dc262ced2
... ...

ポイント

UUID V7 はランダム性を備えつつ、作った順にソート可能な識別子です。そのまま使うと昇順になってしまうので一工夫して XOR 演算します。以下 go での UUID の XOR 例です。

package main

import (
	"fmt"
	"github.com/google/uuid"
)

func main() {
	uu := uuid.Must(uuid.NewV7())
	fmt.Printf("Before %s\n", uu.String())
	for i, u := range uu {
		uu[i] = ^u
	}
	fmt.Printf("After  %s\n", uu.String())
}

実行結果

Before 0190a4cd-d3e7-7222-9f99-fdb74feee752
After  fe6f5b32-2c18-8ddd-6066-0248b01118ad
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?