先日、ユーザー定義のオブジェクトメタデータを使ってちょっとしたデータ(ファイルのページ数とかメモとか)とファイルを一緒にS3に保存するように実装しました。するとコードレビューで『タグという選択肢もあるよ』ということを教わったので調べてみました。
どちらも制限は厳しいので、それぞれの長所・短所を把握して使い分けましょう。
前提
S3のオブジェクトメタデータは2種類あります。
- システムで定義されたオブジェクトメタデータ
- ユーザー定義のオブジェクトメタデータ
この記事ではメタデータという場合は『ユーザー定義のオブジェクトメタデータ』を指します。
タグは、『システムで定義されたオブジェクトメタデータ』に含まれます。そしてS3のオブジェクトメタデータはシステム定義、ユーザー定義を合わせて8KBという制限があります。この制限を超えない範囲であれば、タグとメタデータは併用可能です。
また、S3のオブジェクトメタデータは、タグにせよメタデータにせよキーのリスト取得を効率化するような用途では使えません。もちろんすべてあるいはプレフィックスによる対象範囲のキーのリストをすべて取得して、それらをフィルターするという用途には利用できます。
タグ
公式ドキュメントに分かりやすくまとまっています。
タグを使用してストレージを分類する
- 1 つのオブジェクトに最大 10 個のタグを関連付けることができます。オブジェクトに関連付けるタグには一意のタグキーが必要です。
- ドキュメントには『タグキーには最大 128 個の Unicode 文字、タグ値には最大 256 個の Unicode 文字を使用できます。』と書かれていますが、これは制約の一部です。日本語はそのまま保存できますが、
!
、#
、%
などたくさんの記号が保存できません。 詳しくは後述します。 - タグキーと値は大文字と小文字が区別されます。
- aws: プレフィックスは AWS 用に限定されています。ユーザーがこれを割り当てることは出来ません。タグにこのプレフィックスが付いたタグキーがある場合、タグのキーまたは値を編集、削除することはできません。aws: プレフィックスを持つタグは、リソースあたりのタグ数の制限時には計算されません。
- タグはシステム定義のオブジェクトメタデータとして
x-amz-tagging
に格納されます。
また、メタデータと比較するための追加情報としては、Tagはいつでも追加・編集・削除出来ます。メタデータは、PUTするタイミングでのみ設定可能です。
[追記] タグの値に使用できる文字について
タグではかなりたくさんの記号を使用できない点についてコメントで教えていただきました。ありがとうございます!
公式ドキュメント: Tag によると、以下の正規表現にマッチする文字列を格納することができます。
^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$
つまり\p{Po}
に含まれる!
、#
、%
などの記号が使えないことを実際に確認しました。この制約は結構厳しいですね。
メタデータ
公式ドキュメントはこちらです。
オブジェクトメタデータの使用
- メタデータは、キー・値形式で2KBまでという制限があります。
- メタデータキーは
x−amz−meta−
というプレフィックスが必要です。(2KB制限に含まれます) - メタデータキーは大文字と小文字が区別されず、設定時に小文字に変換されます。
- 重複したメタデータキーを設定すると、読み取った値はカンマ区切りで連結されます。
- 任意のUnicode文字をメタデータの値で使用できますが表示の問題を避けるために以下のようにしてください。
- RESTを使用する場合はUS−ASCII文字(日本語を含める場合はURLエンコードします)
- SOAPまたはブラウザベースのアップロードをPOST経由で使用する場合はUTF−8
- オブジェクトをアップロードする時にメタデータを設定できます。オブジェクトのアップロード後にはメタデータは変更できません。
比較表
8KB制限を考慮しつつ同時にどちらも使用可能ですが、実装工数を考えればどちらかだけ実装したいですよね。
そのために参考になりそうな制限の比較表がこちらです。
タグ | メタデータ | |
---|---|---|
キーの数 | 10個 | 制限なし |
値に使用できる文字 |
! 、# 、% などの記号はNG |
制限なし |
値の文字数 | 256文字 | 制限なし |
値の文字数の合計(英数のみ) | 2560文字 | 約2000文字 |
値の文字数の合計(日本語) | 2560文字 | 約200文字 |
設定タイミング | いつでも | PUTタイミングのみ |
メタデータの制限に「約」と付けているのはキー(x−amz−meta−...
)も2KB制限に含まれるためです。
また日本語はURLエンコードを前提です。"あ" => "%E3%81%82"
のように1文字が変換後は9文字となります。
まとめ
オブジェクトメタデータに保存できるのは小さなデータなので、ちょっとでも要件が大きくなりそうであればDynamoやRDSなどにメタ情報を保存する方が賢いと思います。
もしタグかメタデータか、どちらかで迷った場合はこの比較表を参考にしてみてください。