式
条件式なしで更新を出荷し、2 人のワーカーが同じアイテムを更新し、エラーなしに最後の書き込みが勝つ。DynamoDB は SQL 風の行ロックを推論しない。式で述語を書き下すか、レースを受け入れる。
式は、選択的な読み取りと安全な書き込みの背後にある小さな言語だ。
このセクションはその 5 つの部分を扱う: #name / :value プレースホルダはすべての式で名前と値を束縛し、条件式は書き込みをゲートし、更新式は 1 つのアイテムをその場で変更し、キー条件は Query が何を読むかを決め、射影式は返ってくるものを削る。
読み取り後にアイテムを捨てるフィルター式は、フィルタリング戦略で扱う。
このセクションで身につくこと
- 上書きする代わりに古い書き込みを拒否する条件式を書ける。
- アイテム全体を送らずに
SET/REMOVE/ADD/DELETE更新式を組み立てられる。 - インデックスレベルで
Queryを選択的に保つキー条件を組み立てられる。 - 予約属性名をエイリアスし、JSON エスケープエラーなしに値を束縛できる。
読む順番
- 式の名前と値: すべての式タイプが共有する
#statusと:thresholdの仕組み。 - 条件式:
PutItem、UpdateItem、DeleteItem上のアトミックな述語。楽観的ロック。 - 更新式: 読み取り・変更・書き込みの往復なしの部分更新。
- キー条件式:
Queryが何を読み、したがって何が課金されるか。 - 射影式: UI が必要とする属性だけを返す。
更新上の version = :v は、負けたレースを ConditionalCheckFailedException に変える。これにはアイテムを読み直し、新しいバージョンでリトライして対処する。
status は予約語だ。裸の status = :s は #s にエイリアスするまでパースに失敗する。予約語チェッカー は AWS の
573 個の予約語すべてにフラグを立て、エイリアスを提案する。
キー条件のパーティションキーは = だけを取る。ソートキーは =、<、<=、>、
>=、BETWEEN、begins_with を取る。非キー属性はキー条件にまったく現れられない。
通常のアクセスパターンとして非キー属性でフィルターするなら、それをキーにした GSI を作ってそれをクエリする。その属性を持つアイテムが一部だけなら、スパースにする。
Scan 上のフィルター式はそれでもテーブル全体を読み、その分が課金される。式はレスポンス内の行を隠すだけだ。述語をテーブルか GSI のキー条件に移そう(Query vs Scan)。
射影式は読み取り(GetItem、Query、Scan、BatchGetItem)でレスポンスペイロードを削る。グリッドに決して出さない大きなブロブをアイテムが抱えているときに効く。書き込みが返すものを削るには、ReturnValues
の UPDATED_NEW を使う。
更新式は SET、REMOVE、ADD、DELETE 句を 1 つのアトミックな UpdateItem にまとめる。
ツール
無料の Expression Builder でブラウザ上に式を組み立てる: 操作を選び、句を足し、JSON を手でエスケープせずに SDK/CLI/boto3/PartiQL スニペットをエクスポートする。
DynoTable ではアイテム編集をステージし、コミット前に属性ごとの差分を確認する。コミットは条件付き書き込みなので、同時に行われた変更は上書きされずに競合として表面化する。有料プランがステージングとコミットを解放する。
無料の読み取り専用でも、ビジュアルフィルタービルダーでキー条件とフィルターを組み立て、PartiQL SELECT で列を選び、クエリをコードとしてエクスポートできる。