2013-10-31 4 views
2

postgresql에서 파티션 된 테이블을 장고 설치와 함께 사용하려고합니다.Django PK 및 다른 필드를 기반으로 개체 저장

Google에서이 주제를 통해 장고가 자체적으로 파티션을 지원하지 않는다는 것을 알게되었으므로 직접 테이블을 분할했습니다. 다른 테이블의 외래 키인 두 번째 필드를 기반으로 테이블을 분할합니다. 기본 모델 설정이 너무과 같다 :

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

나는 내 모든 querys 장치 ID를 포함 event_2 등 event_1 같은 서브 테이블을 생성하는 DEVICE_ID하여 테이블을 분할 한, 그래서 querys는 이제 훨씬 더 빨리, 그러나

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

이 지정된 ID를 찾기 위해 테이블의 모든 파티션을 가로 지르는 데이터베이스 결과 : 삽입, 장고는 같은 UPDATE 문을 생성합니다. device_id가 절대로 변경되지 않기 때문에, 이제는 UPDATE 문의 WHERE 부분에 device_id = XXX 문을 추가하여 데이터베이스가 하나의 파티션만을 탐색 할 수있게하려고합니다.

내 문제는 단지 내 데이터베이스의 기본 키에 파티션 키가 없다는 문제의 결과라고 생각하지만 장고는 하나의 필드 만 지원하므로 PK와 파티션 키는 지원되지 않습니다. 독특한, 나는 그것을 PK로 사용할 수 없다.

나는 내 문제에 대한 두 가지 솔루션을 생각할 수 있습니다

  1. 기본 키 필드를 사용하여, 즉 어떻게 든 자동으로 DEVICE_ID (같은이 1_234)와 함께 증가에서 를 구성됩니다. 그러면 데이터베이스에서이 이벤트가있는 장치와 검색 할 파티션을 알 수 있도록 기본 키를 분할해야합니다.
  2. UPDATE 문을 변경하여 WHERE 문에 device_id를 추가합니다.

내 생각에 가장 우아한 방법은 기본 키에 device_id를 포함시키는 것입니다. 따라서 Django에 대한 변경은 필요하지 않으며 분할은 Django를위한 투명 데이터베이스에서만 발생합니다. 그러나 데이터베이스에 이러한 기본 키를 만들 수 있는지 확실하지 않습니다.

당신의 도움이

당신은 아마 그것의 장고를 떠나 가장 좋은 것입니다 동의

답변

1

주셔서 감사합니다. 필자는 이와 같은 것을 한 번도 해본 적이 없지만, 이전에 삽입 트리거를 만들어 연결 한 기본 키를 생성하는 것은 매우 쉽다. 이 같은 것 :

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(); 

그리고 당신의 파티션 기능은 분할해야합니다. 이 작업을 수행하는 파티션 함수를 작성한 적이 없지만 왜 작동하지 않는지는 알 수 없습니다. 그러나 테스트를 거쳐이 '답변'에 결과를 추가해야합니다 (나중에 사용자가 테스트를 통해 도움을 얻을 수 있도록).

+0

제안 해 주셔서 감사합니다. 나는 여분의 데이터베이스로 몇 가지 테스트를 수행했다. 실제로 설명하는 방식으로 기본 키를 구성합니다. 그러나 불행히도 상황을 개선하지는 못합니다. 이제 문제는 쿼리 계획자가 텍스트 필드에서 LIKE '1_ %'을 사용하여 제약 조건을 처리 할 수없는 것 같습니다. id = "1_1234"'이벤트에서 EXPLAIN SELECT * from 이벤트를 수행하면 쿼리 플래너가 unneccesarry 파티션을 제외하지 않습니다. 그러나 대신 모든 테이블을 검색합니다.예제에서 쿼리 플래너는 제약 조건에서 고정 텍스트 값을 구별 할 수있는 것 같습니다. – Tim

+0

파티션에 check 제약 조건을 추가 했습니까? –

+0

예, CHECK (id LIKE '1 _ %')'를 추가했습니다. – Tim

관련 문제