如何将分解为数据库的模型构建为36个表?

时间:2017-07-02 06:58:29

标签: ruby-on-rails postgresql ruby-on-rails-5

我有超过10亿个域名记录,而不是将它们全部放在一个表中,我决定将它们分成36个表(每个表的数据库结构相同)。

有一个基于域名第一个字符的表格(例如:domains_a ... domains_z)。

如何在rails中创建单个Domain模型,根据指定的字符自动在这些表之间切换?

3 个答案:

答案 0 :(得分:3)

通常,这种表分区是在数据库级别处理的。您应该指定您正在使用的数据库,因为这在这里非常相关。

例如,PostgreSQL具有基本的table partition支持。您可以将Rails模型指向主表,并且分区对Ruby层是透明的。

答案 1 :(得分:2)

你不能:你必须编写自己的逻辑来处理这个问题。 Rails需要知道您的业务逻辑并分析SQL查询以找出要选择的表,默认情况下不能这样做,您需要自己编写该代码。

然而有一个技巧会让你变得更加轻松。那么在数据库级别处理这个呢?我已经检查过,所有主要数据库都支持可更新视图

因此,创建一个新视图,将其命名为domains并确保它创建所有域表的 union (从a到z),然后创建模型:

class Domain
  self.table_name = "your_view_name"
end

这将为读取端提供技巧。现在基于您正在使用的数据库,您也许能够以这种方式解决写入问题(使用触发器和类似的DB功能),否则,您需要为写入部分编写自己的代码,这可能需要运行原始查询。

作为替代方案,您可以通过手动或使用生成器创建所有模型(DomainADomainB等)来在Ruby级别处理此问题,然后创建一个充当公共类的公共类一个界面。或者,您可以使用某些元编程创建这些模型,并再次使用一个公共类作为接口。

答案 2 :(得分:0)

表分区是要走的路。不要创建所有相同的表结构。

将为您提供哪些表格分区

  1. 您将拥有由数据库进行逻辑分区的单个表。
  2. 在应用程序视图中,您正在查询单个表,就像任何其他数据库表一样。
  3. 在数据库透视图中,它按分区存储数据,分区由分区类型和分区逻辑定义。在mysql中,您可以参考 https://dev.mysql.com/doc/refman/5.7/en/partitioning-types.html
  4. 如果正确定义,性能优势。它将避免扫描10亿行,而是在进行查询时扫描相关分区。
  5. 表分区可以是特定于数据库的。

    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的特定分区。

    您仍在通过单个表访问它,但数据按分区逻辑存储,具体取决于store_id。

    SELECT * FROM employee WHERE store_id = 10
    

    数据库只会查看分区p1并且不会扫描其他分区(p0,p2和p3),因为只是该查询永远不会在这些分区中找到数据。