2

我正在尝试将 postgresql 中的分区表与 Django 安装一起使用。

通过 Google 搜索主题,我发现 Django 本身不支持分区,所以我自己对表进行了分区。我根据第二个字段对我的表进行分区,该字段是另一个表上的外键。基本模型设置如下:

class Event(models.Model):
    id = models.AutoField(primary_key=True)
    device = models.ForeignKey("Device")
    ... (More Fields)

我已经按 device_id 对表进行了分区,生成了诸如 event_1、event_2 等子表。我所有的查询都包含设备 id,因此查询现在要快得多,但是对于插入,django 会生成一个 UPDATE 语句,例如:

UPDATE event SET device=X, ...=X, ... WHERE id=XXX

这导致数据库遍历表的所有分区以查找指定的 ID。由于 device_id 永远不会改变,我现在想将 device_id=XXX 语句添加到 UPDATE 语句的 WHERE 部分,这将允许数据库只遍历一个分区。

我认为我的问题只是问题的结果,我的数据库的主键中没有分区键,但是由于 django 只支持一个字段作为 PK 并且分区键不是唯一的,我可以不要拿来当PK。

我可以想到两个解决我的问题的方法:

  1. 使用主键字段,它以某种方式自动从增加的数字与 device_id 组合(如 1_234)构建。然后,数据库必须拆分主键以了解此事件针对哪个设备以及它需要在哪个分区中搜索。
  2. 更改 UPDATE 语句,以便将 device_id 添加到 WHERE 语句。

我认为最优雅的方法是将 device_id 包含在主键中。因此,不需要对 Django 进行任何更改,并且分区只会发生在对 Django 透明的数据库中。但是我不确定是否可以在数据库中创建这样的主键。

谢谢您的帮助

4

1 回答 1

1

我同意您最好将 Django 排除在外。虽然我从来没有做过类似的事情,但我认为创建一个插入前触发器来构造新的连接主键会很容易。像这样的东西:

CREATE TABLE foo(
  id TEXT NOT NULL,
  device_id INT NOT NULL,
  CONSTRAINT foo_pkey PRIMARY KEY (id)
);

CREATE SEQUENCE foo_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;

CREATE OR REPLACE FUNCTION generate_foo_id()
  RETURNS trigger AS
$BODY$
BEGIN
  NEW.id :=  NEW.device_id || '_' || nextval('foo_id_seq');
  RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

CREATE TRIGGER trigger_generate_foo_id
  BEFORE INSERT
  ON foo
  FOR EACH ROW
  EXECUTE PROCEDURE generate_foo_id();

你是对的,你的分区函数将不得不拆分它。我从未创建过执行此操作的分区函数,但我不知道为什么它不起作用。但是,您应该测试并在您的结果中添加对此“答案”的评论(以便未来的用户将从您的测试中受益)。

于 2013-10-31T16:21:01.947 回答