3

現在、Java でユーザーベースの Web アプリケーションを開発しています。

ユーザーは、名、姓、地域 (アジア、ヨーロッパ、米国、英国など)、国、部門、支店、製品などの多くのプロパティを持つことができます。

このユーザーには、上記のすべてのフィールドを含む通常の CRUD 画面があります。

ユーザーの追加/編集画面には、発効日と呼ばれる日付フィールドもあります。このユーザーの追加/編集が通常の CRUD での通常の追加/編集と異なる点は、ユーザーに対して行われた更新が有効日まで反映されないことです。

今日が 4 月 6 日で、リージョンがアジアで発効日が 4 月 10 日の新しいユーザーを追加するとします。そして今、私は同じユーザーを変更し、彼の地域をアジアから米国に変更しましたが、発効日は5月15日です。

そのため、5 月 15 日までシステムは彼の地域をアジアのみとして表示し、5 月 15 日に彼の地域は自動的に米国に変更されるはずです。

4 月のようにアジアで働いているユーザーと考えることができますが、5 月 15 日から彼は米国で働くために移動します。つまり、リージョンはアジアから米国発効日 5 月 15 日に変更されます。したがって、5 月 15 日まではアジアのユーザーとしてのみ表示されます。

したがって、単純な更新操作として、彼の地域をアジアからデータベースに更新することはできません。

これは、部門、支店、製品など、他の多くの分野にも当てはまります。

同じユーザーに対して複数のレコードを持つことはできません。

編集1:

また、ユーザーの履歴や今後の更新も確認できるはずです。

4 月 6 日のように、5 月 15 日からユーザーの地域が変わり、5 月 10 日から彼のディビジョンが A から B に変わることがわかります。

また、15 日の発効日から提案されているアジアから米国へのユーザーの移動が今は行われない可能性があることを後で知ったので、その更新を削除できるはずです。

編集2: -

上記の状況で、元のユーザー テーブルとユーザー変更ログ テーブルを変更するにはどうすればよいですか?

システム内のリージョン asia を持つユーザーが、今後数週間で asia から Us に変更されるとします。ユーザーはユーザーに対して同じ更新を行います。彼は地域をアジアからユーザーに変更し、発効日を将来の日付として選択します。

次に、地域がアジアから米国に変更されたかどうかを確認するにはどうすればよいですか (地域のような名前の mre フィールドがある場合があります)。コードレベルでそれを行うべきですか、それともトリガーなどを使用してデータベースレベルで行うことは可能ですか?

このためのシステムとデータベースの設計を手伝ってください。

4

7 に答える 7

1

、、およびUser_Regionを含むマッピングテーブルを作成できます。ユーザーの領域で切り替えが行われるときに与えられます。変更日がnullの場合、ユーザーが現在その地域にいることを意味している可能性があります。User_IDRegion_IDChange_DateChange_Date

User_ID次に、日付とともに地域のリストを作成できます。これは、都合に応じて表示できます。

CREATE TABLE User_Regions{
   User_ID INT,
   Region_ID INT,
   Change_Date DATE,
   FOREIGN KEY User_ID REFERENCES User(ID),
   FOREIGN KEY Region_ID REFERENCES Region(ID)
};
于 2012-04-06T12:26:33.153 に答える
1

履歴テーブルでうまくいきます。つまり、日付列を持つ履歴レコードをできるだけ多く持ち、現在の日付に最も近いものだけを現在のものとして扱います。それ以外の場合は、更新履歴を別のテーブルに保持し、変更を更新するためのバッチ更新プロセスを用意する必要があります。ユーザーエンティティの正規化された構造を取得することで、同じユーザーに複数のレコードを含めることができないという障害を克服することをお勧めします。usersテーブルには、キー列(idなど)と、残りの部分との履歴更新を含む結合テーブルがあります。列。

于 2012-04-06T12:26:42.300 に答える
1

毎日特定の時刻に実行されるCHANGELOG テーブルスケジューラを維持するこのシステムを実装できることをお勧めします。

CHANGELOG テーブルの 属性:

  • ターゲット テーブル
  • targetPrimaryKey
  • ターゲット列
  • ターゲット値
  • 発効日

これで、必須フィールドが更新されるたびに、対応するエントリが changelog テーブルに挿入されます。

例、

  • targetTable : ユーザー
  • targetPrimaryKey : 3 (ユーザー レコードのプライマリ行 ID)
  • targetColumn : 地域
  • targetValue : 米国
  • 発効日: 2012 年 5 月 15 日

現在、スケジューラは毎日 (午前 12 時) に実行され、CHANGELOG テーブルからその日に行われるようにスケジュールされた変更をチェックし、それぞれのターゲット テーブルでそれらの変更を行います。

注: このアプローチには 2 つの利点があります。

  1. 同じレコードに対して 2 つのエントリを維持する必要はありません。

  2. 複数のフィールド (地域、部門、支店) と複数のテーブルも対象にすることができます。

于 2012-04-06T12:30:48.210 に答える
0

ここには2つの可能性があります。

  1. ユーザーテーブルのように見える別のテーブルがあり、追加の列「validFrom」があり、毎朝cron(quartz)ジョブが更新されます。
  2. 有効なtoとともに列を通常のユーザーテーブルに追加し、それを反映するようにすべてのクエリを変更します。

すでに述べたように、複数のレコードを持つことはできないため、2。は悪い解決策になります。1に固執します。

于 2012-04-06T12:26:53.810 に答える
0

私は2つのアプローチを考えることができます:

すべてのバージョンをメイン テーブルに保持する

| user_name (PK) | effective_date_from (PK) | ...remaining columns

このアプローチでは、すべてのユーザーはテーブル内の複数の行で表されますが、現在のUser行は 1 行だけです。現在のデータを見つけるには、追加のクエリを追加する必要があります。

SELECT *
FROM User
WHERE user_name = ?
  AND effective_date >= NOW()
ORDER BY effective_date DESC
LIMIT 1

そのため、指定されたすべてのユーザーを取得していますuser_name(そのようなユーザーには異なるバージョンが複数あるeffective_dateためeffective_date、主キーの一部でもある必要があります)。結果を最新バージョンに制限します (ただしeffective_date、将来のバージョンではありません)。

このアプローチにはいくつかの欠点があります。

  • 外部キーをどうするか 論理的には、システムには 1 人のユーザーしか存在しません
  • パフォーマンスの低下、クエリの複雑化
  • 古いバージョンをどうするか?

保留中のバージョン テーブル

元の (メイン)Userテーブル スキーマを変更せずに保持し、 という 2 番目のテーブルを作成しますPending_user_changes。後者にも同じスキーマ +effective_date列があります。変更の粒度が 1 日である場合は、今日から有効になる保留中の変更を探すジョブを (データベースまたはアプリケーションで) 作成し、メイン テーブルを置き換えます。

私はこの解決策がはるかにきれいだと思います.メインテーブルのプライマリ/外部キーは決して変更されmainず、テーブルは古いデータや重複したデータで雑然としていません.

于 2012-04-06T12:30:06.433 に答える
0

「純粋な」データ モデルは、キーに日付を含め、複数のエディションを持つことですが、将来のイベントの変更にはいくつかの問題があります。

「操作」のリストとして将来の変更をモデル化しようとすると思います。将来フィールドを変更すると、その日にフィールドを変更する操作が実際にスケジュールされます。

アプリケーションは、期限が来ると定期的に操作を適用します。

GUI では、保留中の操作のリストを簡単に表示でき、将来の操作を簡単にキャンセルまたは変更できます。

競合する操作を制限したり、警告を発行したりするルールを設定することもできますが、リストが明確に表示されていれば、それほど問題にはなりません。

于 2012-04-06T12:29:02.407 に答える
0

私の意見では、Event ステートメントを使用する必要があります。2 つのイベントは次のとおりです。

CREATE EVENT myevent
    ON SCHEDULE AT DATE_CHANGING
    DO
      UPDATE myschema.mytable SET mycol = mycol + 1;

CREATE EVENT myevent
    CREATE EVENT myevent
    ON SCHEDULE AT DATE_BACKUP
    DO
      UPDATE myschema.mytable SET mycol = mycol - 1;
于 2012-04-06T12:29:24.167 に答える