Dynamoidの1.3.3を使用して検証しています
countメソッドで取得
この方法では「およそ6時間ごとに定期的に更新」というラグを除いてはもっとも良い方法です。ラグがあっても問題ない場合はこの方法で取得するのが一番良いです。
User.count
全件取得して数える
scanでは1MBを超えて取得できないのでページングをする必要があります。
全件取得するためキャパシティを上げておく必要があります(件数が多いと時間がかかります)
キャパシティをかなり消費するので稼働中のシステムに対しては実行しないほうが良いのと、アプリケーションコード内など頻繁に実行されるようなところには向かないです。 (ちなみに僕が使ったのはテーブルのデータ移行時にデータ移行がうまくいったか確認するために使いました)
table_name = :users
count = 0
scan_data = Dynamoid.adapter.client.scan(table_name: table_name)
loop do
count += scan_data.count
break unless scan_data.last_evaluated_key
scan_data = Dynamoid.adapter.client.scan(table_name: table_name, exclusive_start_key: scan_data.last_evaluated_key)
end
カウント用テーブルを作る
countsテーブルのようなテーブルを作り↓のようなレコードを作っておき、usersテーブルが追加されたらカウントアップするという方法です。
パーティションキー | 値 |
---|---|
users | 0 |
Dynamoid.adapter.client.update_item(
table_name: self.table_name,
key: {tb_name: 'users'},
update_expression: 'SET #col = #col + :val',
expression_attribute_names: {"#col" => :num},
expression_attribute_values: {":val" => 1},
return_values: 'ALL_NEW'
)
また、アクセスが多いと1レコードにアクセスが集中してしまい更新が出来なくなるので例えば↓のように分散して書き込んで取得する時に合計するという方法を取ることも出来ます。
(取得する時の負荷を抑えたければアプリケーション側でキャッシュを入れたりするのが良いと思います)
パーティションキー | 値 |
---|---|
users=0 | 0 |
users=1 | 0 |
users=2 | 0 |