LoginSignup
1
3

More than 3 years have passed since last update.

Amazon QLDBで台帳データベースを構築する

Posted at

Amazon QLDBを触ってみた。

全体構成

WS075.JPG

  • QLDBはテーブルとジャーナルで構成される
    • テーブル
      • データとメタデータを過去の状態を含めてもつ
      • selectの実行先
    • ジャーナル
      • 変更履歴をもつ
      • insert、update、deleteの実行先

ジャーナル

WS076.JPG

  • ドキュメントに行ったすべての変更の完全で不変な履歴全体をもつ
  • 追加していくだけで、変更削除はできない
  • データだけでなく実行されたクエリも記録する

ブロック

  • ジャーナルにコミットされたオブジェクト
  • トランザクション:ブロック = 1:n
  • エントリ、ブロックハッシュを含む

エントリ

  • ドキュメントリビジョン、それらをコミットした PartiQL ステートメントを含む

テーブル

  • ドキュメントリビジョンのコレクション
  • ドキュメントの最新のリビジョンだけでなく、過去のイテレーションもすべて含まれる

ドキュメント

  • データのこと
  • Amazon Ionというフォーマットで表す
    • 構造化データと非構造化データの両方を一緒に保存できる抽象データモデル
    • JSONの拡張フォーマット
  • 1レコードに1つのドキュメントIDがメタデータとして付与されている

Vehicle.json
{
    VIN: "1N4AL11D75C109151",
    Type: "Sedan",
    Year: 2011,
    Make: "Audi",
    Model: "A5",
    Color: "Silver"
}

ネストして保持も可能

VehicleRegistration.json
{
    VIN: "KM8SRDHF6EU074761",
    LicensePlateNumber: "CA762X",
    State: "WA",
    City: "Kent",
    PendingPenaltyTicketAmount: 130.75,
    ValidFrom: 2017-09-14T,
    ValidTo: 2020-06-25T,
    Owners: {
        PrimaryOwner: { PersonId: "IN7MvYtUjkp1GMZu0F6CG9" },
        SecondaryOwners: []
    }
}

ドキュメントリビジョン

  • ドキュメントの更新を表す仕組み
    • ドキュメントIDと0から始めるバージョン番号で表す
  • ドキュメントとドキュメントIDとバージョン番号を含むメタデータで構成される

data:{
    VIN: "KM8SRDHF6EU074761",
    LicensePlateNumber: "CA762X",
    State: "WA",
    City: "Kent",
    PendingPenaltyTicketAmount: 130.75,
    ValidFrom: 2017-09-14T,
    ValidTo: 2020-06-25T,
    Owners: {
        PrimaryOwner: { PersonId: "IN7MvYtUjkp1GMZu0F6CG9" },
        SecondaryOwners: []
    }
},
metadata:{
    id:"JOzfB3lWqGU727mpPeWyxg",
    version:0,
    txTime:2019-06-05T20:53:321d-3Z,
    txId:"HgXAkLjAtV0HQ4lNYdzX60"
}

ユーザーテーブル、カレントビュー、ユーザービュー

  • 削除されていない最新の各ドキュメントが格納される
    • 最新かどうかはジャーナルにコミットされたトランザクションに基づく

システムテーブル、コミット済みビュー

  • 各ドキュメントとそのシステム生成メタデータを格納する
  • ユーザーテーブル作成時にシステムによって作成されるテーブル
  • ユーザーテーブルと1対1の関係
  • 「_ql_committed_」+ユーザーテーブル名で命名される
  • 過去のイテレーションは履歴として保存される

blockAddress

  • ドキュメントリビジョンがコミットされた台帳のジャーナルのブロックの場所
    • strandId:ブロックを含むジャーナルストランドの一意の ID
    • sequenceNo:ストランド内でブロックの場所を指定するインデックス番号

hash

  • ドキュメントリビジョンを一意に表す SHA-256 値
  • ハッシュは data フィールドと metadata フィールドを対象とする
  • 暗号検証に使用

data

  • 最新のドキュメント

metadata

  • システムによって生成される各ドキュメントごとのメタデータ
    • id:システムによって割り当てられたドキュメント ID
    • version:ドキュメントリビジョンごとに増えていく 0 から始まる整数
    • txTime:ジャーナルにドキュメントリビジョンがコミットされたときのタイムスタンプ
    • txId:ドキュメントリビジョンをコミットしたトランザクションの一意の ID

{
    blockAddress:{
        strandId:"JdxjkR9bSYB5jMHWcI464T",
        sequenceNo:14
    },
    hash:{{wPuwH60TtcCvg/23BFp+redRXuCALkbDihkEvCX22Jk=}},
    data:{
        VIN: "KM8SRDHF6EU074761",
        LicensePlateNumber: "CA762X",
        State: "WA",
        City: "Kent",
        PendingPenaltyTicketAmount: 130.75,
        ValidFrom: 2017-09-14T,
        ValidTo: 2020-06-25T,
        Owners: {
            PrimaryOwner: { PersonId: "IN7MvYtUjkp1GMZu0F6CG9" },
            SecondaryOwners: []
        }
    },
    metadata:{
        id:"JOzfB3lWqGU727mpPeWyxg",
        version:0,
        txTime:2019-06-05T20:53:321d-3Z,
        txId:"HgXAkLjAtV0HQ4lNYdzX60"
    }
}

information_schema

  • ユーザーテーブルのメタデータをもつ
    • tableId:テーブル ID
    • name:テーブル名
    • indexes:テーブルのインデックスのリスト
    • status:テーブルの現在のステータス (ACTIVE または INACTIVE)

{
    tableId: "5PLf9SXwndd63lPaSIa0O6",
    name: "VehicleRegistration",
    indexes: [{ expr: "[VIN]" }, { expr: "[LicensePlateNumber]" }],
    status: "ACTIVE"
}

チュートリアル

Amazon QLDB でのデータと履歴の使用をなぞってみた

台帳作成

  • 「台帳の作成」ボタンを押下
    WS000.JPG

  • 任意の台帳名を入力し、「台帳の作成」ボタンを押下
    WS001.JPG

  • 1分くらいで作成完了
    WS004.JPG

データ投入

  • 今回はサンプルデータでテーブルとドキュメントを挿入
    WS009.JPG

  • 「Vehicle」テーブルのドキュメントをselect
    WS014.JPG

クエリ

  • 基本的なSQLは投げられる
  • ネストされたデータもSQLで取得可能
取得元.json
{
  VIN: "1N4AL11D75C109151",
  LicensePlateNumber: "LEWISR261LL",
  State: "WA",
  City: "Tokyo",
  PendingPenaltyTicketAmount: 90.25,
  ValidFromDate: 2017-08-21T,
  ValidToDate: 2020-05-11T,
  Owners: {
    PrimaryOwner: {
      PersonId: "IN7MvYtUjkp1GMZu0F6CG9"
    },
    SecondaryOwners: [{PersonId:"5Ufgdlnj06gF5CWcOIu64s"}]
  }
}
実行SQL.sql
SELECT 
    r.VIN, 
    o.PersonId
FROM
    VehicleRegistration AS r, @r.Owners.PrimaryOwner AS o
WHERE
    r.VIN = '1N4AL11D75C109151'
取得したデータ.json
{
  VIN: "1N4AL11D75C109151",
  PersonId: "IN7MvYtUjkp1GMZu0F6CG9"
}

更新

  • 更新自体はRDSと同様
  • 更新前ドキュメント WS053.JPG
実行SQL.sql
UPDATE VehicleRegistration AS r
SET r.Owners.PrimaryOwner.PersonId = 'IN7MvYtUjkp1GMZu0F6CG9',
r.City = 'Tokyo'
WHERE r.VIN = '1N4AL11D75C109151'
  • 更新後ドキュメント
    WS056.JPG

  • 更新前のドキュメントを履歴テーブルから取得できる
    003.png

  • メタデータも同様に履歴テーブルから取得できる
    004.png

検証

  • 「ダイジェストを取得」ボタンにて現在の台帳のダイジェストを取得
    WS065.JPG

  • 「保存」ボタンを押下し、ファイルとしてダウンロード
    WS066.JPG

sampleLedger-2020-02-22.ion.txt
{
    "digest":"h5pUdLTTNpjgMFE3omBszf2tTtlGWHpty8GM1Zxuzo4=",
    "digestTipAddress":"{strandId:\"JOzfHtF3bQL8pjtQlU37Fu\",sequenceNo:107}",
    "ledger":"sampleLedger",
    "date":"2020-02-22T07:53:34.448Z"
}
  • 検証したいドキュメントのidとblockAddressを取得
    WS068.JPG

  • 「検証」ボタンを押下
    005.png

  • ハッシュのチェーンを確認し検証結果を表示
    006.png

  • リビジョンハッシュと証明ハッシュの1つ目を連結し、ハッシュ化した値を

    さらに2つ目と連結しハッシュ化し、繰り返す

    最終的に出たダイジェストがドキュメントのダイジェストと一致するかを検証している
    WS084.JPG

  • ブロック情報も確認できる
    007.png

感想

  • 台帳作成がマネジメントコンソール上で完結していてすごく楽
  • 数クリック作成されるのはこれまでのブロックチェーンサービスと違って良い体験
  • RDSのSQLのように半構造のドキュメントを扱えるのは良い
  • 更新履歴の持ち方や整合性を考える必要がなくなるのはすごく良い
  • 検証するユースケースはよく分からない…………
1
3
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
1
3