レールとポリモーフィックな関係

多態的なリンクの例で出会ったRailsチュートリアルのほとんどには、これらのリンクのタイプ選択に関する興味深い機能があります。これについては、この投稿で説明します。



Railsでは、さまざまなタイプのポリモーフィックオブジェクト間に接続が確立されます。 これらのオブジェクトはすべて、いくつかの共通の特性を共有しているが、質的な表現が異なると想定されています。 多態的な関係は、スーパータイプとサブタイプの関係を実装する1つの方法です。



3つのモデルを検討してください。

  1. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  2. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  3. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  4. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  5. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  6. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  7. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  8. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end



  9. class Post < ActiveRecord::Base has_many :comments , :as => :resource end class Image < ActiveRecord::Base has_many :comments , :as => :resource end class Comment < ActiveRecord::Base belongs_to :resource , :polymorphic => true end







このようなスキームでは、Commentモデルのresource_typeおよびresource_idフィールドが必要です。また、Railsマニュアルでは、resource_typeをVARCHAR(255)として標準的に定義しています。 長い間、私はこれに注意を払っていませんでしたが、先日、このフィールドをEnum( 'Post'、 'Image')NOT NULLのようにしないでください。問題なく動作します。



ENUMを使用することの利点を確認するために、私は少しの経験をして、上記のモデルで2つのRailsアプリケーションを作成しました。 アプリケーションごとに、特別なスクリプトを使用して、次のように2つの同一のデータセットを形成しました:1,000個の投稿と画像を生成し、作成された各コメントがランダムな投稿または画像にランダムにマッピングされるように1,000,000個のコメントをランダムに生成しました。 複合インデックス(resource_type、resource_id)が導入されましたが、これがコメントを異なるものにしたかった方法です。



データを生成した後、ID 100、200、...、1000の投稿のコントロールサンプルを実行し、実験結果をプレートで提供します。 テストはMySQLバージョン5.1.37–1ubuntu5で実施されました



結果の表



表の簡単な説明:

T1-resource_type VARCHAR(10)NOT NULLのテーブル。

T2-resource_type ENUM( 'Post'、 'Image')NOT NULLのテーブル。

列3および5には、フォームのリクエストの実行時間が含まれています

SELECT * FROM `comments` WHERE resource_type = 'Post' AND resource_id = N1;。

列4および6には、フォームのリクエストの実行時間が含まれています

SELECT * FROM `posts`内部結合コメントON` comments`.resource_type = 'Post' AND` comments`.resource_id = `posts`.id WHERE` posts`.id = N1。

Nは実験番号、N1 = N * 100です。



その後、多型結合にENUMフィールドを使用するのが理にかなっていると思います。 しかし、これまでのところ、落とし穴が何であるかは明確ではありませんか? ポリモーフィックボンドと国民経済におけるそれらの使用に関するあなたの考えは何ですか?)



All Articles