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?

[Railsガイド]複数データベース接続対応について(更新中)

Last updated at Posted at 2025-01-31

データベースレベルでのスケールに対応するため、Railsには複数データベース対応がされている。

<主な機能>

  • 複数の「writer」データベースと、それぞれに対応する「replica」データベース
  • 作業中のモデルでのコネクション自動切り替え
  • HTTP verbや直近の書き込みに応じたwriterとreplicaの自動スワップ
  • 複数のデータベースの作成、削除、マイグレーション、各種操作を行うRailsタスク

※replicaのロードバランシングはまだ未対応

データベースへの接続設定について

まずActiveRecord経由でデータベースに接続するため、/config/database.ymlに対して、接続設定を定義する。

# 定義例

# 環境共通の設定
default: &default
  adapter: # 接続するDBの種類(sqlite3,mysql2,postgresqlなど)
  encoding: # 文字コード
  collation: # 照合順序
  pool: # 確保する接続プールの個数
  timeout: # 接続のタイムアウト時間
  socket: # ソケット
  host: # ホスト名/IPアドレス
  username: # ユーザー名
  password: # パスワード

# 開発環境の設定
development:
  primary:
    <<: *default # defaultの設定の共有
    database: # データベース名

# テスト環境の設定
test:
  primary:
    <<: *default
    database: 

# 本番環境の設定
production:
  primary:
    <<: *default
    database: 

アプリケーションのセットアップ

新しいテーブルを追加するケース

接続情報の定義

animalという名前の第2のデータベースを追加して、両方のデータベースにそれぞれreplicaを追加した場合の例

production:
  primary:
    database: my_primary_database
    username: root
    password: <%= ENV['ROOT_PASSWORD'] %>
    adapter: mysql2
  primary_replica:
    database: my_primary_database
    username: root_readonly
    password: <%= ENV['ROOT_READONLY_PASSWORD'] %>
    adapter: mysql2
    replica: true
  animals:
    database: my_animals_database
    username: animals_root
    password: <%= ENV['ANIMALS_ROOT_PASSWORD'] %>
    adapter: mysql2
    migrations_paths: db/animals_migrate
  animals_replica:
    database: my_animals_database
    username: animals_readonly
    password: <%= ENV['ANIMALS_READONLY_PASSWORD'] %>
    adapter: mysql2
    replica: true

複数のデータベースを用いる場合の重要な設定

  • primaryprimary_replicaのデータベース名は同じにする
    • 2つは同じデータを持つため
  • writerreplicaでは異なるデータベースユーザー名を使い、かつreplicaのパーミッションは(writeではなく)readのみにする
    • replica: trueというエントリがないと、どちらがreplicaでどちらがwriterかをRailsが区別できなくなる
  • 新しいwriterデータベース用のマイグレーションを置くディレクトリをmigrations_pathsキーに設定する

コネクションモデルのセットアップ

  • データベースへの接続は抽象クラスで定義する
  • connects_toメソッドを使用して、接続を定義する
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: { writing: :primary, reading: :primary_replica }
end
  • ApplicationRecordを別のクラス名に変えている場合は、primary_abstract_classを設定する
    • これにより、RailsはコネクションをどのクラスのActiveRecord::Baseと共有すべきかを認識できる
class PrimaryApplicationRecord < ActiveRecord::Base
  primary_abstract_class

  connects_to database: { writing: :primary, reading: :primary_replica }
end
  • 追加したデータベースへの接続は別の抽象クラスを定義する
class AnimalsRecord < ApplicationRecord
  self.abstract_class = true

  connects_to database: { writing: :animals, reading: :animals_replica }
end
  • 上記のコネクションモデルを継承したモデルクラスにて、それぞれのDBへクエリが発行される
class Car < ApplicationRecord
  # primaryデータベースに自動的に話しかける
end
  • ポイント
    • データベースへの接続を「単一のモデル内」で行うこと
    • そのモデルを継承してテーブルを利用すること
    • データベースクライアントがオープンできるコネクション数には上限がある。Railsはコネクションを指定する名前にモデル名を用いるので、同じデータベースに複数のモデルから接続するとコネクション数が増加する
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?