UniProt/SwissProt を ActiveRecord でモデル化

タンパク質知識ベース UniProt/SwissProt を ActiveRecord でモデル化してみました.ActiveRecordRuby on Rails を構成する O/R マッパーです.ActiveRecord でどのようにして UniProt のエントリをモデル化の一例を解説します.

モデル設計

UniProt/SwissProt はタンパク質配列とそのアノテーションのデータベースなので,エントリは配列単位となっています.ただし,複数の生物種でアミノ酸配列が一致するタンパク質はそれぞれ別エントリになっています.
エントリには,タンパク質配列に付与される情報とその情報の根拠となる論文やデータベースの記載がついています.

エントリの構成要素の関係を考える

エントリの構成要素は,関係によって 3 種類に分けることができます.

  1. 遺伝子名(GN)のように,エントリあたり0もしくは1個だけ存在できるものは,エントリと has_one (一対一)関係になります.
    1. ID 行
    2. 日付(DT)
    3. 定義(DF)
    4. 遺伝子名(GN)
    5. 配列情報(SQ)
    6. アミノ酸配列
  2. アクセッション(AC)のように,エントリあたりに複数存在しているものは,エントリと has_many (一対多)関係になります.
    1. アクセッション(AC)
    2. 参考文献(R)
    3. コメント(CC)
    4. データベースリンク(DR)
    5. 特徴(FT)
  3. 生物種名(OS)のように複数のエントリと関連があるものは,エントリと has_and_belongs_to_many (多対多)関係になります.
    1. 生物種名(OS)
    2. 系統カテゴリ(OC)
    3. 生物種データベースリンク(OX)
    4. キーワード(KW)
Entry の ActiveRecord モデル

エントリとその構成要素の関係にもとづいて,エントリを ActiveRecord でモデル化します.has_one 関係はひとつのテーブルの中で表現することができるので,基本的にここにはあらわれません.ただし,遺伝子名は遺伝子名と別名の関係などがあるのでエントリのテーブルの中では扱えないのであらわれています.

 1: class エントリ < ActiveRecord::Base
 2:   has_many :アクセッション
 3:   has_one :遺伝子名
 4:   has_and_belongs_to_many :生物種名
 5:   has_and_belongs_to_many :系統カテゴリ
 6:   has_and_belongs_to_many :生物種データベースリンク
 7:   has_many :参考文献
 8:   has_many :コメント
 9:   has_many :データベースリンク
10:   has_and_belongs_to_many :キーワード
11:   has_many :特徴
12: end
 1: class Entry < ActiveRecord::Base
 2:   has_many :acs
 3:   has_one :gn, :include => [:loci, :synonyms, :orf_names]
 4:   has_and_belongs_to_many :oss,  :join_table => :entries_oss
 5:   has_and_belongs_to_many :ocs
 6:   has_and_belongs_to_many :oxs, :join_table => :entries_oxs
 7:   has_many :refs, :include => [:rxs, :rgs, :rps, :rcs]
 8:   has_many :ccs
 9:   has_many :drs
10:   has_and_belongs_to_many :kws
11:   has_many :fts
12: end
class CreateEntries < ActiveRecord::Migration
  def self.up
    create_table(:entries) do |t|
      t.column(:name, :string)
      t.column(:data_class, :string)
      t.column(:molecular_type, :string)
      t.column(:sequence_length, :integer)
      t.column(:entry_type, :string)
      t.column(:dt_create, :string)
      t.column(:dt_sequence, :string)
      t.column(:dt_annotation, :string)
      t.column(:definition, :string)
      t.column(:sequence, :text)
      t.column(:mw, :integer)
      t.column(:crc64, :string)
    end