11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【MongoDB】ObjectId以外のプライマリキーを使う

Last updated at Posted at 2020-05-02

MongoDBではObjectIdの代わりに任意の値をプライマリキーとして使うことができる

今回はMongoDBでのプライマリキー(主キー)の扱いの話です。

MongoDBでの主キーフィールドには実は任意の値を入れることが可能だったという話です。
調べても意外にもそのことに言及した書き込みが出てこなかったため書くことに。

まず前提から

MongoDBを使っていた際にプライマリキーにデフォルトのデータ型以外の値を入れたい場合が出てきました。

MongoDBではデフォルトのプライマリキーはObjectIdです。

MongoDBのObjectIdというのは12バイトの値を持つデータ型で、ドキュメント(RDBMSではレコードに相当)を作成するときにMongoDBによって自動的に生成されます。一意の値を持つように生成されるので、MongoDBではRDBMSにおける自動インクリメントされる整数に代わってプライマリキーとして使われます。

具体的には下のようなデータで、キーは必ず_idになります。

{ "_id" : ObjectId("507f1f77bcf86cd799439011") }

この_idにObjectId以外の値を入れたかったのですが、調べたところ次の記事に答えがありました。

_idフィールドの値はユーザー任意のデータで上書き可能

つまり、_idフィールドの値には文字列、整数(1, 2 etc...)や日付(JSのDateオブジェクト)を入れることも可能ということ。

ただしこの場合、{_id: 1}というようにユーザーが明示的に_idフィールドの値を書く必要があります1

もしも、入力データに_idフィールドがなかった場合はDB側で自動的にObjectId型のプライマリキーが生成される実装になっているようです。

このように上書き可能な値ですが、ObjectIdを任意の値で上書きするには1つだけ条件があります。それは...

  • _idフィールド内で一意な値をもつこと(値が同カラム内で重複しない)

考えてみればプライマリキーなので値が重複しないことが条件なのは当たり前といえば当たり前です2

UUIDなど一意な値を使うときに利用できるかも

値が一意でないといけないので、実際にObjectId以外だと使う場合が限られそうですが、
UUIDやULIDなどで代替したい場合にいいかも。

また、自動インクリメント整数をプライマリキーにすることも↓のような方法があるので組み合わせて実現できそうです。(こういう場合は素直にRDBMS使った方が楽だと思いますが)

  1. ちなみに_idというフィールド名を変更することはできない。必ず_idという名前のフィールドがプライマリキーになるようになっている。

  2. ちなみにMongoDBはスキーマレスなNoSQLなので_idフィールド内のデータの型は同じである必要はない。例えば同一フィールド内の値に整数と文字列が混ざっていても問題ない。

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?