1

我有一个大型 Web 应用程序,它每天将数百万行写入 PostgreSQL 中的分区表(这意味着每天的数据都有一个新表)。

我们正在使用PostgreSQL 的表继承和分区来加快速度:

由于我们的数据库中有一年的数据,我们无法有效地使用插入触发器将内容路由到正确的表(函数的长度变得非常非常长)。

长话短说,我们需要 ActiveRecord 来知道哪个表insertupdate数据。但是,不要更改用于选择和其他数据库任务的表。

显然,为模型定义表名很简单,但是是否可以仅针对特定操作覆盖表名?

这里有更多细节:

数据库:

  • 表: dashboard.impressions(id、主机、数据、created_on 等)
  • 表: data.impressions_20120801(继承自dashboard.impressions,约束created_on等于表日期)

Impression.create :host=>"localhost", :data=>"{...}", created_on=>DateTime.now应该写入data.impressions_20120801表,Impression.where(:host=>"localhost")应该在哪里搜索dashboard.impressions表,因为它包含所有数据。

编辑:我正在运行 PostgreSQL 9.1 和 Rails 3.2.6

4

1 回答 1

1

我不做 Rails,所以我无法在 ActiveRecord 方面提供帮助,但如果你不能让 ActiveRecord 做你想做的事,我可以提供一个纯 Pg 后备解决方案。它会花费您一点点插入性能,因此教 ActiveRecord 将插入到正确的位置会更好。

就我个人而言,我只是INSERT通过 gem 直接执行 spg并完全绕过 ActiveRecord。如果您不能这样做,或者 ActiveRecord 进行了缓存,这意味着您不应该这样做,请尝试这种备用分区触发器实现。

不要在触发函数中明确列出每个分区,而是考虑EXECUTE ... USING插入,并使用您的命名方案生成分区名称。像未经测试的东西:

CREATE OR REPLACE FUNCTION partition_trigger() RETURNS trigger AS $$
DECLARE
    target_partition text;
BEGIN
    IF tg_op = 'INSERT' THEN
        target_partition = ( ... work out the partition name ... )
        EXECUTE 'INSERT INTO '||quote_ident(target_partition)||' (col1,col2) VALUES ($1, $2)'
            USING (NEW.col1, NEW.col2);
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
于 2012-08-29T02:08:04.897 回答