3
1

PrismaのSchemaの@idと@@idの違い

Last updated at Posted at 2023-09-29

TL;DR

@idは一つのフィールドの値をそのまま主キーにしたいときに使う属性です。
@@idは、複数のフィールドの値を組み合わせた値を主キーにしたいときに使う属性です。

@idを使ったサンプルコード

schema.prisma
model User {
  id   String @id
  name String
}
const newUser = await prisma.user.create({
  data: {
    id: 1,
    name: 'Alice',
  },
})

上記のコードでnewUserを作成した場合、このnewUserの主キーidは1になります。

そのため、以下のコードで一意のuserを探すことができます。

const user = await prisma.user.findUnique({
  where: {
    id: 1,
})

@@idを使ったサンプルコード

schema.prisma
model User {
  id   String
  name String
  @@id([id, name])
}
const newUser = await prisma.user.create({
  data: {
    id: 1,
    name: 'Alice',
  },
})

上記のコードでnewUserを作成した場合、newUserの主キーid_nameは、1_Aliceになります。

そのため、以下のコードで一意のuserを探すことができます。

const user = await prisma.user.findUnique({
  where: {
    id_name: {
      id: 1,
      name: 'Alice',
    },
  },
})

そもそも@と@@の違い

属性は、フィールドやブロックの動きを編集するのですが、データモデルに属性を追加するのには2つの方法があります。

フィールドに対して属性を追加するなら、属性の頭に@をつけます。
ブロックに対して属性を追加するなら、属性の頭に@@をつけます。

@id@@idの他に、@map@@mapのような属性も存在します。


ここから下は意見です。

複合主キーのデメリット

主キーとして用いているフィールドの値に修正が入った場合に、修正コストが高いです。
例えば、Aliceさんが名前を、Bobさんに変更した場合は1_Alice1_Bobに変更になります。
外部テーブルからこのレコードが参照されている場合、そちらも変更する必要があります。

@id@@idのどちらを使うべき?

複合主キーのフィールドの値が二度と変更されない場合は、複合主キーを使っても良いです。
例えば、下記のような中間テーブルでは、postIdとuserIdは変更される可能性が低いので使うことができます。

model Like {
  postId String
  userId String
  @@id([postId, userId])
}

しかし、基本的には、サロゲートキーを使うべきです。

参考文献

https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#remarks-5
https://scrapbox.io/mrsekut-p/サロゲートキー_v.s._複合主キーでは、前者を選ぶ
https://zenn.dev/kaz_z/articles/prisma-unique-key
https://scrapbox.io/mrsekut-p/ナチュラルキーがある時はサロゲートキーは不要

3
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
3
1