Ruby on rails 如何将分解到数据库中的模型构造为36个表?

Ruby on rails 如何将分解到数据库中的模型构造为36个表?,ruby-on-rails,postgresql,ruby-on-rails-5,Ruby On Rails,Postgresql,Ruby On Rails 5,我有超过10亿个域名记录,我没有将它们全部放在一个表中,而是决定将它们分成36个表(每个表的db结构相同) 有一个基于域名第一个字符的表(例如表:domains\u a…domains\u z) 如何在rails中创建一个单一的域模型,根据指定的字符自动在这些表之间无缝切换?你不能:你必须编写自己的逻辑来处理这个问题。Rails需要了解您的业务逻辑并分析SQL查询,以确定要选择哪个表,而默认情况下,您不能这样做,您需要自己编写代码 然而,有一个技巧,将使它非常容易为您。在数据库级别处理这个问题怎

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

有一个基于域名第一个字符的表(例如表:
domains\u a
domains\u z


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

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

然而,有一个技巧,将使它非常容易为您。在数据库级别处理这个问题怎么样?我已经检查过,所有主要数据库都支持可更新视图

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

class Domain
  self.table_name = "your_view_name"
end
这对读取端来说是可行的。现在,基于您正在使用的数据库,您可能还可以通过这种方式(使用触发器和类似的DB功能)解决写入问题,否则,您需要为写入部分编写自己的代码,这可能需要运行原始查询


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

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


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

表分区是一种方法。不要创建所有相同的表结构

表分区将为您提供什么

  • 您将有一个由数据库逻辑分区的表
  • 在应用程序视图中,查询单个表就像查询任何其他数据库表一样
  • 在数据库透视图中,它按分区存储数据,分区由分区类型和分区逻辑定义。在mysql中,您可以参考
  • 如果定义正确,性能优势。它将避免扫描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
    );
    
    根据员工所属的存储区(存储区id),员工被存储到p0、p1、p2或p3的特定分区

    您仍然通过单个表访问它,但数据是根据存储id按分区逻辑存储的

    SELECT * FROM employee WHERE store_id = 10
    

    数据库将只查看分区p1,而不扫描其他分区(p0、p2和p3),因为简单地说,该查询永远不会在这些分区中找到数据。

    使用ymal如何?您究竟为什么要分解数据?除非你有充分的理由,否则这是一个错误。10亿条记录对于例如postresql来说并不是那么大。它允许32 TB的表。因此,只要您的记录小于等于30Kb,您就可以继续使用。MySQL允许使用非常大的表。请指定您使用的数据库——任何解决方案都会严重涉及特定于数据库的功能。@Gene,因为大量插入由于索引而变得非常缓慢。某些阅读也有同样的问题。对表进行分区有助于大大减少延迟。@AdamLassek PostgresIs在Postgres表分区中,如果范围值被更新,有没有一种方法可以自动将行移动到适当的分区?