2017-07-02 5 views
11

私は1つのテーブルにすべてを入れるのではなく、36個のテーブル(各テーブルの同じDB構造)に分割することにしました。36テーブルとしてデータベースに分割されたモデルを構造化する方法は?

ドメイン名の最初の文字(例:domains_a ... domains_z)に基づく表があります。

Domainモデルを、指定された文字に基づいてシームレスにこれらのテーブルを自動的に切り替えるレールで作成するにはどうすればよいですか?

+0

ymalの使用はいかがですか? –

+4

なぜあなたはデータを分割しましたか?優秀な理由がない限り、これは間違いです。 10億のレコードは、例えば、 postresql。 32 TBのテーブルが可能です。あなたの記録が30Kb以下であれば、あなたは良いことです。 MySQLでは、ずっと大きなテーブルが可能です。 – Gene

+2

使用しているデータベースを指定してください。どのような解決策でもDB固有の機能が大きく関わっています。 –

答えて

2

:あなたはそれに対処する独自のロジックを書く必要があります。 Railsはあなたのビジネスロジックを知り、SQLクエリを分析して、どのテーブルを選ぶべきかを見つけ出す必要があり、デフォルトでそれを行うことはできません。自分でコードを書く必要があります。

でも、あなたにとっては非常に簡単になるテクニックがあります。これをデータベースレベルで扱うのはどうですか?私はチェックして、すべての主要なデータベースは更新可能なビューをサポートしています。だから、

、新しいビューを作成し、名前をdomainsし、それが(からZまでの)すべてのドメインテーブルの組合を作成することを確認し、そのモデルをcreatea:

class Domain 
    self.table_name = "your_view_name" 
end 

これはどうしたらトリックfor 読み取り側。今使用しているデータベースに基づいて、このような方法で書き込み問題を解決することができます(トリガーなどのDB機能を使用)。そうでなければ、書き込み部分に独自のコードを書く必要があります。生のクエリを実行します。

代わりに、Rubyレベルで、すべてのモデル(DomainADomainBなど)を手動またはジェネレータで作成し、インタフェースとして機能する共通クラスを作成することができます。あるいは、ある種のメタプログラミングを使ってそれらのモデルを作成し、再びインターフェイスとして機能する共通のクラスを持つことができます。

3

通常、この種のテーブル分割はデータベースレベルで処理されます。使用しているデータベースを指定する必要があります。なぜなら、これはここで非常に重要な意味を持つからです。

例えば、PostgreSQLは基本的にtable partitionをサポートしています。 Railsモデルをマスターテーブルに向けると、パーティションはRubyレイヤーに透過的になります。

+0

範囲値が更新された場合、自動的に行を適切なパーティションに移動する方法はありますか? – Jacob

0

テーブルの分割は、方法です。同じテーブル構造をすべて作成しないでください。あなたは論理的にデータベースによって仕切られている単一のテーブルを持っていますあなたの

  1. 何テーブルパーティショニングを提供します。

  2. アプリケーションビューでは、他のデータベーステーブルと同じように単一のテーブルをクエリしています。
  3. データベースパースペクティブでは、パーティションタイプとパーティションロジックで定義されたパーティション単位でデータを格納します。 mysqlでは、参照することができます https://dev.mysql.com/doc/refman/5.7/en/partitioning-types.html
  4. パフォーマンスの利点が正しく定義されている場合。10億の行をスキャンするのではなく、クエリを実行するときに関連するパーティションをスキャンします。

テーブルパーティションは非常にデータベース固有のものです。

mysqlの簡単な例です。

CREATE TABLE employees (
    id INT NOT NULL, 
    fname VARCHAR(30), 
    lname VARCHAR(30), 
    hired DATE NOT NULL DEFAULT '1970-01-01', 
    separated DATE NOT NULL DEFAULT '9999-12-31', 
    job_code INT NOT NULL, 
    store_id INT NOT NULL 
) 
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6), 
    PARTITION p1 VALUES LESS THAN (11), 
    PARTITION p2 VALUES LESS THAN (16), 
    PARTITION p3 VALUES LESS THAN MAXVALUE 
); 

従業員は、店舗(STORE_ID)従業員が所属に応じていずれかのP0、P1、P2またはP3に特定のパーティションに格納されています。

まだ1つのテーブルでアクセスしていますが、データはstore_idに応じて論理的にパーティションに格納されます。

SELECT * FROM employee WHERE store_id = 10 

データベースは、単にパーティションP1を見ていきますと、単純にそのクエリは、これらのパーティション内のデータを見つけることはありませんので、他のパーティション(P0、P2とP3)をスキャンしません。

関連する問題