5
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?

【Supabase】複数テーブルの関連データを取得したい

Posted at

はじめに

Supabaseから複数の関連テーブルからデータを取得しようとした際につまりました。

問題

以下の3つのテーブルを定義していました。
下記の手順でデータを取得したかったです。

  • usersテーブルのuser_idを元に、user_skillテーブルのuser_idを参照
  • user_skillテーブルのskill_idを元に、skillsテーブルのidを参照
  • skillsテーブルのnameを取得

  • usersテーブル
user_id: varchar name: varchar description: text a_id: varchar b_id: varchar c_id: varchar created_at: timestamptz
sample-id なまえ <h1>なまえ</h1> aのid bのid cのid 2025-XX-XX
  • user_skillテーブル
id: int8 user_id: varchar skill_id: int8 created_at: timestamptz
1 sample-id 1 2025-XX-XX
  • skillsテーブル
id: int8 name: varchar created_at: timestamptz
1 React 2025-XX-XX
2 TypeScript 2025-XX-XX
3 GitHub 2025-XX-XX

image.png

解決方法

user_skillテーブルに外部キーを設定する

  • user_skillテーブルのuser_idを外部キーとして設定
    (参照先はusersテーブルの主キー: user_id
  • user_skillテーブルのskill_idを外部キーとして設定
    (参照先はskillsテーブルの主キー: id

外部キーとは

あるテーブルのカラム(列)が別のテーブルの主キーを参照すること

なぜ外部キーの設定が必要?

外部整合制約のメリットをもらうため

データの整合性保持

skillsテーブルのid=1のレコードを削除した場合、user_skillテーブルのskill_id=1はどこも参照できず、ただのデータになってしまいます。

誤削除の防止

外部キーの設定を行うことで、意図せずレコードを削除してしまうことを防ぐことができます。

試しに、skill_id=1を消そうとすると、エラーとなり削除を防ぐことができました。

image.png

Supabaseのdashbordから外部キーを設定する

  1. user_skillテーブルのuser_idをクリック、Edit columnを選択

image.png

2. Add foreign keyを押下

image.png

3. 参照するテーブルを選択(今回はusersテーブル

image.png

4. 参照するカラムを選択(今回はuser_idカラム)選択後、Saveを押下

image.png

リレーションで取得するように修正

Supabaseでは外部キーの関係を自動的に検出して、簡単にデータを取得できます

  • 公式ドキュメントより引用

The data APIs automatically detect relationships between Postgres tables. Since Postgres is a relational database, this is a very common scenario.

(日本語訳)
データAPIは自動的にPostgresテーブル間の関係を検出します。Postgresはリレーショナルデータベースなので、これは非常に一般的なシナリオです。

  const { data, error } = await supabase
    .from("users")
    .select("*, user_skill(skills(name))")
    .eq("user_id", id);
  • from("users"): usersテーブルから取得する
  • .select("* : *でusersテーブルの全てのカラムを取得する
  • user_skill(): usersのuser_idと紐づくものを取得
  • skills(name):user_skillと紐づくidからskillsテーブルのidと紐づくものを取得

以下のSQLと同じことをしています。

SELECT 
  users.*,
  skills.name
FROM 
  users
LEFT JOIN 
  user_skill ON users.id = user_skill.user_id
LEFT JOIN 
  skills ON user_skill.skill_id = skills.id
WHERE 
  users.user_id = [id]

おわりに

外部キーをなぜ指定しないといけないのかわかっていない状態でした。
SQLの学習も進めていきたいです。

参考

5
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
5
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?