更新履歴の作り方 (oracle限定)

2009年7月6日

ネタ元
http://blogs.wankuma.com/ognac/archive/2009/06/27/176670.aspx
http://blogs.wankuma.com/ognac/archive/2009/07/04/177045.aspx

データ更新時のバージョン管理方法についてのお話です。

元記事にもあるとおり「業務アプリの各テーブルの末尾に、作成日、作成者,更新日、更新者、等を設定する」ことがあります。個人的にはなんのためにそんなことをしているのかさっぱりわからない(*1)のですが、割とふつうに定義されていることが多いようです。

で、この処理。冗長に感じるので、履歴機能をDBMS側でやってくんないかな?という話だったので、Oracleで試してみました。以下実験結果。

(*1)
DELETE発行時には無効であること、UPDATE発行時も変更前のデータがなにかわからないこと、最終の更新しか記録に残らないなどから、その実装の重さに比べて、履歴機能としてはかなり弱い仕組みだと考えています。
こんなことなら、履歴テーブルを一つ別に起こして、そこに履歴データをつっこむほうが、トレーサビリティ的にも堅いのではないかと思っています。(元記事にはそうしていると書かれておりますね…)

1.まずこんなテーブルを作ります。

CREATE TABLE HISTORY_TEST
(
   EMPNO NUMBER(4),      /* 従業員No */
   ENAME VARCHAR2(10),   /* 従業員名 */
   UPDATER VARCHAR2(10)  /* 更新者名 */
);

2.次に以下のようなDMLを実行します。

/* 最初の Insert */
INSERT INTO HISTORY_TEST VALUES (7499,'Allen','James');
COMMIT;
/* Update */
UPDATE HISTORY_TEST SET ENAME='Ford',UPDATER='Adams' WHERE EMPNO=7499;
COMMIT;
/* Delete/Insert */
DELETE HISTORY_TEST WHERE EMPNO=7499;
INSERT INTO HISTORY_TEST VALUES (7499,'Scott','Martin');
COMMIT;

3.ふつうにSELECTします。当然最後にINSERTしたのが残ります。

SELECT * FROM HISTORY_TEST

     EMPNO ENAME                UPDATER
---------- -------------------- --------------------
      7499 Scott                Martin

4.VERSIONS BETWEEN句を使用して、フラッシュバックバージョンクエリを発行してみます。

SELECT versions_starttime,
       versions_endtime,
       versions_operation,
       EMPNO,ENAME,UPDATER
FROM HISTORY_TEST
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE EMPNO = 7499;

VERSIONS_STARTTIME VERSIONS_ENDTIME   VERSIONS_OPERATION   EMPNO ENAME UPDATER
------------------ ------------------ -------------------  ----- ----- -------
09-07-05 23:23:38                      I                   7499  Scott Martin
09-07-05 23:23:38                      D                   7499  Ford  Adams
09-07-05 23:22:41  09-07-05 23:23:38   U                   7499  Ford  Adams
09-07-05 23:20:47  09-07-05 23:22:41   I                   7499  Allen James

なんとなくいけておりますね。使えそうです。
ただ、更新者(UPDATER)は、今回は列として保持してみましたが、DELETEやDELETE/INSERTではだれがDELETEしたのかは不明ですね。当然といえば当然です。
本来はRDBMS側がログオンユーザーで自動記録してくれるといいんですけど。

とりあえず今回の実験はここまで。






カテゴリー: Oracle, データベース

Follow comments via the RSS Feed | Leave a comment | Trackback URL

2 Comments to "更新履歴の作り方 (oracle限定)"

  1. Ognac

    誰が、何のプログラムで...という経緯を問わなけば、充分使えますね。
    フラッシュバックって楽そう。
     監視という面からみると、「誰が、何のプログラムで」が要りそうなので、作り込みは避けられないかも。

    トラックバックは、URLが禁止ワードに引っかかってますね。 ".."に加工すれば、コメントできましたが、
    直接引用できませんね。

  2. オールトの雲

    > 監視という面からみると、「誰が、何のプログラムで」が要りそうなので、作り込みは避けられないかも。

     そうですね。
     なんで、先日のパフォーマンスの件や、今回のようなことなどを想定すると、更新系のDMLを発行する場合は、ストアドにしておいたほうがいいのかなという気がしてきました。インターフェイスさえ決めてしまえば、あとは履歴の実装をどうしようと、ストアドだけを変更すればよく、アプリケーションは触らずにすむので。
     しかし、更新系だけとはいえ、DML全てを抵抗勢力の強い抵抗にあいそうですが…

コメントを投稿する

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


«   »
 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org