[Seasar-user:18321] Re: 【DBFlute】Bhv共通処理

kubo [E-MAIL ADDRESS DELETED]
2009年 8月 18日 (火) 23:20:27 JST


久保(jflute)です。

hattiさん、もろもろの情報ありがとうございます。

> ※会員ステータスのような区分値は、確かに画面からは論理削除しません。
> ただ、保守上、一時的に画面に表示したくない場合などは手動で削除番号を付与して
> 画面表示させなかったりします。
ここですね
この場合は「論理削除」というより「表示・非表示」の制御と
なるかと思います。「論理削除カラム」という共通のカラムで
「論理削除(物理削除の代わり)」と「表示・非表示」がごっちゃに
扱われることが多いです。
もし、とある会員ステータスが「非表示」状態になっている場合、
そのステータスを参照している会員が削除扱いとするべきかどうかは
状況(画面)によって変わることがあるかと思います。
つまり結合時の論理削除条件の扱いが状況によって変わることになります。
このパターンは一例です。他の色々なリレーションと状況で、
(非依存型のリレーションなのか依存型なのかなど)
「結合時に論理削除条件を一律に付与する」のが妥当かどうか
整理することをお奨めします。

> あと、これはうろ覚えなのですが、全てに論理削除番号をつけるのは、
> 都度物理削除(delete)するより、
> 論理削除(update)しておいて夜間バッチで論理削除データを一括削除(delete)
> するほうが、パフォーマンスが良いからという意味もあった気がします、、、
画面リクエストで物理削除コストを避けるのに「削除マーク」を付けて
夜に物理削除するのは画面のパフォーマンス向上のための一パターンですね。
ただ、よほどの件数を一気に削除するのでなければあまりメリットは少ない
かもですね。一件削除くらいだとほとんど変わらないです。
ですが、「全てのテーブルに論理削除カラムを用意すること」の理由
としてはあまり関係がないような気がします。

> > B. 結合テーブルの論理削除カラムの条件はどう扱うのか?
> 結合した場合は、結合条件として削除番号=0を必ず付与します。
結合条件ということは「on句」に付与するということでしょうか?
(「where句」に付けるのか「on句」に付けるのかは大違いなので)

> > <論理削除カラムの連番の話>
> > 論理削除カラム用のシーケンスがあるとのことですが、
> > 全テーブル共通のシーケンスと考えてOKでしょうか?
> 論理削除番号は全テーブル共通のシーケンスですが、
ありがとうございます。
この方法であれば論理削除されていないレコードでの
ユニーク制約が付与出来ますね。これはちょっと自分にとっても
新鮮なやり方でとても貴重な情報でした。
デメリットとしては、仕組みがちょっと大げさになってしまうのと
ちょっと仕様がパッと見でわかりにくいところですかね。
そのデメリットをうまく吸収出来ればってところですね。

> 追記:
> 私自身まだ仕事の経験が浅く学習中のため、
> 皆さんのレベルについていけてないかもしれませんが、
> アプリの品質向上のために頑張りたいと思います。
随分レベルの高い議論をしているかと思いますので、
ぜひぜひこれからも頑張って下さいね。

2009/8/18 HATTI <[E-MAIL ADDRESS DELETED]>:
> お世話になっております。
> hatti です。
>
>> 拡張も「メソッドの追加」とか内部的なロジックにあんまり関係のない
>> 修正であればそんなに大きなトラブルは発生しにくいかと思います。
> 了解しました。色々と試行錯誤してみます。
>
>> ただ、これは確定事項ではなく、論理削除に対する良いアプローチが
>> あれば柔軟に対応したいとは考えているものです。
> なるほど、了解いたしました。
> 何か良い案があればよいのですが、、
>
>> A. 全てのテーブルが実際に論理削除される可能性があるのか?
> 基本全テーブルが論理削除される可能性があります。
> ただ、マスタメンテ画面が存在しなかったり、
> 手動メンテするようなマスタはアプリから論理削除することはなかったりします。
>
> ※会員ステータスのような区分値は、確かに画面からは論理削除しません。
> ただ、保守上、一時的に画面に表示したくない場合などは手動で削除番号を付与して
> 画面表示させなかったりします。
>
> あと、これはうろ覚えなのですが、全てに論理削除番号をつけるのは、
> 都度物理削除(delete)するより、
> 論理削除(update)しておいて夜間バッチで論理削除データを一括削除(delete)
> するほうが、パフォーマンスが良いからという意味もあった気がします、、、
>
>> B. 結合テーブルの論理削除カラムの条件はどう扱うのか?
> 結合した場合は、結合条件として削除番号=0を必ず付与します。
> 結合する場合は確かに意識しないといけないのですが、
> selectAll や selectByPK など、簡単かつ頻繁に使用するメソッドについては、
> 論理削除条件をいちいち付与しなくても使いたかったためです。
>
>> ちなみに自分はいつも論理削除カラムは
>> 「本当に業務的に論理削除されるテーブル」
>> にだけ付与しています。
>> (全テーブル論理削除カラム付与は極力やりたいくないですね)
> こちらも参考にさせていただきます。
>
>> <論理削除カラムの連番の話>
>> 論理削除カラム用のシーケンスがあるとのことですが、
>> 全テーブル共通のシーケンスと考えてOKでしょうか?
> 論理削除番号は全テーブル共通のシーケンスですが、
> 個々のテーブルのみに使用するシーケンスも存在しています。
>
> 追記:
> 私自身まだ仕事の経験が浅く学習中のため、
> 皆さんのレベルについていけてないかもしれませんが、
> アプリの品質向上のために頑張りたいと思います。
>
> 以上、よろしくお願いいたします。
>
> 2009/08/18 21:33 に kubo<[E-MAIL ADDRESS DELETED]> さんは書きました:
>> 久保(jflute)です。
>>
>> hattiさん、こんばんは
>>
>> <機能的な面>
>> 既に議論されていますが、とりあえず機能的な面で現状の結論は
>> テンプレートファイル(VMファイル)を拡張することです。
>> デメリットとしては:
>> o アップグレード時の作業がちょっと面倒になる
>> o 他のDBFluteのプロジェクトとは違う仕様になる
>> ですが、運用をしっかりするのであればやれないことはないと思います。
>> 拡張も「メソッドの追加」とか内部的なロジックにあんまり関係のない
>> 修正であればそんなに大きなトラブルは発生しにくいかと思います。
>>
>> <論理削除の条件付与の話>
>> で、論理削除の話ですが、
>> なぜ「論理削除の条件を一律に付与する」というような機能が
>> DBFluteに無いかと言うと、「論理削除の仕様」というか「定義」が
>> プロジェクトによってかなりバラツキがあるためです。
>> かつ、その論理削除の扱いに寄っては一律に付与しない方が良いと
>> 思われるような場合もあるからです。
>> (また、外だしSQLの場合は結局明示的に条件を付与しなければ
>>  ならないので、それならばCBのときからディベロッパーに意識
>>  させておいた方が逆に間違いが無いかなと)
>>
>> ただ、これは確定事項ではなく、論理削除に対する良いアプローチが
>> あれば柔軟に対応したいとは考えているものです。
>>
>> 参考までにお聞きしたいのですが、hattiさんのプロジェクトでは、
>> 全テーブルに論理削除カラムを付与するとのことですが、
>>
>> A. 全てのテーブルが実際に論理削除される可能性があるのか?
>>
>> 例えば、「会員」と「会員ステータス」があったとして、
>> 「会員ステータス」のレコードが論理削除されることが
>> 実際にあるのか?(その論理削除カラムは必要なのか?)
>>
>> B. 結合テーブルの論理削除カラムの条件はどう扱うのか?
>>
>> 例えば、「会員」と「会員ステータス」があったとして、
>>
>> MemberCB cb = new MemberCB();
>> cb.setupSelect_MemberStatus();
>>
>> としたときに、会員ステータスの論理削除カラムの条件は
>> どのように付与するイメージでしょうか?
>> (Where句?インラインビュー?付与しない?)
>> ※ここのポリシー次第で拡張の仕方も変わるんじゃないかと
>>
>> 結合先の論理削除カラムの条件をどのように扱うかは、
>> 個人的な今までの経験上はかなり「ケースバイケース」でした。
>> トランザクションテーブル join マスタテーブル
>> トランザクションテーブル join トランザクションテーブル
>> などなどそのリレーションの特性によって付与の有無が変わると。
>> なので、一律付与でOKの場合と一律付与がまずい場合とあったりして、
>> そんな状態で一律付与されていると余計にディベロッパーが混乱します。
>>
>> ちなみに自分はいつも論理削除カラムは
>> 「本当に業務的に論理削除されるテーブル」
>> にだけ付与しています。
>> (全テーブル論理削除カラム付与は極力やりたいくないですね)
>>
>> <論理削除カラムの連番の話>
>> 論理削除カラム用のシーケンスがあるとのことですが、
>> 全テーブル共通のシーケンスと考えてOKでしょうか?
>>
>>
>> #
>> # mokkouyouさん、フォローありがとうございます!!!
>> #
>>
>>
>> 2009/8/18 HATTI <[E-MAIL ADDRESS DELETED]>:
>>> お世話になっております。
>>> hatti です。
>>>
>>>> なるほど、論理削除されていれば再度業務キーが利用可能というケースでしたか。
>>>> 失礼しました。
>>>> ※ただ、そのパターンでも私でしたら制約はつけないかな・・
>>> いえいえ、私の説明不足でした。
>>> 制約をつけるか消すかについてはどちらがよいか、アプリ作成しながら考えたいと思います。
>>> 現在仕事のプロジェクトでこのようにしていたので真似てみました。
>>> 参考にさせていただきます。
>>>
>>>> 会員の例でしたら、有効会員テーブルと、会員マスタみたいなのを設けて、
>>>> 業務的One-To-Oneで結び、常に有効な会員が取れるようにするという手もあるかとは思いますが、
>>>> 全てのテーブルとなると厳しいですね。(テーブル二つ用意しないで自分への参照でもいけるかもしれませんが)
>>>> http://d.hatena.ne.jp/jflute/20081201/1228126523
>>> なるほど
>>> しかしやはり全テーブルでは厳しそうですね、、、
>>>
>>>> ExBhvに関しては
>>>> [プロジェクトルート]\mydbflute\dbflute-[version]\templates\om\java\bsbhv\BaseBhv.vm
>>> ありがとうございます。先ほど確認してみました。
>>> BaseBhv の extends org.seasar.dbflute.bhv.${myExtendClassName} を修正して、
>>> extends CommonBhv<${myExtendedObjectClassName}> みたいにしてみようかと思いました。
>>> (CommonBhv は自動生成で、再生成時に上書きされないよう。)
>>> また家でじっくり考えます。
>>>
>>>> 極端な話、CBのConditionQueryを初期化するところで、常に削除フラグを条件に入れてしまう
>>>> という手もあるかもしれませんね。
>>> なるほど、こういう手もあるのですね。
>>> vm のほうが安全に触れそうなので、 vm でやってみようと今のところ考えています。
>>>
>>> 他にもご意見あればお待ちしております。
>>> 私も自分なりに良い方法を考えてみます。
>>> (今のところは vm ファイルの修正ですかね)
>>>
>>> 以上、よろしくお願いいたします。
>>>
>>> 2009/08/18 14:54 に mokkouyou<[E-MAIL ADDRESS DELETED]> さんは書きました:
>>>> mokkouyouです。
>>>>
>>>> なるほど、論理削除されていれば再度業務キーが利用可能というケースでしたか。
>>>> 失礼しました。
>>>> ※ただ、そのパターンでも私でしたら制約はつけないかな・・
>>>>
>>>> それはそうと、
>>>> 会員の例でしたら、有効会員テーブルと、会員マスタみたいなのを設けて、
>>>> 業務的One-To-Oneで結び、常に有効な会員が取れるようにするという手もあるかとは思いますが、
>>>> 全てのテーブルとなると厳しいですね。(テーブル二つ用意しないで自分への参照でもいけるかもしれませんが)
>>>> http://d.hatena.ne.jp/jflute/20081201/1228126523
>>>>
>>>>
>>>> 全体的にとなると、やはりテンプレートのカスタマイズでしょうか?
>>>> vmにつきましてはVelocityの知識が必要です。
>>>> 1ユーザの私としてはこの拡張性が好きですが、
>>>> 一気に自己責任になる部分ですので、あまりお勧めするわけではありません。
>>>> (そもそも自己責任なんでしょうけど)
>>>>
>>>> ExBhvに関しては
>>>> [プロジェクトルート]\mydbflute\dbflute-[version]\templates\om\java\bsbhv\BaseBhv.vm
>>>>
>>>> 辺りを見てください。
>>>>
>>>>
>>>> 極端な話、CBのConditionQueryを初期化するところで、常に削除フラグを条件に入れてしまう
>>>> という手もあるかもしれませんね。
>>>>
>>>> 結合(setUp)などを考えるとよく内部を調査しないといけませんが。
>>>> それこそ、業務的One-To-Oneと整合性が取れるかも不明。
>>>> ※そしてそのことを忘れるといざ削除済をほしい場合など、後々大騒ぎをすることになるかもしれませんね。(^^;
>>>>
>>>> 2009/08/18 14:12 HATTI <[E-MAIL ADDRESS DELETED]>:
>>>>>
>>>>> お世話になっております。
>>>>> hatti です。
>>>>>
>>>>> mokkouyou さんのご回答へ返信いたします。
>>>>> ご回答ありがとうございます。
>>>>>
>>>>> >> 論理削除済みのレコードは対象としない(質問にもありますよね)とすれば、
>>>>> >> 論理削除済みのレコードが再度削除されることが無いのではないでしょうか?
>>>>> おっしゃるとおり、論理削除済のレコードをアプリから再度検索、削除されないように考えています。
>>>>> そのため、自動生成された検索/更新などのメソッドの WHERE 句に「削除番号=0」を付加させたいと考えています。
>>>>>
>>>>> >> 論理削除=新規インサートということでしょうか??
>>>>> 論理削除は UPDATE 処理です。
>>>>> 対象テーブルの論理削除番号カラムにシーケンスによる採番を行います。
>>>>>
>>>>> >> 更新ならともかく削除にバージョニングして履歴管理では
>>>>> >> そもそも、何度か削除されるという前提になっているような・・・
>>>>> バージョン管理は、別途バージョン番号カラムを用意してそちらで行います。
>>>>> 楽観排他もこちらのカラムで行います。
>>>>>
>>>>> >> それは別として、以下のスマートな解決方法があればいいですが、
>>>>> >> 無いようであれば、(本当に全てのテーブルで共通なのであれば)
>>>>> >> テンプレートとなる、vmファイルに手を入れるというのもありかと思います。
>>>>> なるほど、vmファイルというものがあるのですね。
>>>>> また確認させていただきます。
>>>>>
>>>>> 以上、よろしくお願いいたします。
>>>>>
>>>>> 2009/08/18 12:49 に HATTI<[E-MAIL ADDRESS DELETED]> さんは書きました:
>>>>> > hatti です。
>>>>> >
>>>>> > 質問がわかりづらく申し訳ございません。
>>>>> > 例えば会員マスタ(ユーザID, ログインID, パスワード, 論理削除番号) のテーブルがあるとします。
>>>>> >
>>>>> > ユーザID(連番PK) / ログインID / パスワード / 論理削除番号
>>>>> > ----------------------------------------------------------------------
>>>>> > 1 / id1 / aaa / 0
>>>>> > 2 / id2 / bbb / 1
>>>>> > 3 / id2 / ccc / 0
>>>>> >
>>>>> > PK のユーザIDには当然自動でインデックスが作られるのでいいのですが、
>>>>> > 業務キーとなる、ログインIDも一意としたいためログインIDにも一意制約をかけようとしています。
>>>>> > しかし、論理削除のため、論理削除番号もユニークインデックスに含めないと、
>>>>> > テストデータ1, 2 のように、同一のログインIDが登録できません。
>>>>> >
>>>>> > そして、論理削除を表すものが論理削除フラグだった場合、
>>>>> > さらに id2 のユーザを論理削除した場合に、
>>>>> >
>>>>> > 2 / id2 / bbb / 1
>>>>> > 3 / id2 / ccc / 1
>>>>> >
>>>>> > となってしまい、ユニークでなくなってしまいます。
>>>>> > そこでフラグでなく、削除番号とし、
>>>>> >
>>>>> > 2 / id2 / bbb / 1
>>>>> > 3 / id2 / ccc / 2
>>>>> >
>>>>> > となるようにしようとしています。
>>>>> >
>>>>> > まだ説明不足な点があればご指摘ください。
>>>>> >
>>>>> > 以上、よろしくお願いいたします。
>>>>> >
>>>>> > 2009/08/18 12:30 に mokkouyou<[E-MAIL ADDRESS DELETED]> さんは書きました:
>>>>> >> mokkouyouです。
>>>>> >>
>>>>> >> 論理削除がかち合う意味が若干わかりませんのでなんとも・・・ですが、
>>>>> >>
>>>>> >> 論理削除済みのレコードは対象としない(質問にもありますよね)とすれば、
>>>>> >> 論理削除済みのレコードが再度削除されることが無いのではないでしょうか?
>>>>> >>
>>>>> >> 同時性の問題であれば、楽観でも悲観でもいいのでロックすればいいだけのような。
>>>>> >>
>>>>> >>
>>>>> >> とここまで書いて気づきましたが、
>>>>> >> ユニークインデックスとありますので、
>>>>> >> 論理削除=新規インサートということでしょうか??
>>>>> >>
>>>>> >> 更新ならともかく削除にバージョニングして履歴管理では
>>>>> >> そもそも、何度か削除されるという前提になっているような・・・
>>>>> >>
>>>>> >> というのが4.に対する「私なら」の回答でしょうか
>>>>> >>
>>>>> >>
>>>>> >> それは別として、以下のスマートな解決方法があればいいですが、
>>>>> >> 無いようであれば、(本当に全てのテーブルで共通なのであれば)
>>>>> >> テンプレートとなる、vmファイルに手を入れるというのもありかと思います。
>>>>> >>
>>>>> >> 以上宜しくお願いいたします。
>>>>> >>
>>>>> >> 2009/08/18 12:09 HATTI <[E-MAIL ADDRESS DELETED]>:
>>>>> >>>
>>>>> >>> お世話になっております。
>>>>> >>> hatti と申します。
>>>>> >>>
>>>>> >>> DBFlute9.5.3 / OracleXE(10g) を使用しております。
>>>>> >>> 特に急ぎの質問ではないため、時間のあるときに回答いただけるとありがたいです。
>>>>> >>>
>>>>> >>> 現在 DBFlute の学習として、サンプルアプリを作成しています。
>>>>> >>> サンプルではテーブルのレコードを物理削除せずに、論理削除で削除しようと考えております。
>>>>> >>>
>>>>> >>> 全テーブルに論理削除番号(フラグではなく連番 ※1以上は削除済)をサフィックスカラムとして持たせました。
>>>>> >>> フラグではなく、連番なのは業務キーと削除Noを合わせてユニークインデックスを張りたいためです。
>>>>> >>> (フラグだと 0/1 のみなので、同一の業務キーレコードが2回削除されるとかち合うため。)
>>>>> >>>
>>>>> >>> そこで、4点ほど質問させていただきたいことがあります。
>>>>> >>>
>>>>> >>> 1.論理削除番号を常に検索条件に付加
>>>>> >>> 自動生成されるメソッド(selectByPK など)は、純粋に PK のみで検索されるため、
>>>>> >>> 論理削除されているものも取れてしまうと思いますが、
>>>>> >>> これら自動生成されるメソッドに対して、論理削除番号を常に条件に付加させることはできないでしょうか。
>>>>> >>>
>>>>> >>> 2. 1.が無理な場合、全 Bhv に共通な自作メソッドを持たせたい
>>>>> >>> 自動生成が無理ならば、自分で作成するしかないです。
>>>>> >>> その場合、全 ExBhv に findAll などを持たせるのはテーブル数が多いと困難です。
>>>>> >>>
>>>>> >>> そこで、全 ExBhv に共通な処理(findByPk, findAll, logicalDelete
>>>>> >>> など)を持たせることは可能でしょうか。
>>>>> >>> 自動生成された Bhv を見ると、ExBhv とそれに対する BsBhv しかなく、各テーブルごとに処理を持たせないと
>>>>> >>> いけないのかなと感じております。
>>>>> >>>
>>>>> >>> ※最悪、commonBhv などを作って、全 ExBhv に DI しようかと考えていますが、、、
>>>>> >>>
>>>>> >>> 3.2.が可能な場合、自動生成されるメソッドが不要
>>>>> >>> 自ら作成した共通メソッドをディベロッパに使用してもらいたいです。
>>>>> >>> 大規模な開発の際に、全員に情報伝達できず、
>>>>> >>> DBFlute によって作成されたメソッドが使われて論理削除されたデータが
>>>>> >>> 画面表示されたりしてしまうとまずいので、、
>>>>> >>>
>>>>> >>> ※テストをしっかりしろと言われるかもしれないですが、現実問題起こりそうなので、、
>>>>> >>>
>>>>> >>> 4.また、こんなことをせずともその他解決、品質を高くできる方法
>>>>> >>> 論理削除番号の持たせ方、実装方法など、ご指摘があればお願いいたします。
>>>>> >>> ※私ならこうする~など
>>>>> >>>
>>>>> >>> 以上、お手数をおかけしますがよろしくお願いいたします。
>>>>> >>> _______________________________________________
>>>>> >>> Seasar-user mailing list
>>>>> >>> [E-MAIL ADDRESS DELETED]
>>>>> >>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >> --
>>>>> >> mokkouyou
>>>>> >> [E-MAIL ADDRESS DELETED]
>>>>> >>
>>>>> >> _______________________________________________
>>>>> >> Seasar-user mailing list
>>>>> >> [E-MAIL ADDRESS DELETED]
>>>>> >> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>> >>
>>>>> >>
>>>>> >
>>>>> _______________________________________________
>>>>> Seasar-user mailing list
>>>>> [E-MAIL ADDRESS DELETED]
>>>>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>
>>>>
>>>>
>>>> --
>>>> mokkouyou
>>>> [E-MAIL ADDRESS DELETED]
>>>>
>>>> _______________________________________________
>>>> Seasar-user mailing list
>>>> [E-MAIL ADDRESS DELETED]
>>>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>
>>>>
>>> _______________________________________________
>>> Seasar-user mailing list
>>> [E-MAIL ADDRESS DELETED]
>>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>
>> _______________________________________________
>> Seasar-user mailing list
>> [E-MAIL ADDRESS DELETED]
>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
>


Seasar-user メーリングリストの案内