Django 基于 PK 和另一个字段保存对象



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

通过谷歌搜索这个主题,我发现 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 透明的数据库中进行。但是,我不确定是否可以在数据库中创建这样的主键。

感谢您的帮助

我同意你最好把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();

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

相关内容

  • 没有找到相关文章

最新更新