0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

migrationで不整合を防ぐ

Last updated at Posted at 2024-07-17

はじめに

昨日コーディングインタビューにて「migrationファイルにおける不整合データの対策について」を問われた際にパッと答えることができなかったので、ここで供養していく。

問題

以下のようなテーブル定義のmigrationファイルがあった際、どのようにして不整合データの対策をしていくかといった内容。(以下Ruby on Railsのmigrationを例に)

  def up
    create_table :follows do |t|
      t.references :follow_to, foreign_key: { to_table: :users }
      t.references :follow_by, foreign_key: { to_table: :users }
      t.timestamps
    end
  end

よくあるsnsのユーザーフォローの機能のテーブルをイメージしていただきたい。
followsテーブルとusersテーブルは1:Nの関係になっている。

どんな不整合が起こりうるか

思いつくのは存在しないユーザーとの関連データ/欠損データ/重複データの3つ。

  • 存在しないユーザーとの関連データ
    • 外部キー(follow_to,follow_by)に出鱈目なユーザーのidを格納することで生じるデータ
  • 欠損データ
    • 外部キー(follow_to,follow_by)にnullが格納されることで、必要なリレーションが欠損したデータ
  • 重複データ
    • フォローしたユーザーとされたユーザーの組み合わせが同じなレコードを複数存在させたデータ

どうやって対策するのか

  • 存在しないユーザーとの関連データ
    • 上記migrationは既に対応済みではあるが、外部キー制約を付与することで存在するユーザーのみを格納するようにする(referenceやadd_foreign_key)
  • 欠損データ
    • NOT NULL制約をすることで、不完全なデータを作成しないようにする
  • 重複データ
    • follow_to,follow_byの組み合わせにindexを追加して、重複データが作成されないようにする

上記の対策を施したmigrationは以下のようになる。

  def up
    create_table :follows do |t|
      t.references :follow_to, null: false, foreign_key: { to_table: :users }
      t.references :follow_by, null: false, foreign_key: { to_table: :users }
      t.timestamps
    end
    add_index :follows, %i[follow_to_id follow_by_id], unique: true
  end
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?