View
1.490
Download
1
Category
Preview:
Citation preview
Oracle での論理削除@mogmet
2016/05/10 Database Connect 2016
About me• twitter: @mogmet• 好物: iOS, php, MySQL, Oracle• 仕事:インフラエンジニア→ iOS エンジニア→フリーランスな DBA• ブログとか: http://mogmet.com/• 作ったアプリたち↓
ワンナイト人狼 for iPhone STARBUCKSHOLIC
はじめての Oracle の発表です
論理削除戦争
#ronsakucasual DB の論理削除についてひたすら共有する 論理削除 Casual Talks #1 にいってきたまとめ
http://blog.mogmet.com/ronsakucasual-1/
様々な方法の参考
考えに考え、結果、削除フラグを採用することになった皆さんへ朗報です
12c 新機能In-Database Archiving (インデータベース・アーカイブ)
これを使うと論理削除をOracle の機能として実現できる!
有効にするにはALTER TABLE <table_name> ROW ARCHIVAL;を実行するだけ!
※ 新規の時は table を作る時に ROW ARCHIVAL をつけるだけ。
有効化するとORA_ARCHIVE_STATEという非表示の varchar2 型の列が追加されるのでそれを削除フラグとして使う
SQL> create table anohana(id number, name varchar(32)) row archival;
Table created.
SQL> insert into anohana values (1, 'jintan');
1 row created.
SQL> insert into anohana (id, name, ORA_ARCHIVE_STATE) values (2, 'menma', 1);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from anohana;
ID NAME---------- --------------------
1 jintan
menma が見当たらない!
魔法のコトバを唱える
SQL> ALTER SESSION SET ROW ARCHIVAL VISIBILITY = ALL;
SQL> select * from anohana;
ID NAME---------- --------------------
1 jintan 2 menma
見つかっちゃった(๑ゝڡ ๑◕)
In-Database Archiving を有効にしたテーブルに対して実行計画をとってみると
実行計画をみると SQL が自動的に付与されていたのがわかる-----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 2033 | 3 (0)| 00:00:01 ||* 1 | TABLE ACCESS FULL| ANOHANA | 1 | 2033 | 3 (0)| 00:00:01 |-----------------------------------------------------------------------------
Predicate Information (identified by operation id):---------------------------------------------------
1 - filter("ANOHANA"."ORA_ARCHIVE_STATE"='0' AND "ID"<3)
-----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2 | 62 | 3 (0)| 00:00:01 ||* 1 | TABLE ACCESS FULL| ANOHANA | 2 | 62 | 3 (0)| 00:00:01 |-----------------------------------------------------------------------------
Predicate Information (identified by operation id):---------------------------------------------------
1 - filter("ID"<3)
ALTER SESSION SET ROW ARCHIVAL VISIBILITY = ALL;
SELECT * FROM anohana WHERE id < 3;
SELECT * FROM anohana WHERE id < 3;
Tips
インデータベースアーカイブが有効( VISIBILITY = ACTIVE )な時にORA_ARCHIVE_STATE を条件にいれて
SELECT しても全くデータがでないので注意!
SQL> SELECT * FROM anohana WHERE ORA_ARCHIVE_STATE = 1;
no rows selected
SQL> ALTER SESSION SET ROW ARCHIVAL VISIBILITY = ALL;
Session altered.
SQL> SELECT * FROM anohana WHERE ORA_ARCHIVE_STATE = 1;
ID NAME---------- --------------------
2 menma
CHECK 制約をORA_ARCHIVE_STATEに追加することもできます!
SQL> ALTER TABLE anohana ADD CONSTRAINT check_state CHECK (ora_archive_state IN ('1', '0'));
Table altered.
SQL> INSERT INTO anohana (id, name, ORA_ARCHIVE_STATE) VALUES (1, 'yukiatsu', 2);INSERT INTO anohana (id, name, ORA_ARCHIVE_STATE) VALUES (1, 'yukiatsu', 2)*ERROR at line 1:ORA-02290: check constraint (HOGE.CHECK_STATE) violated
まとめ
まとめ• 論理削除を実装する際にはインデータベース・アーカイブを用いるとアプリの実装コストを下げられそう• varchar2 の型で ORA_ARCHIVE_STATE は使えるので使い方によっては様々な情報を工夫して入れられそう
One more thing…
個人的には DB 全般において論理削除を使う話になった時はもう少し詰めて設計を考えて、使わないで済むならその方がいいと思っている
御静聴ありがとうございました
Recommended