MongoDB - データベース
概要
MongoDBにおけるデータベースは、コレクションの集合である。
各データベースは、独立したストレージエンジンを持ち、独自の権限管理とバックアップが可能である。
MongoDBは、ドキュメント指向のNoSQLデータベースである。
階層構造は、[データベース] -> [コレクション] -> [ドキュメント] で構成される。
RDBMSとの用語対応
下表に、MongoDBとRDBMSの用語対応を示す。
| RDBMS | MongoDB | 説明 |
|---|---|---|
| データベース | データベース | コレクションやドキュメントの集合 |
| テーブル | コレクション | ドキュメントの集合 |
| 行 | ドキュメント | データの単位 |
| 列 | フィールド | データの属性 |
| インデックス | インデックス | 検索パフォーマンスを向上させる構造 |
| 主キー | _id フィールド | ドキュメントの一意識別子 (自動生成) |
システムデータベース
MongoDBインスタンスには、特別な用途を持つ3つのシステムデータベースが存在する。
これらは、MongoDBの内部動作や管理機能に使用される重要なデータベースである。
adminデータベース
adminデータベースは、認証、認可、管理機能に使用される。
主要なコレクションを以下に示す。
- system.users
- すべてのユーザ認証情報を保存する。
- データベース横断的な認証を管理する。
- system.roles
- ユーザ定義ロールの情報を保存する。
- カスタムロールの定義と権限を管理する。
adminデータベースは、MongoDBインスタンス全体の管理者権限を持つユーザを管理するために使用される。
localデータベース
localデータベースは、レプリケーション用メタデータとノード固有のデータを保存する。
主要な特徴を以下に示す。
- レプリケーションに含まれない
- 各ノードに独立して存在する。
- ノード固有のデータを保存する。
- system.replset
- レプリカセット設定情報を保存する。
- レプリケーショントポロジーの定義を管理する。
localデータベースは、レプリカセット環境において各ノードのローカル情報を管理するために使用される。
configデータベース
configデータベースは、シャーディング環境のメタデータを保存する。
このデータベースは、シャードクラスタのみに存在する。
主要なコレクションを以下に示す。
- config.collections
- シャード対象コレクションのメタデータを保存する。
- config.databases
- データベースとシャード分散情報を保存する。
- config.chunks
- チャンク情報 (データの分割単位) を保存する。
- config.shards
- シャード設定 (各シャードの接続情報) を保存する。
configデータベースは、シャーディング環境において、データの分散配置と管理を行うために使用される。
データベースの作成
基本的な作成方法
データベースを作成するには、use コマンドを使用する。
基本的な構文を以下に示す。
use <database_name>
指定されたデータベースがまだ存在しない場合、コマンドは失敗せずに接続状態を変更する。
データベースの実際の作成は、コレクション作成またはドキュメント挿入時に自動実行される。
使用例を以下に示す。
use myDatabase
db.myCollection.insertOne({ name: "Alice", age: 30 })
この例では、myDatabase というデータベースに接続し、myCollection というコレクションを作成して、ドキュメントを挿入している。
この操作により、データベースとコレクションの両方が自動的に作成される。
命名規則と制限
MongoDBのデータベース名には、以下の命名規則と制限がある。
許可される文字を以下に示す。
- ASCII文字 (a-z、A-Z)
- 数字 (0-9)
- アンダースコア (_)
使用不可な文字を以下に示す。
- ドット (.)
- コレクション区切り文字として予約されている。
- スペース
- データベース名に空白文字は使用できない。
- 特殊文字 (
$、@、#等)- 特殊な意味を持つため使用できない。
- ダブルクォート (")
- 構文解析の問題を避けるため使用できない。
- ヌル文字
- 文字列終端記号として予約されている。
その他の制限を以下に示す。
- 文字数上限
- データベース名は64文字以下でなければならない。
- 大文字小文字の区別
- MongoDBは大文字小文字を区別しない。
- salesData と SalesData は同じデータベースとして扱われる。
- 予約名
admin、local、configは、特別な目的で予約されている。- これらの名前は、ユーザデータベースとして使用しない。
推奨される命名規則を以下に示す。
- 小文字のみを使用する (例:
mydb、sales_data) - 意味のある名前を付ける (例:
userdb、inventory) - アンダースコアで単語を区切る (例:
sales_data、user_management)
既存データベースの確認
既存のデータベースを確認するには、show dbs コマンドを使用する。
show dbs
このコマンドは、存在するすべてのデータベース名と各データベースのディスク上のサイズを表示する。
# 実行例 admin 40.0 KB config 72.0 KB local 40.0 KB test 8.0 KB
※注意
- 空のデータベース (コレクションが存在しないデータベース) は表示されない。
useコマンドで接続しただけでは、データを挿入していないデータベースは表示されない。
データベースの削除
単一データベースの削除
データベースを削除するには、db.dropDatabase メソッドを使用する。
基本的な使用方法を以下に示す。
use temp
db.dropDatabase()
このコマンドは、現在接続されているデータベース (この例では temp) を削除する。
db.runCommandメソッドを使用する方法db.runCommand( { dropDatabase: 1 } )
- ライトコンサーンを指定する場合
db.runCommand( { dropDatabase: 1, writeConcern: { w: "majority", j: true, wtimeout: 5000 } } )
| パラメータ | 説明 |
|---|---|
writeConcern |
書き込み確認要件を指定する文書 (オプション) |
w |
確認応答の数 (デフォルト: majority)majority は過半数のレプリカからの確認を待つ。
|
j |
ジャーナルへの書き込み確認true の場合、ディスクへの書き込みが完了するまで待つ。
|
wtimeout |
タイムアウト時間 (ミリ秒) 指定した時間内に確認が得られない場合、エラーを返す。 |
削除時の注意事項
データベースを削除する場合には、以下の事柄に注意する必要がある。
- 不可逆的な操作
- この操作は不可逆的である。
- 削除されたデータベースは復旧できない。
- 削除前に必ずバックアップを取得すること。
- デフォルトのライトコンサーン
- デフォルトでは、
majorityライトコンサーンで実行される。 - 過半数のレプリカに削除が反映されるまで待機する。
- デフォルトでは、
- システムデータベースの削除
admin、local、config等のシステムデータベースは削除しない。- これらを削除すると、MongoDBインスタンスが正常に動作しなくなる。
- 実行権限
- データベースを削除するには、適切な権限 (
dbAdminまたはdbOwner) が必要である。
- データベースを削除するには、適切な権限 (
データベースの確認
show dbsコマンド
全てのデータベースを表示するには、show dbs コマンドを使用する。
show dbs
このコマンドは、存在する全てのデータベース名と各データベースのディスク上のサイズを表示する。
# 出力例 admin 40.0 KB config 72.0 KB local 40.0 KB mydb 8.0 KB test 4.0 KB
特徴を以下に示す。
- 空のデータベースは表示されない
- コレクションやドキュメントが存在しないデータベースは一覧に表示されない。
- サイズ情報を含む
- 各データベースがディスク上で占有しているサイズが表示される。
プログラム内でデータベース一覧を取得する方法を以下に示す。
db.adminCommand( { listDatabases: 1 } )
このコマンドは、JSON形式でデータベース情報を返す。
下表に、オプショナルパラメータを示す。
| パラメータ | 説明 |
|---|---|
filter |
返すデータベースをフィルタリングするクエリ述語 例: { name: { $regex: /^test/ } } で名前が test で始まるデータベースのみを返す。
|
nameOnly |
true の場合、データベース名のみ返す。サイズ情報等は含まれない。 |
authorizedDatabases |
アクセス制御有効時にユーザ権限に応じて返すデータベースを制御する。true の場合、ユーザがアクセス権限を持つデータベースのみを返す。
|
戻り値の例を以下に示す。
{
"databases" : [
{ "name" : "admin", "sizeOnDisk" : 83886080, "empty" : false },
{ "name" : "local", "sizeOnDisk" : 83886080, "empty" : false },
{ "name" : "test", "sizeOnDisk" : 83886080, "empty" : false }
],
"totalSize" : 251658240,
"totalSizeMb" : 251,
"ok" : 1
}
データベース名のみを取得する例を以下に示す。
db.adminCommand( { listDatabases: 1, nameOnly: true } )
db.getName() メソッド
現在のセッションで接続されているデータベース名を取得するには、db.getName() メソッドを使用する。
このメソッドは、スクリプトやアプリケーション内で現在のデータベースコンテキストを確認する場合に使用するとよい。
db.getName()
このメソッドは、現在接続されているデータベース名を文字列として返す。
使用例を以下に示す。
use myDatabase
db.getName()
# 出力例 myDatabase
db.statsメソッド
データベースの詳細な統計情報を取得する場合は、db.stats() メソッドを使用する。
このメソッドは、データベースの使用状況を監視し、容量計画を立てる場合に使用するとよい。
基本的な使用方法を以下に示す。
db.stats()
単位を指定する場合の使用方法を以下に示す。
db.stats(1024)
このコマンドは、サイズをキロバイト単位で返す。
フリーストレージを含める場合の使用方法を以下に示す。
db.stats( { freeStorage: 1, scale: 1024 } )
下表に、主要な戻り値フィールドを示す。
| フィールド | 説明 |
|---|---|
db |
データベース名 |
collections |
コレクション数 |
views |
ビュー数 |
objects |
ドキュメント総数 |
avgObjSize |
平均ドキュメントサイズ |
dataSize |
ドキュメント内に格納された未圧縮データの総サイズ |
storageSize |
ドキュメント保存に割り当てられたストレージ総容量 |
indexes |
インデックス総数 |
indexSize |
全てのインデックスに割り当てられたディスク容量 |
totalSize |
ドキュメントとインデックスの両方に割り当てられたディスク容量合計 |
fsUsedSize |
ファイルシステム全体で使用中のディスク容量 |
fsTotalSize |
ファイルシステムの総容量。 |
出力例を以下に示す。
{
"db" : "mydb",
"collections" : 5,
"views" : 0,
"objects" : 1000,
"avgObjSize" : 256.5,
"dataSize" : 256500,
"storageSize" : 512000,
"indexes" : 10,
"indexSize" : 102400,
"totalSize" : 614400,
"fsUsedSize" : 10240000000,
"fsTotalSize" : 51200000000,
"ok" : 1
}
データベースのバックアップとリストア
mongodumpコマンド
MongoDBのデータベースをバックアップするには、mongodump コマンドを使用する。
このコマンドは、BSON形式でデータをエクスポートする。
基本的な使用方法を以下に示す。
mongodump
このコマンドは、デフォルトで現在のディレクトリに dump/ というディレクトリを作成し、全データベースをバックアップする。
出力先を指定する場合の使用方法を以下に示す。
mongodump --out=/opt/backup/mongodump-1
認証を使用する場合の使用方法を以下に示す。
mongodump \
--host=mongodb1.example.net \
--port=3017 \
--username=user \
--password="pass" \
--out=/opt/backup/mongodump-1
主要なオプションを下表に示す。
| オプション | 説明 |
|---|---|
--out=<path> |
バックアップ出力先ディレクトリを指定する。 デフォルトは ./dump/ である。 |
--host=<hostname[:port]> |
接続先ホストを指定する。 デフォルトは、localhost である。 |
--port=<port> |
接続先ポートを指定する。 デフォルトは 27017 である。 |
--username=<user> |
認証ユーザ名を指定する。 |
--password=<pass> |
認証パスワードを指定する。 |
--authenticationDatabase=<db> |
認証データベースを指定する。 デフォルトは admin である。 |
--db=<database> |
特定データベースのみバックアップする。 |
--collection=<collection> |
特定コレクションのみバックアップする。 |
--gzip |
gzip圧縮でバックアップファイルを出力する。 |
- 特定データベースをバックアップする例
mongodump --db=mydb --out=/opt/backup/mydb-backup
- 特定コレクションをバックアップする例
mongodump --db=mydb --collection=users --out=/opt/backup/users-backup
- gzip圧縮を使用する例
mongodump --db=mydb --gzip --out=/opt/backup/mydb-compressed
mongorestoreコマンド
バックアップからデータベースを復元するには、mongorestore コマンドを使用する。
基本的な使用方法を以下に示す。
mongorestore /opt/backup/mongodump-1
このコマンドは、指定されたディレクトリから全てのデータベースを復元する。
接続文字列を使用する方法を以下に示す。
mongorestore --uri mongodb://localhost:27017 /opt/backup/mongodump-1
下表に、主要なオプションを示す。
| オプション | 説明 |
|---|---|
--host--port--username--password--authenticationDatabase |
mongodump コマンドと同様の認証オプション。
|
--db=<database> |
特定データベースのみ復元する。 |
--collection=<collection> |
特定コレクションのみ復元する。 |
--drop |
復元対象コレクションをあらかじめ削除する。 既存データを完全に置き換える場合に使用する。 |
--gzip |
gzip圧縮されたバックアップから復元する。 |
- 特定データベースを復元する例
- mongorestore --db=mydb /opt/backup/mongodump-1/mydb
- 既存データを削除してから復元する例
- mongorestore --db=mydb --drop /opt/backup/mongodump-1/mydb
- gzip圧縮されたバックアップを復元する例
- mongorestore --db=mydb --gzip /opt/backup/mydb-compressed/mydb
- 認証を使用する例
mongorestore \ --host=mongodb1.example.net \ --port=3017 \ --username=user \ --password="pass" \ --authenticationDatabase=admin \ /opt/backup/mongodump-1
※注意
- バックアップとリストアは、MongoDBのバージョン間で互換性がある
- ただし、メジャーバージョン間では互換性が保証されない場合がある。
- 大規模データベースのリストアには時間が掛かる
- 本番環境でのリストアは、メンテナンス時間を確保して実施すること。
--dropオプションは慎重に使用する- 既存データが完全に削除されるため、誤操作に注意すること。
データベースの権限管理
データベースレベルの権限
MongoDBでは、データベースレベルで権限を管理できる。
主要な権限ロールを以下に示す。
readロール
read ロールは、指定されたデータベースへの読み取り専用アクセスを提供する。
許可されるアクションを以下に示す。
- find
- ドキュメントの検索。
- listCollections
- コレクション一覧の取得。
- listIndexes
- インデックス一覧の取得。
read ロールは、データを参照するだけで変更を行わないユーザに適している。
readWriteロール
readWrite ロールは、指定されたデータベースへの読み取りと書き込みアクセスを提供する。
許可されるアクションを以下に示す。
- find、insert、update、remove
- ドキュメントの検索、挿入、更新、削除。
- createCollection、dropCollection
- コレクションの作成と削除。
- createIndex、dropIndex
- インデックスの作成と削除。
readWrite ロールは、データベースの日常的な操作を行うユーザに適している。
dbAdminロール
dbAdmin ロールは、データベース管理タスクの実行を許可する。
許可されるアクションを以下に示す。
- インデックス管理
- インデックスの作成、削除、再構築。
- 統計情報取得
- データベースの統計情報とパフォーマンスメトリクスの取得。
- コレクション操作
- コレクションの名前変更、オプション変更。
- スキーマ検証
- スキーマ検証ルールの設定と変更。
dbAdmin ロールは、データベースの構造やパフォーマンスを管理する管理者に適している。
dbOwnerロール
dbOwner ロールは、dbAdmin、readWrite、userAdmin ロールを結合したものである。
これは、完全なデータベース管理と所有権を提供する。
dbOwner ロールは、データベースの完全な管理権限を持つ所有者に適している。
ユーザの作成と権限付与
データベースにユーザを作成し、権限を付与する方法を以下に示す。
ユーザの作成
db.createUser メソッドを使用してユーザを作成する。
以下の例では、productsデータベースにaccountUserというユーザを作成し、readWriteとdbAdminロールを付与している。
passwordPrompt関数は、パスワードの入力を促すものである。
use products
db.createUser({
user: "accountUser",
pwd: passwordPrompt(),
roles: [ "readWrite", "dbAdmin" ]
})
複数ロール割り当ての例
複数のデータベースにまたがってロールを割り当てる例を以下に示す。
以下の例では、dbadminユーザに対して以下に示す権限を付与している。
- mydbデータベースへの読み取りと書き込みアクセス
- mydbデータベースの管理権限
- analyticsデータベースへの読み取り専用アクセス
use admin
db.createUser({
user: "dbadmin",
pwd: "securePassword",
roles: [
{ role: "readWrite", db: "mydb" },
{ role: "dbAdmin", db: "mydb" },
{ role: "read", db: "analytics" }
]
})
既存ユーザへのロール付与
既存のユーザにロールを追加するには、db.grantRolesToUser メソッドを使用する。
以下の例では、accountUser01ユーザにproductsデータベースへのreadWriteロールを追加している。
use admin
db.grantRolesToUser(
"accountUser01",
[ { role: "readWrite", db: "products" } ]
)
ユーザのロール確認
ユーザに付与されているロールを確認するには、db.getUser メソッドを使用する。
use admin
db.getUser("accountUser01")
ユーザのロール削除
ユーザからロールを削除するには、db.revokeRolesFromUser メソッドを使用する。
use admin
db.revokeRolesFromUser(
"accountUser01",
[ { role: "readWrite", db: "products" } ]
)
ユーザの削除
ユーザを削除するには、db.dropUser メソッドを使用する。
use admin
db.dropUser("accountUser01")
シャーディング環境でのデータベース
シャーディング環境では、データベースを複数のシャードに分散させることができる。
これにより、大規模なデータセットを水平方向にスケールアウトすることが可能になる。
シャーディングの有効化
データベースでシャーディングを有効にするには、sh.enableSharding メソッドを使用する。
基本的な使用方法を以下に示す。
sh.enableSharding("shardTest")
このコマンドは、shardTest データベースでシャーディングを有効にする。
プライマリシャードを指定する場合の使用方法を以下に示す。
以下の例では、shard1 をプライマリシャードとして指定している。
プライマリシャードは、シャードされていないコレクションのデータを保持するシャードである。
sh.enableSharding("shardTest", "shard1")
db.adminCommand メソッドを使用する方法を以下に示す。
db.adminCommand( { enableSharding: "shardTest" } )
※注意
- mongosインスタンスから実行
- シャーディングコマンドは、
mongosインスタンスから実行する必要がある。 mongodインスタンスから実行することはできない。
- シャーディングコマンドは、
- adminデータベースに対して実行
- シャーディングコマンドは、
adminデータベースに接続して実行する。
- シャーディングコマンドは、
- MongoDB 6.0以降の変更
- MongoDB 6.0以降では、
sh.enableSharding実行はコレクションシャーディング時にオプションである。 - コレクションをシャードする場合に、データベースのシャーディングが自動的に有効化される。
- MongoDB 6.0以降では、
コレクションのシャーディング
データベースのシャーディングを有効にした後、個々のコレクションをシャードする必要がある。
以下の例では、shardTest.users コレクション を userId フィールドをシャードキーとしてシャードしている。
sh.shardCollection("shardTest.users", { userId: 1 })
シャーディング状態の確認
データベースのシャーディング状態を確認する。
このコマンドは、シャードクラスタの状態、データベース、コレクション、チャンクの分散情報を表示する。
sh.status()
関連情報
- MongoDB公式ドキュメント - データベースとコレクション
- MongoDB公式ドキュメント - dropDatabase
- MongoDB公式ドキュメント - db.stats()
- MongoDB公式ドキュメント - mongodump
- MongoDB公式ドキュメント - mongorestore
- MongoDB公式ドキュメント - ビルトインロール
- MongoDB公式ドキュメント - シャーディング