GH GambleHub

MongoDBと柔軟なデータスキーマ

(セクション: 技術とインフラ)

簡単な要約

MongoDBは、柔軟な回路(BSON)、高速インサート、水平スケーリング、強力なアグリゲーションパイプラインを備えたドキュメント指向のストレージです。iGamingでは、プレイヤープロファイル、柔軟なCRMカード、イベントログ、テレメトリー、実体化されたストリームプロジェクション、ゲームカタログ、キャッシュされたフロントビューに最適です。通貨不変量(ウォレット/レジャー)の場合、SQL/CPの輪郭はより頻繁に残されます。MongoDBは、読み取りモデルおよび高性能ドキュメントストレージとして適切です。


MongoDBがiGamingを最大限に活用する場所

プレーヤープロファイルと設定:構造変数(ロケール設定、環境設定、KYCメタデータ)。
コンテンツ/ゲーム/プロバイダカタログ:クイックカード読み取り、フィルタ、タグ付け、全文。
イベント/テレメトリー/ログ:高いTPS、時間ウィンドウ、TTLストレージ。
マテリアライズドビュー(CQRS):クイックスクリーン(リーダーボード、最近のアクション、集計)。
パーソナライゼーション/特長オンラインML:コレクションのKVパターン、短いTTL。


柔軟なスキームの原則: カオスの代わりに規律

MongoDBは「スキーマなし」ではありません。スキーマはコードと検証に住んでいます。

推奨される:

1.契約としてのスキーム:コレクション内のJSONスキーマ検証。

2.'schemaVersion'フィールドを持つドキュメントのバージョン管理。

3.厳密な必須フィールド(id、検索キー)、まれな属性の「尾」-オプション。

4.配列寸法とネストを拘束します(インデックスとRAM用)。

5.バックグラウンドでの移行:'schemaVersion'、 shedulers、 back fillsによる更新。

例: JSONスキーマ検証

js db.createCollection("player_profiles", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["playerId", "createdAt", "schemaVersion"],
properties: {
playerId: { bsonType: "string" },
createdAt: { bsonType: "date" },
schemaVersion: { bsonType: "int", minimum: 1 },
locale: { bsonType: "string" },
kyc: {
bsonType: "object",
properties: {
status: { enum: ["pending", "verified", "rejected"] },
doc: { bsonType: "object" }
}
}
}
}
}
});

データモデルとドキュメントデザイン

デザイン「オンデマンド」:1画面/エンドポイント=1ドキュメントまたは小さなドキュメントのセット。
非正規化:添付された小さなサブドキュメント(ゲームプロバイダのミニカードなど)を含める。

リンクと埋め込み:
  • 埋め込み-密接に関連し、まれに更新されたフラグメントのために。
  • 参考文献('ref')-大きなサイズ/頻繁な更新/再使用。
  • サイズ制限:文書≤ 16 MB;大きなバイナリ-GridFS/オブジェクトストレージ。
  • 監査/メタデータ:'createdAt'、 'updatedAt'、 'traceId'、 'tenantId'、 'idempotencyKey'。

インデックス: 読み取り品質とレイテンシの安定性

インデックスタイプとプラクティス:
  • Bツリー(プライマリ)

複合:フィールドの順序は頻繁な述語とソートに対応します。
プレフィックスルール:プレフィックスオプションは'(tenantId、 playerId、 createdAt)'で動作します。
Sort:インデックスの最後にある'sort'を考えます(例えば'createdAt: -1')。

js db.bets.createIndex(
{ tenantId: 1, playerId: 1, createdAt: -1 },
{ name: "idx_bets_tenant_player_created_desc" }
);

部分的な/Sparse

頻繁なサブセット('status:' pending')を加速し、サイズを縮小します。

js db.withdrawals.createIndex(
{ playerId: 1, createdAt: -1 },
{ partialFilterExpression: { status: "pending" } }
);

TTL

テレメトリー/ログ/一時的な機能-自動有効期限。

js db.events.createIndex({ expireAt: 1 }, { expireAfterSeconds: 0 });

テキスト/オートコンプリート

'text'または全文(言語制限);自動補完の場合-'n-gram '/trigram through fields and regex approachまたはAtlas Search。

インデックスのantipatterns

「すべて」インデックス→書き込み速度の低下。
部分的な→低い選択性のない低いcardinality。
複製された化合物。
巨大配列内のインデックスフィールドに制限はありません。


集約パイプライン: クイックスクリーンとレポート

'$match'→'$sort'→'$limit'を初期段階として使用します。'$match/$ sort'の下のプロジェクトインデックス。
'$lookup'は制御されたジョインのために(適度な容積の柔らかい)。
複数のメトリックの'$facet';'$unionWith'-コレクションをマージします。
'$merge'/'$out'-コレクション(read-models)の結果を具現化します。

例:最後のプレーヤーベット+ボールト:
js db.bets.aggregate([
{ $match: { tenantId: "eu-1", playerId: "p123" } },
{ $sort: { createdAt: -1 } },
{ $limit: 100 },
{ $group: {
_id: "$playerId",
lastBets: { $push: { amount: "$amount", ts: "$createdAt", game: "$gameId" } },
totalAmount: { $sum: "$amount" }
} }
]);

トランザクション、コンシステンシー、idempotency

単一文書原子-自由な原子性;複雑な不変量-ドキュメントのパーティショニングを考える。
マルチドキュメントトランザクション(ACID)-レプリカセットで利用できますが、レイテンシが高くなります。ポイントワイズを適用します。

懸念を書く/懸念を読む:
  • 'w:クリティカルレコード(レイテンシコスト)のための'magazine';
  • 'readConsidence:' magazine'は一貫して読むことができます。
  • Idempotency: 'idempotencyKey'/'pspTx'の一意のキー、UPSERT操作('$setOnInsert'、'$inc')。
例UPSERT:
js db.wallet.updateOne(
{ playerId: "p123" },
{ $inc: { balanceCents: -5000 }, $set: { updatedAt: new Date() } },
{ upsert: true, writeConcern: { w: "majority" } }
);
💡 通貨不変量の場合、SQLは通常好ましいです。Mongoでは-厳格なキー/アイデンポテンスの規律と限られたトランザクションのみ。

シャーディングとキーの選択

シャードキーによるMongoDBシャード。選択は重要です:
  • 負荷分布:高いカーディナリキーと均一な分布(例えば、'(tenantId、 playerId)')。
  • 単調さを避ける:'createdAt'を唯一のキー→「hot」シャードとして指定します。
範囲とハッシュ:
  • ハッシュ-レコードをより均等に配布します。
  • 範囲は範囲クエリに適していますが、ホットテールに注意してください。
  • 規制/ローカライズ(EU/LatAm/TR)のタグ範囲。
例:
js sh.enableSharding("igaming");
db.bets.createIndex({ tenantId: 1, playerId: 1, _id: "hashed" });
sh.shardCollection("igaming.bets", { tenantId: 1, playerId: 1, _id: "hashed" });
Antipatterns:
  • 低いカーディナリティによるシャードキー('status')-シャードのスキュー。
  • 1つのキーを同時に共有することなく、シャーディーコレクション間で頻繁に'$lookup'を実行します。
  • 変更可能なシャードキー(変更が困難で高価)。

レプリカセット、読み取り、読み取り後のポリシー

レプリカセット=HAとトランザクションベース。

Preferenceを読む:
  • 'primary'(クリティカルな読み込み後の書き込み);
  • 'primaryPreferred'/'secondary'-アナリティクス/非クリティカル。
  • SLOとレイテンシーバジェットによる懸念座標の読み取り/書き込み。

ストリーム、CDC、統合の変更

ストリームの変更:挿入/更新/削除のサブスクリプション-次の場合に便利です:
  • キャッシュレイヤー同期(Redis)
  • CRMトリガー/通知、
  • OLAP (ClickHouse/Pinot)へのダウンロード、
  • リアクティブスクリーン。
  • アウトボックスパターン:クリティカルドメインの場合、イベントを別のコレクションにパブリッシュします。これにより、統合の予測可能性が向上します。

観測可能性とSLO

SLO: p99カード読書≤ 10-20 ms;イベントの挿入≤ 20-40ミリ秒;X%内のシャード間の合図差;99 ≥可用性。9%.

メトリクス:op-latency、キューの深さ、セカンダリあたりのアンプの%、キャッシュ/WT統計、ページフォルト、ロックウェイト、オープンカーソル/接続の数。
プロファイリング:'システム。profile'、'explain ("executionStats')'、collection/index locks。
アラート:WTキャッシュ圧力の増加、遅い操作、インデックスに含まれていないリクエストの増加、セカンダリリリクエストのバックログ、チャンク移行/バランサ。


パフォーマンスとチューニング

WiredTiger Cache:デフォルトでは~ 50% RAM-プロファイルの検証。
圧縮:コレクション用のsnappy/zstd、ログ用のzstd-CPU/IOバランス。
テレメトリー用のバッチインサートとbulkWrite。
「厚い」ドキュメントをドラッグしないように投影('{field: 1}')します。
Limit/Skip:大きな'skip'→カーソル/マーカーのページネーション('createdAt/_ id')を使用しないようにします。
「リング」ログのキャップコレクション。


安全性とコンプライアンス

Auth/RBAC:コレクション/データベース上のロール、必要最小限の権限。
トランジット中のTLS、ディスク上の暗号化(FLE/at-rest)。
PIIポリシー:マスキング/エイリアス、機密フィールド用の個別のコレクション。
マルチテナンシー:接頭辞/個々のデータベース/コレクション、'tenantId'によるフィルタ、アプリケーション内のRLS風のレイヤーを使用できます。
監査:重要なコレクションのオペレーションの監査を有効にします。


バックアップ、PITR、 DR

Point-in-Time Recoveryのボリュームのスナップショット+oplogバックアップ。
DR用の別の領域に設定されたレプリカ。定期的な回復演習。
挿入ピーク(PSP webhooks/tournaments)のoplog成長の制御。
シャードクラスタ-コンフィグサーバとの一貫したバックアップ。


他のアーキテクチャとの統合

CQRS:チームはSQL (money)、イベント→MongoDBのMaterialized Viewsをヒットしました。
イベントストリーミング:バスとしてのKafka/Pulsar、 Mongo-コネクタと変更ストリームを介してシンク/ソース。
Redis:超低レイテンシーレイヤー(キャッシュ/カウンタ)として近くにあります。
OLAP: ClickHouse/Pinotにアップロードして、長いスキャンとBIを実行します。


実装チェックリスト

1.ドメインを修正:Mongoで何が起こっているか(柔軟性/高TPS/投影)、 SQLに残っているもの。
2.スキーマ契約の定義:JSONスキーマ検証、'schemaVersion'。
3.実際のクエリのためのインデックスを設計します。ノイズの多いデータのTTLを追加します。
4.シャードキーを選択します(高いカーディナリティ、均一性)。必要に応じて-ゾーンシャーディング。
5.SLOのためのレプリカセット、読む/書く心配をセットアップして下さい;read-after-writeポリシー。
6./WT キャッシュ/oplogインデックスへの監視とプロファイル、アラートを有効にします。
7.バックアップ+PITR、 DRクラスタ、通常の演習を整理します。
8.Change Streams/Outboxを接続してキャッシュとバスを同期させます。
9.ドキュメントのサイズとネストを制限する。カーソルによるページネーションを実装します。
10.PII/テナント、暗号化、監査のための個別のポリシー。


アンチパターン

製品の「スキームなし」:検証とバージョンの欠如→カオス。
時間/単調なシャードキー-ホットシャードと不安定なp99。
インデックス/ペジネーションなしの巨大なセットでJoynes'$lookup'。
あらゆる場所でトランザクションを使用-生産性の低下。
ログのTTL/リテンションの欠如→ボリュームとコストの増加。
重要な金融不変量を厳格な特権なしでMongoにのみ保存します。


[結果]

MongoDBは柔軟なiGamingドメインのための強力なツールです:プロファイル、ディレクトリ、テレメトリー、投影とパーソナライズ。成功の鍵は、契約スキームと検証、思慮深いインデックス作成、適切に選択されたシャードキー、意識的な読み書き懸念、統合と厳格な運用規律(オブザビリティ、バックアップ、DR)の変更ストリームです。SQLコアとストリーミングバスを組み合わせることで、プラットフォームに高速なインターフェイスとトーナメントピークの安定性を提供します。

Contact

お問い合わせ

ご質問やサポートが必要な場合はお気軽にご連絡ください。いつでもお手伝いします!

統合を開始

Email は 必須。Telegram または WhatsApp は 任意

お名前 任意
Email 任意
件名 任意
メッセージ 任意
Telegram 任意
@
Telegram を入力いただいた場合、Email に加えてそちらにもご連絡します。
WhatsApp 任意
形式:+国番号と電話番号(例:+81XXXXXXXXX)。

ボタンを押すことで、データ処理に同意したものとみなされます。