복붙노트

[SQL] 트위스트와 임시 데이터베이스 설계, (초안 행 VS 라이브)

SQL

트위스트와 임시 데이터베이스 설계, (초안 행 VS 라이브)

나는 개체 버전 모두 라이브 초안 개체가 필요의 추가 트위스트와 함께 구현으로 찾고 있어요, 그것도 가능하다면 나는 잠재적으로 무서운 해킹없이 의심하기 시작하고있어,이 누군가의 경험에서 통찰력을 사용할 수 있습니다.

나는 예를 위해서 태그 게시물을 무너 뜨리는 것입니다,하지만 내 사용의 경우는 (느리게 변화하는 차원 포함 - http://en.wikipedia.org/wiki/Slowly_changing_dimension) 좀 더 일반적이다.

당신이 게시물 테이블, 태그 테이블 및 post2tag 테이블을했습니다 가정 해 봅시다 :

posts (
 id
)

tags (
 id
)

post2tag (
 post_id fkey posts(id),
 tag_id fkey tags(id)
)

나는 몇 가지 필요 해요 :

나는 다양한 옵션을 조사했습니다. 지금까지 최고의 내가 (점 # 4 / # 5 없음)을 마련했습니다는 조금 SCD의 TYPE6 하이브리드 설정처럼 보이지만 대신 현재 부울을 가진의는 현재 행에 대한 전망을 구체화있다. 모든 의도와 목적은 다음과 같습니다 :

posts (
 id pkey,
 public,
 created_at,
 updated_at,
 updated_by
)

post_revs (
 id,
 rev pkey,
 public,
 created_at,
 created_by,
 deleted_at
)

tags (
 id pkey,
 public,
 created_at,
 updated_at,
 updated_by
)


tag_revs (
 id,
 public,
 rev pkey,
 created_at,
 created_by,
 deleted_at
)

post2tag (
 post_id fkey posts(id),
 tag_id fkey tags(id),
 public,
 created_at,
 updated_at,
 updated_by
)

post2tag_revs (
 post_id,
 tag_id,
 post_rev fkey post_revs(rev), -- the rev when the relation started
 tag_rev fkey tag_revs(rev), -- the rev when the relation started
 public,
 created_at,
 created_by,
 deleted_at,
 pkey (post_rev, tag_rev)
)

나는 기간 (created_at, deleted_at)에 인덱스를 유지하기 위해 pg_temporal을 사용하고 있습니다. 그리고 트리거를 사용하여 동기화 여러 테이블을 유지한다. 야다의 궁시렁 궁시렁 ... 난 초안이 발표되지 않고 회전 속도를 올린다에 저장됩니다 방식으로 게시물 / 태그 편집을 취소 할 수 있도록 트리거를 만들었습니다. 그것은 잘 작동합니다.

내가 post2tag 초안 행 관련 관계에 대해 걱정할 필요가 경우를 제외하고. 이 경우, 나에게 모든 지옥 나누기 느슨한,이 힌트 나는 거기에서 설계 문제의 어떤 종류를했습니다있다. 그러나 나는 아이디어를 밖으로 실행하는거야 ...

I는 데이터의 중복 (각 개정안 도입 즉, n 개의 행 post2tag)를 도입하는 것으로 간주했다. 작품의이 종류는하지만, 많이 느린 나는 그것이 싶습니다보다 경향이있다.

나는 "마지막 초안"에 대한 초안 테이블을 도입 고려했지만,이 신속하게 아주 아주 추악하게하는 경향이있다.

나는 플래그의 모든 종류의 고려했습니다 ...

질문 그래서 : 행 버전 제어 된 환경에서 비 라이브 행 VS 라이브 관리의 일반적으로 인정 된 방법이 있습니까? 그렇지 않으면, 당신은 노력과 함께 합리적으로 성공 무슨이?

해결법

  1. ==============================

    1.너무 위키 백과의 문서를 참조하십시오 - 앵커 모델링은 시간 dB을 구현하는 좋은 방법입니다. 일부 익숙해 시간 만 작업 좋은 이동합니다. [-> 로컬 파일에서 모델을로드 파일]이 온라인 모델링 도구입니다 당신이 제공되는 XML 파일을로드하는 경우 또한 사용 -이 같은 것을 볼 수 [레이아웃 -> Togle 이름].

    너무 위키 백과의 문서를 참조하십시오 - 앵커 모델링은 시간 dB을 구현하는 좋은 방법입니다. 일부 익숙해 시간 만 작업 좋은 이동합니다. [-> 로컬 파일에서 모델을로드 파일]이 온라인 모델링 도구입니다 당신이 제공되는 XML 파일을로드하는 경우 또한 사용 -이 같은 것을 볼 수 [레이아웃 -> Togle 이름].

    에서 [생성 -> SQL 코드] 테이블, 뷰 및 포인트 - 인 - 타임 기능에 대한 DDL을 생성합니다. 코드는 매우 긴, 그래서 난 여기를 게시하고 있지 않다. 코드 체크 아웃 - 당신이 그것을 수정해야 할 수 있습니다 당신의 DB합니다.

    여기에 도구를 모델링에로드 할 파일입니다.

    <schema>
    <knot mnemonic="EXP" descriptor="Expired" identity="smallint" dataRange="char(1)">
    <identity generator="true"/>
    <layout x="713.96" y="511.22" fixed="true"/>
    </knot>
    <anchor mnemonic="US" descriptor="User" identity="int">
    <identity generator="true"/>
    <attribute mnemonic="USN" descriptor="UserName" dataRange="varchar(32)">
    <layout x="923.38" y="206.54" fixed="true"/>
    </attribute>
    <layout x="891.00" y="242.00" fixed="true"/>
    </anchor>
    <anchor mnemonic="PO" descriptor="Post" identity="int">
    <identity generator="true"/>
    <attribute mnemonic="TIT" descriptor="Title" dataRange="varchar(2)">
    <layout x="828.00" y="562.00" fixed="true"/>
    </attribute>
    <layout x="855.00" y="471.00" fixed="true"/>
    </anchor>
    <anchor mnemonic="TG" descriptor="Tag" identity="int">
    <identity generator="true"/>
    <attribute mnemonic="TGT" descriptor="TagText" dataRange="varchar(32)">
    <layout x="551.26" y="331.69" fixed="true"/>
    </attribute>
    <layout x="637.29" y="263.43" fixed="true"/>
    </anchor>
    <anchor mnemonic="BO" descriptor="Body" identity="int">
    <identity generator="true"/>
    <attribute mnemonic="BOT" descriptor="BodyText" dataRange="varchar(max)">
    <layout x="1161.00" y="491.00" fixed="true"/>
    </attribute>
    <layout x="1052.00" y="465.00" fixed="true"/>
    </anchor>
    <tie timeRange="datetime">
    <anchorRole role="IsTagged" type="PO" identifier="true"/>
    <anchorRole role="IsAttached" type="TG" identifier="true"/>
    <anchorRole role="BYAuthor" type="US" identifier="false"/>
    <knotRole role="Until" type="EXP" identifier="false"/>
    <layout x="722.00" y="397.00" fixed="true"/>
    </tie>
    <tie timeRange="datetime">
    <anchorRole role="Contains" type="PO" identifier="true"/>
    <anchorRole role="ContainedIn" type="BO" identifier="false"/>
    <layout x="975.00" y="576.00" fixed="true"/>
    </tie>
    <tie>
    <anchorRole role="CreatedBy" type="TG" identifier="true"/>
    <anchorRole role="Author" type="US" identifier="false"/>
    <layout x="755.10" y="195.17" fixed="true"/>
    </tie>
    <tie>
    <anchorRole role="CreatedBy" type="PO" identifier="true"/>
    <anchorRole role="Author" type="US" identifier="false"/>
    <layout x="890.69" y="369.09" fixed="true"/>
    </tie>
    <tie>
    <anchorRole role="ModifiedBy" type="BO" identifier="true"/>
    <anchorRole role="Author" type="US" identifier="false"/>
    <layout x="1061.81" y="322.34" fixed="true"/>
    </tie>
    </schema>
    
  2. ==============================

    2.내가 SCD 2 형과 PostgreSQL 규칙 및 트리거를 사용하여 임시 데이터베이스를 구현하고, 액티브을위한 자체에 포함 된 패키지에 싸서했습니다 http://github.com/ifad/chronomodel

    내가 SCD 2 형과 PostgreSQL 규칙 및 트리거를 사용하여 임시 데이터베이스를 구현하고, 액티브을위한 자체에 포함 된 패키지에 싸서했습니다 http://github.com/ifad/chronomodel

    수동 규칙 및 트리거를 만들 수 있으며, 데이터베이스가 알아서합니다 -하지만 디자인은 언어 / 프레임 워크에서 독립적이다. https://github.com/ifad/chronomodel/blob/master/README.sql에서보세요.

    또한 효율적인 형상 인덱싱 및 연산자를 사용하여 임시 데이터 질의를 보너스로서 포함된다. :-)

  3. ==============================

    3.post2tag_revs는 2 개 근본적으로 다른 개념을 표현하기 위해 노력하고 있다는 점에서 문제가있다.

    post2tag_revs는 2 개 근본적으로 다른 개념을 표현하기 위해 노력하고 있다는 점에서 문제가있다.

    개정은 지금까지 공개되지 않는 초안 포스트 개정에 적용되는 태그는 오직 그 하나의 버전에 적용됩니다.

    태그가 (즉, 게시 된 후 개정과 관련) 게시되면이 취소 될 때까지,이 게시물의 모든 미래 버전에 적용됩니다.

    그리고 게시 된 개정과 관련, 또는 unasociating, 당신이 인위적으로 당신이 태그 추가 또는 제거를 연결할 수 있습니다 단지 있도록 개정을 복제하여이를 시행하지 않는 한, 게시 개정에 반드시 동시 아니지만 ...

    나는 초안 태그 post2tag_revs.post_rev 만 관련하여 모델을 변경할 것입니다. 개정이 게시 (그리고 태그가 살아 있습니다) 일단, 나는 시작을 표시하기 위해 타임 스탬프 열을 사용하여 게시 된 유효 기간의 종료 것입니다. 당신은 수도 있고이 변화를 표현하는 새로운 post2tag_revs 항목을하지 않을 수 있습니다.

    당신이 지적으로,이 관계는 양방향 시간적합니다. 당신은 태그가 현재 포스트와 연관되어 있음을 나타냅니다 post2tag에 부울을 추가하여 "정상"경우에 성능이 향상 될 수 있습니다.

  4. ==============================

    4.나는 그것을 못을 박았다 생각합니다. 기본적으로, 당신은 관련 테이블에 (고유의) 초안 필드를 추가, 그들은 새 게시물 / 태그 / 등 것처럼 당신은 초안 작업 :

    나는 그것을 못을 박았다 생각합니다. 기본적으로, 당신은 관련 테이블에 (고유의) 초안 필드를 추가, 그들은 새 게시물 / 태그 / 등 것처럼 당신은 초안 작업 :

    posts (
     id pkey,
     public,
     created_at stamptz,
     updated_at stamptz,
     updated_by int,
     draft int fkey posts (id) unique
    )
    
    post_revs (
     id,
     public,
     created_at,
     created_by,
     deleted_at,
     pkey (id, created_at)
    )
    
    tags (
     id pkey,
     public,
     created_at,
     updated_at,
     updated_by,
     draft fkey tags (id) unique
    )
    
    
    tag_revs (
     id,
     public,
     created_at,
     created_by,
     deleted_at,
     pkey (id, created_at)
    )
    
    post2tag (
     post_id fkey posts(id),
     tag_id fkey tags(id),
     public,
     created_at,
     updated_at,
     updated_by,
     pkey (post_id, tag_id)
    )
    
    post2tag_revs (
     post_id,
     tag_id,
     public,
     created_at,
     created_by,
     deleted_at,
     pkey (post_id, tag_id, created_at)
    )
    
  5. ==============================

    5.게시물, 태그 및 post2tag : 만 3 테이블을 사용합니다.

    게시물, 태그 및 post2tag : 만 3 테이블을 사용합니다.

    모든 테이블에 START_TIME 및 END_TIME 열을 추가합니다. 키 START_TIME 및 END_TIME에 대한 고유 인덱스를 추가합니다. END_TIME가 null이 어디 키를 고유 인덱스를 추가합니다. trigers를 추가합니다.

    현재의 경우 :

    SELECT ... WHERE end_time IS NULL
    

    시 :

    WHERE (SELECT CASE WHEN end_time IS NULL
    THEN (start_time <= at_time)
    ELSE (start_time <= at_time AND end_time > at_time)
    END)
    

    현재 데이터를 검색하기 때문에 기능 인덱스의 느린 없습니다.

    편집하다:

    CREATE UNIQUE INDEX ... ON post2tag (post_id, tag_id) WHERE end_time IS NULL;
    CREATE UNIQUE INDEX ... ON post2tag (post_id, tag_id, start_time, end_time);
    
    FOREIGN KEY (post_id, start_time, end_time) REFERENCES posts (post_id, start_time, end_time) ON DELETE CASCADE ON UPDATE CASCADE;
    FOREIGN KEY (tag_id, start_time, end_time) REFERENCES tags (tag_id, start_time, end_time) ON DELETE CASCADE ON UPDATE CASCADE;
    
  6. from https://stackoverflow.com/questions/6318317/temporal-database-design-with-a-twist-live-vs-draft-rows by cc-by-sa and MIT license