
データベース
データベースとはアクセス、管理、更新が容易なデータの組織的な集合体のことです。
データベースは通常、顧客データ、在庫、財務記録など、特定の対象や目的に関連する情報を保存するために設計されています。
データはテーブルに整理され、各テーブルには行(レコードとも呼ばれる)と列(フィールドとも呼ばれる)が含まれます。
データベースは通常、データベース管理システム(DBMS)を使用して管理されます。
DBMSはユーザーがデータベースを作成、変更、照会できるようにするソフトウェアで、データベースを保護し、データの完全性を確保するためのツール(ユーザー認証、バックアップ、トランザクションログなど)も提供しています。
データベースにはリレーショナル・データベース(RDB)、NoSQLデータベース、オブジェクト指向データベースなど、いくつかの種類があります。
リレーショナルデータベースは最も一般的なタイプで、テーブル間の関係に基づいて構成されています。一方、NoSQLデータベースは、文書やグラフなどの非構造化または半構造化データを保存・管理するために設計されたデータベースです。オブジェクト指向データベースは、実世界の実体や概念を表すクラスのインスタンスであるオブジェクトにデータを格納します。
データベースは個人の小規模プロジェクトから企業レベルの大規模システムまで、幅広い用途で使用されており、データを効率的に管理・整理し、必要なときに迅速かつ効率的にアクセスするために不可欠なものです。
イベント
マガジン
技術ブログ
PSSLの佐々木です Claude Code・Copilot・Codex といった AI コーディングエージェントは、コマンドを実行できる権限を持ったまま手元のリポジトリの中で動きます。便利ですが、 secret (API token、DB 接続文字列、本番 AWS キー) との同居していることでシークレットが漏洩しないか心配になったので対応策を調査してみました。 この記事では、 ルールで縛っても AI Agent に .env を読まれてしまう情報漏洩リスク その緩和策として Infisical を選んだ理由 Infisical の仕組み (= なぜ AI に「見えない」のか) 個人 AWS アカウントを使った検証での導入手順 についてまとめました。 1. ルールで縛っても AI Agent は secret を読みうる危険がある Claude Code / Copilot 等の主要な AI コーディングエージェントには、運用ルールを書ける場所が用意されています。Claude Code なら CLAUDE.md みたいなやつです。 検証用に立てたプロジェクトの CLAUDE.md にも、こんなルールを書いてみました: - `.env`, `.env.prod`, `.env.*`, `*.pem`, `client_secret.json` などの secret 実体を読まないでください - secret ファイルに対して `cat`, `grep`, `sed`, `awk`, `head`, `tail`, `less`, `python` などで 内容を表示・抽出しないでください - secret 値、DATABASE_URL、SECRET_KEY、SMTP password、RDS password、private key を チャット、docs、issue、PR、ログへ書かないでください しかしここにルールを記載しても何度も裏切られた経験もあり、意図せずAgnetがルールを無視してシークレット情報を見に行く可能性も否定しきれないなと開発をしながら思っていました。 例えば以下のような場合にAgentがルールを無視してシークレットを読みに行く可能性があります 「node dev server が立ち上がらない」→ デバッグのため DATABASE_URL の構造を確認する必要が出る 「ECR push が失敗している」→ AWS profile / credential の状態を見る必要が出る 「 make で env が読まれていないっぽい」→ シェルから env | grep XXX する つまり、 CLAUDE.md だけに頼った secret 管理は 「事故が起きないことを祈る運用」 だと感じていて商用製品の開発をする際にかなりのリスクになりえると思っています。 2. Infisical とは Infisical は OSS の secret 管理プラットフォームです。AWS Secrets Manager や HashiCorp Vault と同じ「secret を集中管理する」カテゴリに属しますが、開発者体験が抜群に良いと思いました Web UI で見て編集できる (json でなく key-value のテーブル) CLI が direnv / dotenv-cli の上位互換 として使える 環境別 ( dev / staging / prod ) + パス別 で分離可能 メンバー単位の RBAC 、誰がいつ何を見たかの audit log Cloud (SaaS) も Self-host (Docker compose) も選べる 無料枠 が個人開発で十分使える 公式に GitHub Star 約 2 万 あって、HashiCorp Vault よりは小規模、AWS Secrets Manager よりは開発者寄りという立ち位置です。 3. 仕組み ― なぜ AI Agent から「見えない」のか Infisical CLI の中核機能は infisical run です: infisical run --env=dev --path=/aws/sandbox -- aws sts get-caller-identity このコマンドの裏では、こういう流れが起きます: infisical CLI (親) │ ├─ 1. ローカルに保存された JWT で Infisical API へ認証 ├─ 2. /aws/sandbox パスの secret 一覧を HTTPS で取得 (in-memory) ├─ 3. fork して子プロセスを作る │ └─ 子プロセスの environ に AWS_ACCESS_KEY_ID 等を export └─ 4. 子プロセス (= `aws sts get-caller-identity`) 実行 └─ 子プロセス終了で memory も解放、secret はどこにも残らない Infisicalを使っていてうれしいポイント ディスクに .env ファイルを一切作らない — AI が cat .env しても “そんなファイルない” 親 shell の env に export しない — AI が env や printenv を打っても見えない (= デフォルトの shell には載っていない) shell history に値が残らない — infisical run -- foo という呼び出し履歴は残るが、secret 値は履歴に出ない 子プロセスが終わったら secret 痕跡ゼロ — RAM 上から消える つまり、AI エージェントが「環境変数経由で secret を盗む」最もカジュアルな経路 (= cat .env と env ) を 両方とも構造的に塞いでいます 。 4. 導入手順 (個人 AWS アカウントで検証) ここからは、自分の個人 AWS アカウント上に検証用の IAM user を作り、その credential を Infisical に登録して AI エージェントから AWS リソースを操作させる、という流れで手を動かしてみた手順です。あわせて、検証用に立てた Django プロダクトの .env 相当の値 (DB 接続文字列、SECRET_KEY、SMTP password など) も Infisical に寄せて、ローカルの .env を消し去るところまでやりました。 4.1 アカウント作成 infisical.com/cloud でサインアップ。Org → Project を作成。 4.2 CLI のインストール # macOS brew install infisical/get-cli/infisical # Linux curl -1sLf '<https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh>' | sudo -E bash sudo apt update && sudo apt install -y infisical 4.3 ログインとリポジトリの紐付け infisical login # ブラウザが開いて OAuth cd path/to/repo infisical init # この repo を Infisical project に紐付け (.infisical.json 生成) .infisical.json は project ID と環境名の対応だけ が入っていて secret 値は無いので、git に commit しても問題なし。 4.4 secret を登録 Web UI から登録するのが楽です。複数環境 ( dev / staging / prod ) と任意のパス ( /aws/sandbox /django/app 等) で分けられます。 検証では、個人 AWS アカウントに作った IAM user の credential と、検証用 Django プロダクトの env をこんな感じで分けました: Infisical path env vars 用途 dev / /aws/sandbox AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (個人検証用 IAM user) AI エージェントから S3 / EC2 / SSM などを叩く検証 dev / /django/app DATABASE_URL / SECRET_KEY / SMTP_PASSWORD 等 検証用 Django アプリの実行時 env これで手元の .env は完全に削除。値は全部 Infisical 側にだけ存在する状態にしました。 4.5 実行 # AWS 操作 infisical run --env=dev --path=/aws/sandbox -- aws sts get-caller-identity # → arn:aws:iam::xxxxxxxx:user/sandbox-user # Django 起動 infisical run --env=dev --path=/django/app -- python manage.py runserver これで OK。 .env ファイルもシェルへの export も一切無し。 5. 検証してわかった恩恵 5.1 AI エージェントが構造的に secret に触れなくなった 検証では Claude Code に「個人 AWS アカウントの S3 バケットを一覧して、不要なものを削除して」みたいなタスクを投げてみました。 infisical run 経由で AWS 操作を委任しても、Claude は そもそも secret 値を「知る」術がない 。例えば: infisical run --env=dev --path=/aws/sandbox --silent -- \\ aws s3 ls これを Claude に実行させても、Claude が見られるのは: コマンドの引数 (= 公開情報) コマンドの出力 (= 私が許可した情報) だけ。 AWS キー本体は Claude のプロセス空間にも会話履歴にも入りません。 検証用 Django アプリ側でも同様で、 .env を消した状態で Claude に「dev server を立ち上げて動作確認して」と頼むと、 infisical run 経由でしか起動できない。エージェントが好奇心で cat .env しても ファイルが存在しない ので空振りに終わります。実際にやらせてみても、 DATABASE_URL や SECRET_KEY の値が会話履歴に出てくることは一度もありませんでした。 5.2 検証用 IAM user を分けやすい 個人 AWS アカウントで遊んでいると「これは AI に渡していい権限」「これは自分が手でしかやらない権限」を分けたくなります。Infisical のパスで切るとそこが綺麗: # AI に渡していい権限 (read 中心、限定リソース) infisical run --env=dev --path=/aws/sandbox -- <command> # 自分しか使わない権限 (IAM 編集、billing 系) infisical run --env=dev --path=/aws/admin -- <command> IAM user 自体は別々に作って、Infisical 側でパス権限を分けるだけ。エージェントには /aws/sandbox だけアクセスできるトークンを渡す、みたいな運用が現実的にできます。 5.3 検証が終わったら剥奪が一瞬 個人検証あるあるで「検証終わったけど IAM key 消し忘れて放置」が起こりがちですが、Infisical に集約しておけば Web UI で値を消すだけ。 .env が複数のリポジトリに散らばってる状態より圧倒的に管理が楽でした。 6. まとめ AI Agent と一緒に開発する時代、 .env をローカルに転がしておく運用は 「ルールで縛っても、いつかは事故る」 可能性があります。 文章ルール ( CLAUDE.md ) は「お願い」レベル AI Agent はタスク遂行のために env を覗くことがある (悪意なしでも) 一度履歴に入った secret は AI ベンダー側に永続化される Infisical の infisical run -- <command> 方式に切り替えると、 .env ファイルがそもそも存在しない → cat で出ない shell env にも default で乗らない → env / printenv で出ない 子プロセスのライフサイクル内だけで secret が生きる それでいて direnv 同等の手軽さで開発が回る 完全防御ではないが、 カジュアルな漏洩経路を構造的に塞いだ上で、AI エージェントとの共存を成立させる ための最小コストの一手として、強くおすすめできます。 個人 AWS アカウントでの検証レベルでも、 .env を消して Infisical に寄せたことで「エージェントに何を喋らせても secret が混入しない」という安心感は段違いでした。本番投入前のサンドボックスとして手を動かしてみる価値は十分あると思います。 参考リンク Infisical 公式 Infisical CLI ドキュメント Anthropic Claude Code 公式 GitHub: Infisical/infisical ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AI エージェントに.envを読まれたくなかったからInfisicalを導入てみた first appeared on SIOS Tech Lab .
こんにちは。 KINTO テクノロジーズの DBRE チーム所属の @hoshino です。 はじめに Aurora MySQL 2系(MySQL 5.7互換)から3系(MySQL 8.0互換)へのメジャーバージョンアップを、19クラスタ・46スキーマ規模のメインシステムで実施しました。 このバージョンアップで最も苦労したのが COLLATION の問題です。 Aurora MySQL 3系ではデフォルト COLLATION が utf8mb4_0900_ai_ci に変わりますが、既存システムでは、検索条件、ORDER BY、ユニーク制約、JOIN、帳票、バッチ処理などが utf8mb4_general_ci の比較・ソート挙動を前提に動いています。 utf8mb4_0900_ai_ci への変更は単なる DB 設定変更ではなく、アプリケーション仕様の変更に近いため、今回は互換性維持を優先し、 utf8mb4_general_ci を維持したまま移行する方針を取りました。 しかし、Aurora MySQL 3系では default_collation_for_utf8mb4 が utf8mb4_0900_ai_ci 固定で、サーバー側で変更する手段が用意されておらず、明示的に指定しないとセッションのデフォルトが utf8mb4_0900_ai_ci になってしまいます。そのため、 utf8mb4_general_ci を維持するために以下の対策を実施しました。 今回実施した対策 SCHEMA / TABLE / COLUMN / VIEW / ROUTINE / TRIGGER / EVENT の COLLATION を統一 接続設定・SQL クエリで COLLATION を明示指定することで COLLATION を制御 意図しない COLLATION が設定されないように information_schema を使った Slack 自動通知によるチェック体制の整備 本記事では、これらの対策の詳細について説明します。 背景 KINTO テクノロジーズの DBRE チームでは、Aurora MySQL 2系(MySQL 5.7互換)から3系(MySQL 8.0互換)へのメジャーバージョンアップを進めてきました。 弊社では多数のクラスタを運用していますが、今回対象となったのは複数プロダクトが共有するメインシステムの DB です。 このメインシステムは少し特殊な構成になっています。 1つの環境に対して 2つの Aurora クラスタが存在しており、複数プロダクトがこの2クラスタを共有して利用しています。 両クラスタは密接に連携しているため、片方だけバージョンアップするわけにはいかず、同時に移行する必要がありました。 対象規模は dev・stg・prod などの全環境を合計して 19クラスタ・46スキーマ・56ユーザー にのぼります。 構成を図にすると以下のようになります。 この移行で最も苦労したのが COLLATION の問題でした。 Aurora MySQL 3系(MySQL 8.0)のデフォルト COLLATION は utf8mb4_0900_ai_ci です。 一方、既存のデータベースは utf8mb4_general_ci で運用されていました。 システム全体を utf8mb4_0900_ai_ci に切り替えるという選択肢もゼロではありませんでしたが、COLLATION の変更はアプリケーションの挙動に直接影響します。 utf8mb4_general_ci と utf8mb4_0900_ai_ci は、どちらも大文字・小文字を区別しない COLLATION ですが、内部のソートアルゴリズムが異なります。 utf8mb4_0900_ai_ci は Unicode Collation Algorithm(UCA 9.0.0)に準拠しており、 = 演算子による比較結果や ORDER BY のソート順が utf8mb4_general_ci とは異なるケースがあります。 既存のアプリケーションが utf8mb4_general_ci の挙動を前提としている場合、COLLATION を切り替えただけで検索結果やソート順が変わり、意図しない不具合につながる可能性があります。 そうなると各プロダクト側でも影響調査や改修が必要になります。 複数プロダクトが共有しているデータベースであるため、その改修範囲は広く、プロダクト側の開発コストも大きくなります。 プロダクト側の負担を最小限にするためにも、 utf8mb4_general_ci を維持したままバージョンアップするという方針を選択しました。 Illegal mix of collations に対する対応 utf8mb4_general_ci を維持する方針で進めるにあたって直面したのが、 Illegal mix of collations というエラーです。 このエラーは、テーブル側の COLLATION とセッション側の COLLATION が混在した状態でクエリを実行したときに発生します。Aurora MySQL 3系では、サーバー側でデフォルト COLLATION を変更する手段がないため、何も対策しないとこのエラーが発生しやすい構造になっています。 MySQL 8.0 には default_collation_for_utf8mb4 というシステム変数があります( MySQL 公式: Server System Variables )。 これは CHARACTER SET utf8mb4 を指定して COLLATE を省略したとき、どの COLLATION がデフォルトで使われるかを決める変数で、デフォルト値は utf8mb4_0900_ai_ci です。 通常の MySQL であれば、 SET PERSIST default_collation_for_utf8mb4='utf8mb4_general_ci'; を実行することでこの値を変更できますが、Aurora MySQL ではこの変数を変更する手段がありません。 理由としては SET PERSIST は Aurora では使えず、パラメータグループにもこの設定項目が存在しないためです。 この制約により、 collation_connection を指定せずに接続した場合、セッションのデフォルトが utf8mb4_0900_ai_ci になってしまいます。 影響は実行するクエリだけではありませんでした。 VIEW や ROUTINE(ストアドプロシージャ・ファンクション)は、作成時のセッションの character_set_client や collation_connection が定義に依存するため、 utf8mb4_0900_ai_ci のセッションで VIEW を作成すると、その VIEW 自体が utf8mb4_0900_ai_ci を持ってしまいます。 後からセッションの COLLATION を変えても、すでに作成された VIEW の定義は変わりません。 さらに、クエリの中で COLLATION が動的に決まる箇所にも影響します。 たとえば UNION や CAST 関数を含むクエリでは、TABLE 側の COLLATION( utf8mb4_general_ci )とセッション側の COLLATION( utf8mb4_0900_ai_ci )が混在してエラーが発生します。 例1:CAST 関数を使った JOIN SELECT * FROM table_a AS t1 JOIN table_b AS t2 ON CAST(t1.id AS CHAR) = t2.code; -- ^^^^^^^^^^^^^^^^^^ ^^^^^^^ -- utf8mb4_0900_ai_ci utf8mb4_general_ci -- (セッションのデフォルト)(テーブルの COLLATION) CAST(t1.id AS CHAR) はセッションの collation_connection に従うため、Aurora のデフォルトである utf8mb4_0900_ai_ci になります。一方、 t2.code はテーブル定義の utf8mb4_general_ci のままです。この2つを = で比較するため、COLLATION の不一致が発生します。 例2:UNION で異なる COLLATION が混在 SELECT name FROM table_a -- ^^^^ -- utf8mb4_general_ci(テーブルの COLLATION) UNION SELECT CAST(id AS CHAR) FROM table_b; -- ^^^^^^^^^^^^^^^^ -- utf8mb4_0900_ai_ci(セッションのデフォルト) UNION は各 SELECT の COLLATION を統一する必要がありますが、上記のように一方が utf8mb4_general_ci 、もう一方が utf8mb4_0900_ai_ci になると統一できず、エラーになります。 どちらのクエリも、最終的には以下のエラーになります。 ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation '=' これを防ぐには、接続時に COLLATION を明示的に指定するか、SQL 文の中で COLLATE 句を明示する方法があります。 方法1:接続時に COLLATION を指定する -- MySQL クライアントから接続する場合 SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; # JDBC URL での指定例 jdbc:mysql://host:3306/mydb?connectionCollation=utf8mb4_general_ci 方法2:SQL 文の中で COLLATE 句を明示する UNION や CAST など動的に COLLATION が決まる箇所に、直接 COLLATE 句を付与する方法です。 -- UNION での指定例 SELECT name COLLATE utf8mb4_general_ci FROM table_a UNION SELECT name COLLATE utf8mb4_general_ci FROM table_b; -- CAST での指定例 SELECT CAST(column AS CHAR CHARACTER SET utf8mb4) COLLATE utf8mb4_general_ci FROM table_a; しかし、接続時の COLLATION 指定やクエリへの COLLATE 句付与は、あくまで移行後の運用で問題を防ぐための対策です。 移行するにあたり、移行前に Aurora 2系側の COLLATION を統一しておく必要がありました。 注意事項 SET NAMES utf8mb4 (COLLATE 句を省略)を実行すると、それまでに設定していた collation_connection が破棄され、Aurora MySQL 3系のデフォルトである utf8mb4_0900_ai_ci に戻ってしまいます。 SET SESSION collation_connection = 'utf8mb4_general_ci'; -- ↑ ここで utf8mb4_general_ci になる SET NAMES utf8mb4; -- ↑ COLLATE 句がないため utf8mb4_0900_ai_ci に戻ってしまう ORM やアプリケーションフレームワークが内部で SET NAMES utf8mb4 を発行する実装も存在するため、実際に発行されるクエリのログを確認し、暗黙の SET NAMES が含まれていないかを把握しておく必要があります。 SET NAMES を使う場合は、必ず COLLATE 句までセットで指定するのが確実です。 移行手順と事前準備 移行方法 今回の移行は mysqldump などで論理ダンプを取得し、それをインポートする方式を採用しました。 Aurora MySQL 2系から3系への移行方式としては、Blue/Green デプロイやインプレースアップグレードといった選択肢もありますが、今回は以下の理由からダンプ・インポートを採用しました。 COLLATION の事前調整で DDL 変更が必要だった VIEW や ROUTINE の定義を書き換えて再作成する必要がありましたが、Blue/Green デプロイでは DDL 変更が Green 環境へのレプリケーション中断を引き起こすリスクがあり、レプリケーションとの互換性検証コストが高いと判断しました ダンプ・インポート方式の社内実績が豊富だった 弊社では全環境で数百の DB クラスタが存在しており、そのほとんどをダンプ・インポート方式で移行しました そのため、今回のような複数プロダクトが共有する大規模システムの移行において、Blue/Green デプロイなどの実績のない手法を採用するリスクは取れませんでした 安全を最優先に考えた結果、確実にコントロールできるダンプ・インポート方式を選択しました。 ダンプ・インポート時の COLLATION エラー ダンプ・インポート方式で移行を進めたところ、COLLATION の不整合によるエラーが発生しました。 Aurora 2系側の COLLATION が utf8mb4_general_ci に統一されていない状態でダンプを取ってインポートすると、VIEW の作成時に Illegal mix of collations エラーとなり、移行そのものが失敗します。 そのため、以下の手順で移行を実施しました。 Aurora 2系側で COLLATION を utf8mb4_general_ci に統一する その状態でダンプを取得する Aurora 3系にインポートする 事前作業の内容 事前作業では SCHEMA / TABLE / COLUMN / VIEW / ROUTINE のすべてに手を入れる必要がありました。 対象となるのは2クラスタ × 全環境(dev・stg・prod 等)にまたがる数十スキーマです。複数プロダクトが共有しているため、各スキーマの VIEW や ROUTINE がどのプロダクトに属するかを把握し、プロダクトチームと調整しながら進める必要がありました。 調整箇所は全環境合計で数千にのぼり、環境ごとにリストを作成し、プロダクトチームにレビューを依頼し、反映前に最終チェックを行うというサイクルを、すべての環境に対して繰り返し実施しました。 以下、具体的な調整方法をオブジェクトの種類ごとに説明します。 SCHEMA / TABLE / COLUMN の調整 SCHEMA・TABLE・COLUMN は ALTER 文で COLLATION を utf8mb4_general_ci に変更しました。 -- SCHEMA ALTER DATABASE ${schema} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- TABLE ALTER TABLE ${table} CHARACTER SET utf8mb4 COLLATE 'utf8mb4_general_ci'; -- COLUMN ALTER TABLE ${table} CONVERT TO CHARACTER SET utf8mb4 COLLATE 'utf8mb4_general_ci'; VIEW / ROUTINE / TRIGGER / EVENT の調整 一方、VIEW・ROUTINE・TRIGGER・EVENT は ALTER では対応できないため、定義を書き換えて再作成する必要がありました。 定義内の文字コード・COLLATION を一括で置換してから CREATE OR REPLACE VIEW で再作成するアプローチを取りました。主な置換パターンは以下の通りです。 "utf8 " → "utf8mb4 " "utf8_general_ci" → "utf8mb4_general_ci" "utf8mb4_0900_ai_ci" → "utf8mb4_general_ci" "utf8mb4_unicode_ci" → "utf8mb4_general_ci" "charset utf8mb4) AS" → "charset utf8mb4) COLLATE utf8mb4_general_ci AS" 最後のパターンは CAST 関数の末尾に該当します。 CAST(column AS CHAR) のような式では COLLATION が動的に決まるため、明示的に COLLATE を付与する必要がありました。 ただし、文字列置換だけでは対応しきれないケースも存在しました。 CAST 関数の使い方が複雑であったり、置換パターンに収まらない定義を持つ VIEW がいくつかありました。 こうした箇所は information_schema で COLLATION の状態を一つひとつ確認しながら、手動で定義を修正して再作成しました。 -- 置換漏れがないか確認するクエリ SELECT table_schema, table_name, character_set_client, collation_connection FROM information_schema.views WHERE collation_connection != 'utf8mb4_general_ci' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); この確認を怠ると、一見すると置換が完了しているように見えても utf8mb4_0900_ai_ci が残ったままの定義が存在する場合インポート時にエラーが発生するか、移行後に Illegal mix of collations となってしまいます。 移行後に発生したインシデント 事前作業で Aurora 2系の COLLATION を統一し、Aurora 3系への移行を完了しました。 しかし移行後、プロダクトから Illegal mix of collations のエラーが発生したとの報告がありました。 発生したエラー エラーの内容は以下の通りです。 1267 (HY000): Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '=' Aurora 2系では問題なく動作していた機能が、Aurora 3系への移行後にエラーとなっていました。 原因の調査 まず、エラーが発生しているクエリの調査を行いました。 問題のクエリには CAST 関数を使った JOIN が含まれていました。 以下は同様の構造を持つ例です。 -- 例:CAST 関数を使った JOIN で COLLATION の不一致が発生するケース SELECT * FROM table_a AS t1 LEFT JOIN table_b AS t2 ON CAST(t1.id AS CHAR) = t2.code; CAST(... AS CHAR) の結果にはセッションの collation_connection が適用されます。 該当のアプリケーションでは collation_connection が指定されておらず、Aurora のデフォルトである utf8mb4_0900_ai_ci が適用されていました。 その結果、CAST 関数の結果は utf8mb4_0900_ai_ci となり、テーブル側の utf8mb4_general_ci と混在して Illegal mix of collations が発生していました。 対処方法 対処として、アプリケーションの DB 接続設定に collation_connection=utf8mb4_general_ci を追加しました。 # 接続文字列に COLLATION 設定を追加 mysql+mysqlconnector://user:password@host/dbname ?init_command=SET SESSION collation_connection=utf8mb4_general_ci init_command は接続確立直後に実行されるため、以降のクエリでは collation_connection が utf8mb4_general_ci の状態で処理されます。 collation_connection が utf8mb4_general_ci になることで、 CAST や UNION のようにセッションの COLLATION 値で動的に COLLATION が決まる箇所も utf8mb4_general_ci に揃えられ、テーブル側との不一致を防げます。 この変更をリリースした後、エラーは解消し、現在は安定稼働しています。 COLLATION の定期チェックと自動通知 一度問題を修正しても、新しい VIEW が作成されたりアプリケーションが更新されたりすると、同様の問題が再発する可能性があります。 本番環境でエラーが発生してから気づくのではなく、開発段階で COLLATION の不一致を早期に検知するために、全環境の COLLATION の状態を定期的にチェックし、意図しない COLLATION が設定された場合に自動で通知する仕組みと、手動で現状のCOLLATIONの状態を確認できる仕組みを構築しました。 自動化の仕組み 仕組みの全体像は以下の通りです。 1. 日次で COLLATION 情報を自動取得 COLLATION をチェックするクエリを CLI コマンドとして実装しました。 このコマンドを全クラスタに対して日次で自動実行し、取得結果を JSON 形式で S3 に保存しています。 2. 期待する COLLATION との照合と Slack 通知 EventBridge で決まった時間に、S3 上の JSON データを精査します。 DynamoDB にあらかじめ登録してある「期待する COLLATION」と照合し、意図しない COLLATION が検出された場合は Slack の専用チャンネルに自動通知します。 3. CLI による手動チェック CLI コマンドは手動でも実行できます。 新規 TABLE 作成後やトラブルシューティング時など、任意のタイミングで特定のクラスタの状態を確認したい場合に使用しています。 COLLATION チェックで実行しているクエリ 自動化の仕組みの中で各クラスタに対して実行しているクエリは、 information_schema を使って utf8mb4_general_ci 以外の COLLATION が混入していないかを検出するものです。対象が SCHEMA・TABLE・COLUMN・VIEW・ROUTINE・TRIGGER の6種類です。 -- SCHEMA の COLLATION 確認 SELECT schema_name, default_character_set_name, default_collation_name FROM information_schema.schemata WHERE schema_name NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); -- TABLE の COLLATION 確認 SELECT table_schema, table_name, table_collation FROM information_schema.tables WHERE table_collation != 'utf8mb4_general_ci' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); -- COLUMN の COLLATION 確認 SELECT table_schema, table_name, column_name, collation_name FROM information_schema.columns WHERE collation_name IS NOT NULL AND collation_name != 'utf8mb4_general_ci' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); -- VIEW の collation_connection 確認 SELECT table_schema, table_name, character_set_client, collation_connection FROM information_schema.views WHERE collation_connection != 'utf8mb4_general_ci'; -- ROUTINE の COLLATION 確認 SELECT routine_schema, routine_name, routine_type, collation_connection, database_collation FROM information_schema.routines WHERE collation_connection != 'utf8mb4_general_ci'; -- TRIGGER の COLLATION 確認 SELECT trigger_schema, trigger_name, collation_connection, database_collation FROM information_schema.triggers WHERE collation_connection != 'utf8mb4_general_ci'; 今後のAuroraバージョンアップ(Aurora MySQL 4)に向けて MySQL 8.4 で default_collation_for_utf8mb4 を SET PERSIST で変更すると、以下の deprecated 警告が表示されます。 mysql> SET PERSIST default_collation_for_utf8mb4='utf8mb4_general_ci'; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> SHOW WARNINGS; +---------+------+--------------------------------------------------------------------------------------------------------+ | Level | Code | Message | +---------+------+--------------------------------------------------------------------------------------------------------+ | Warning | 1681 | Updating 'default_collation_for_utf8mb4' is deprecated. It will be made read-only in a future release. | +---------+------+--------------------------------------------------------------------------------------------------------+ 「将来のリリースで read-only にする」と警告されていることから、今後この変数による COLLATION の制御はさらに難しくなる可能性があります。COLLATION を確実に制御するためには、SCHEMA・TABLE・COLUMN・VIEW・ROUTINE のすべてで明示指定し、 information_schema で定期的にチェックするアプローチが引き続き有効です。 Aurora MySQL のリリースカレンダー によると、Aurora MySQL 3 のメジャーバージョン標準サポートは 2028年4月30日 までとなっています。その後は次のメジャーバージョンへの移行が必要になるため、今回整備した定期チェックの仕組みや CLI コマンドを次のバージョンアップでもそのまま活用できるようにしておくことが重要だと考えています。 まとめ Aurora MySQL 3系では MySQL 8.0 互換となり、デフォルト COLLATION が utf8mb4_0900_ai_ci に変わったことで、既存 DB の utf8mb4_general_ci と混在しやすくなった。これが今回の苦労の根本原因 Aurora MySQL では SET PERSIST で default_collation_for_utf8mb4 を変更できないため、サーバー側で utf8mb4 の デフォルト COLLATION を制御できない 接続時に collation_connection を明示指定しないと、セッションのデフォルトが utf8mb4_0900_ai_ci となり Illegal mix of collations が発生する可能性がある ダンプ・インポートで移行する場合、移行前に Aurora 2系側の SCHEMA / TABLE / COLUMN / VIEW / ROUTINE の COLLATION を統一しておく必要がある SET NAMES utf8mb4; (COLLATE 省略)は直前の COLLATE 指定を破棄するため、接続文字列の init_command で指定するのが確実 移行後も information_schema を使った COLLATION の定期チェックと自動通知の仕組みが有効 今回整備した COLLATION チェックの仕組みや CLI コマンドは、次のバージョンアップでもそのまま活用できる 本記事の内容が、同じ課題に取り組んでいる方々の参考になれば幸いです。 参考文献 Changes in MySQL 8.0 collation_server のデフォルトが utf8mb4_0900_ai_ci に変更 Server System Variables default_collation_for_utf8mb4 パラメータの補足 接続に関するパラメータの理解 character_set_* / collation_* 各パラメータの関係 SET NAMES の補足 セッションの COLLATION 指定方法
本ブログは、 株式会社テイツー 様とアマゾン ウェブ サービス ジャパン合同会社が共同で執筆いたしました。 AWS 上に既にあるリソースを別のシステムの一部として活用しよう、というアイデアを思いつくことは頻繁にあるかと思います。しかし実現に向けたアクションとなると、連携方式の選定や既存システムへの影響評価など検討すべきことが山積し断念、気がつくと巨大で複雑な連携システムが出来上がっていた・・・こんな経験はありませんか。テイツーはこの課題をクラウドの特徴を捉えたシンプルな設計判断で乗り越え、わずか約 3 ヶ月での新サービスリリースを実現しました。 このブログでは既存の AWS 資産を活用した新サービス創出までのアプローチと、リユース業界における店舗 DX の取り組みについてご紹介します。 株式会社テイツー(以下、テイツー)は、「古本市場」「ふるいち」「トレカパーク」などのリユース店舗を全国 180店舗(執筆時点)展開する東証スタンダード上場企業です。同社はトレーディングカードの読取査定機「 TAYS 」の開発・運用を通じて、 AWS の活用を進めてきました。テイツーはこの TAYS の AWS 基盤を活かし、店舗向け POP 自動生成サービス「POP×THREE」をわずか約 3 ヶ月で開発・リリースしました。 リユース業界における店舗運営の課題 テイツーは 1989 年の創業以来、書籍、家庭用テレビゲーム、トレーディングカード、ホビー、スマートフォン、CD、DVD、衣類など幅広いカテゴリのリユース品を取り扱い、「家族で楽しめる廉価な娯楽の提供」を事業の柱としてきました。近年はトレーディングカード市場の拡大に伴い、トレカ読取査定機「TAYS」を自社開発し、BtoB サービスとして外販するなど、テクノロジーを活用した事業展開にも積極的に取り組んでいます。 一方で、リユース業界特有の課題として、商品の買い取り価格が市場動向に応じて日々変動するという点があります。特にトレーディングカードの分野では、新タイトルの発売や大会の開催などによって価格が大きく変動するため、店舗に掲示する買い取り告知 POP を頻繁に更新する必要があります。 これまでは全店舗に配信する買い取り告知 POP の作成に、1 回あたり約 1〜2 時間の作業時間を要していました。主な作業内容はカードの価格変更やタイトルの入れ替えですが、告知を一から作成する場合にはさらに多くの時間がかかるケースもありました。全国の店舗に対してタイムリーに情報を届けるためには、この POP 作成業務の効率化が不可欠でした。 TAYS から POP×THREE へ – 既存 AWS 基盤を活かした新サービス構想 テイツーが運用するトレカ査定システム「TAYS」は、読み取りスキャナーと連携し AWS を中心としたクラウド上でAIによる判定、データ閲覧と編集を可能にした、トレカ買い取りに特化した基盤です。 TAYS の基盤では、Amazon Aurora MySQL を DB サーバとして採用し、Amazon EC2 上のLinux でアプリケーションを稼働させています。AWS WAFによるセキュリティ対策も施されており、全国の店舗からインターネット経由で安全にアクセスできる構成となっています。 TAYS 自身は元々、外販向けの構想や個店ごとの価格設定などを見据えて設計されていました。つまり、そのデータベースには買い取り以外にも店舗運営に必要な商品・価格情報が蓄積されており、新たなサービスを構築するためのデータ資産がすでに存在していたのです。 ここから生まれたのが「POP×THREE」です。TAYS のデータ資産とインフラ基盤を API 経由で活用し、その上にフロントエンドを構築するというアプローチで新サービスを開発できるのでは、という発想からスタートしました。実装内容をなるべく少なく、リリースを速くしたいという方針のもと、2025 年 9 月下旬に開発をスタートし、同年末には提供を開始しています。 POP×THREE のサービス概要 POP×THREE は、TAYS に蓄積された商品・価格データを活用し、店舗向けの買い取り告知 POP を効率的に作成するサービスです。商品データを一括投入し、テンプレートを活用して POP を量産するツールとして設計されています。画像認識には独自構築の画像認識モデルを用いており、カード画像の細かな違いを認識することでトレーディングカードにおけるバリアントの判定も可能となっています。 システムアーキテクチャ POP×THREE はあくまでフロントエンドとして機能し、バックエンドは既存の TAYS 基盤との連携を前提に設計されています。ここでは、TAYS の既存基盤と POP×THREE の新規構成の両方をご紹介します。 TAYS + POP×THREE 基盤 TAYS POP×THREE 構成図(一部省略) TAYS のシステム基盤は、以下の構成となっています。 ネットワーク・アクセス: Amazon Route 53 による DNS 管理、 Elastic Load Balancing (ALB) によるトラフィック分散 コンピューティング: オートスケール構成のAmazon EC2 データベース: Amazon Aurora MySQL をメインの DB サーバとして採用 ストレージ連携:カード画像・スキャン画像・OCR ログなどのデータを各サーバ間で共有。画像処理や一括データ更新を実行 セキュリティ: AWS WAF による Web アプリケーション保護 POP×THREE のワークロード増加に伴いオートスケール化とセキュリティ強化策を講じることで、TAYS は全国の店舗と本部を結ぶより堅牢なシステム基盤として安定稼働しています。 POP×THREE の構成 POP×THREE は、TAYS の資産を最大限に活かすことを念頭に、既存 AWSアカウントに同居する形で構築しました。東京リージョンの 2 つのアベイラビリティゾーンにまたがる構成で、高可用性を確保しています。 ネットワーク・アクセス:共通 ALB によるトラフィック分散 コンピューティング: Private Subnet 内に本番環境・検証環境で分離して配置 キャッシュ: Amazon ElastiCache を本番・検証それぞれに配置し、パフォーマンスを最適化。スロークエリログおよびエンジンログを CloudWatch Logs で管理 セキュリティ: WAF Charmと共通 AWS WAF による Web アプリケーション保護 ログ管理: Amazon CloudWatch Logs と Amazon Data Firehose によるログの収集・S3 への転送(本番・検証それぞれ)。AWS WAF ログ、ALB ログも Amazon S3 に保管 設定管理: AWS Systems Manager パラメータストアによる構成情報の一元管理 設計上のポイント POP×THREE の設計において最も重要な判断は、TAYS の既存データをどのように新サービスから利用するかという連携方式の選定でした。新システムを構築する際の一般的なアプローチとしては、①DB レプリカや DMS によるデータ同期、②既存システム側に専用 API を公開し新システムがそれを利用する、③既存 DB を直接参照する、といった選択肢が考えられます。 テイツーが採用したのは②のアプローチです。TAYS 側に POP×THREE 専用(連携アプリ用)の API を設置し、POP×THREE はその API を介して商品・価格データを取得する構成としました。この判断の背景には、TAYS と POP×THREE で保守を担当する開発ベンダーが異なるという事情もありました。①のレプリカ構成では DB 構造への依存が強くなり、スキーマ変更のたびに両ベンダー間で調整が発生します。DMS によるデータ同期についても、レプリケーションの複雑性と継続的なメンテナンス負荷を踏まえ、現在の運用体制では現実的ではないと判断しました。③は②の構成が取れれば必要ありません。 API を採用した最大の狙いは、システム間の責務を明確に分離し、将来的な変更や機能追加のスピードを確保することにあります。これを介することで、DB 構造変更時の影響範囲は TAYS 側に閉じ、POP×THREE 側は API の後方互換性さえ保たれていれば独立して開発・デプロイが可能です。保守ベンダーが異なっていても、調整コストを最小限に抑えながら利用者の要望に迅速に応えられる構成となっています。一方で、POP×THREE から見れば TAYS が稼働していなければデータ取得ができないという依存は残りますが、Aurora MySQL 自体の高可用性構成と、読み取りレプリカの追加による柔軟なスケーリングにより、実運用上のリスクは許容範囲と判断しました。 加えて年内リリースの方針のもと、各ベンダーがスケジュール遵守を前提に開発を進める必要がありました。API のインターフェース仕様を早期に確定させたことで、TAYS 側(API 公開)と POP×THREE 側(フロントエンド構築)の開発を並行して進められたことも、約 3 ヶ月という短期間でのリリースを支えた要因です。AWS という共通のクラウド基盤上で IAM やネットワーク設計が標準化されていたことで、異なるベンダー間の技術的な齟齬が生じにくかった点も大きく寄与しています。 導入効果 POP×THREEにより、テイツーでは以下の効果が得られています。 業務効率化 すでに POP×THREE を導入している外販先企業では、数時間単位での業務効率化につながっているとのことです。 テイツー直営店での本格利用はこれからですが、全店舗に配信する予定の買い取り告知 POP の作成業務において、運用次第では 1 枚あたり約 30 分程度の作業時間短縮が見込まれています。従来は 1 回あたり約 1〜2 時間を要していた作業であり、特に価格変更やタイトルの入れ替えといった定型的な更新作業での効率化が期待されます。 外販先での実績を踏まえ、さらなる効果が期待されています。 安定稼働とスケーラビリティ POP×THREE はサービス開始以来システムダウンを経験していません。テイツーは「クラウドの恩恵として、マネージドサービスでインフラ管理コストを下げつつも、安定稼働している」と評価しています。 スケーラビリティの面では、直近でトレーディングカードのビッグタイトルが発売され大規模な負荷が発生した際、TAYS のオートスケール対応を実施しました。常時複数台のサーバを配置する構成へ移行し、今後のさらなるトラフィック増加にも対応できる体制を整えています。 AWS の活用メリット テイツーが AWS を活用する中で特に評価しているのは、以下の点です。 複数ベンダーとの円滑な連携: POP×THREE の開発では複数の開発ベンダーに依頼しましたが、AWS という認知度の高い基盤があったことでスムーズに連携を行うことができました 適切なサービス選択の提案: AWS からの技術支援により、要件に合った適切なサービスの選択を行うことができました クラウドの安定性: お客様向けサービスの基盤として、高い可用性と安定稼働を実現しています テイツー様からのコメント 「当社として本件は単なるシステム導入事例ではなく、AWS ならではのスピーディーな立ち上げとして対外的に発信できるテーマだと考えています。 トレカ査定システム TAYS の開発・運用を通じて培った AWS 基盤を最大限に活用することで、POP×THREE を約 3 ヶ月という短期間で立ち上げることができました。既存の RDS を活用し、フロントエンドの開発に集中するというアプローチは、実装をなるべく速く、少なくしたいという当社の方針に合致するものでした。また、AWS からの適切なサービス選択の提案により、限られたリソースの中でも最適なアーキテクチャを構築できたと感じています。 本取り組みは、既存データ資産を活用し小さく始めることで再現可能なモデルであり、AWS の各サービスの機能を利用して継続的に最適化できる点も大きな強みです。 システムの安定稼働はお客様へのサービス品質に直結するものであり、クラウドの恩恵を日々実感しています。今後も AWS の技術を活用し、リユース業界における店舗 DX をさらに推進してまいります。」 — 株式会社テイツー 情報システム部マネジャー 野口 義弘 様 今後の展望 テイツーでは、POP×THREE の展開をさらに加速させるとともに、AWS 基盤の強化を進めていく計画です。現在は TAYS が公開する API を介したデータ連携により運用していますが、導入先の拡大に伴うトラフィック増加に備え、Aurora の読み取りレプリカ追加やキャッシュ戦略の見直しも視野に入れています。さらに、中長期的には API の拡充やイベント駆動型の連携導入により、TAYS と POP×THREE それぞれが独立してスケール・進化できるアーキテクチャへの発展を段階的に進める方針です。直営店についてはこれから POP×THREE の利用を本格化させる段階であり、現場からのフィードバックを得ることで今後の展開を検討していく予定です。 テイツーの取り組みは、既存の AWS 基盤を活かして新たなサービスを迅速に立ち上げるという、クラウド活用の好例です。リユース業界における店舗 DX の推進に向けて、テイツーの挑戦は続きます。





















