4

私はデータベースの設計を決定しようとしています。より具体的には、これはより大きな設計のサブパーツです。基本的に、「ロケーション」があります。各ロケーションには、任意の数のセンサーを関連付けることができ、ロガーを含めることができます(ただし、1つのみ)。

私にはセンサーの測定値があり、ロガーの測定値があります。それぞれが、別々のテーブルを保証するのに十分異なると思います。

センサーの読み取り値が範囲外になると、アラートが生成されます。センサーの読み取り値が範囲外にある間、それらはそのアラートに関連付けられ続けるため、多くの読み取り値を含む1つのアラートになり、後でアラートをグラフ化して傾向などを見つけることができます。

ロガーの測定値と同じです。

このデータを保存するためのこれまでの私の3つのアイデアは次のとおりです。

オプション1:

場所[表]
-ID [PK]
- 名前
-HasLogger

LiveSensor[表]
--LocationId [FK]
-ID [PK]

LiveSensorReading[表]
-ID [PK]
--SensorId [FK]
- 価値

LiveSensorAlert[テーブル]
-ID [PK]
--SensorReadingId [FK](必要ない場合があります-常に少なくとも1つの読み取り値が必要です)

LiveSensorAlertCorrectiveAction[表]
--LiveSensorAlertId [FK]
--CorrectiveActionId [FK]
--ByUserId [FK]

LiveSensorAlertAcknowledgement[表]
--LiveSensorAlertId [FK]
--ByUserID [FK]

LiveSensorAlertReading[テーブル]
--SensorAlertId [FK]
--SensorReadingId [FK]

LoggerReading[表]
--LocationId [FK]
- 価値

LoggerAlert[テーブル]
-ID [PK]
--LoggerReadingId [FK](必要ない場合があります-常に少なくとも1つの読み取り値が必要です)

LoggerAlertReading[テーブル]
--LoggerAlertId [FK]
--LoggerReadingId [FK]

LoggerAlertCorrectiveAction[テーブル]
--LoggerAlertId [FK]
--CorrectiveActionId [FK]
--ByUserId [FK]

LoggerAlertAcknowledgement[表]
 --LoggerAlertId [FK]
 --ByUserID [FK]
  • 問題:繰り返しテーブルがたくさんあります(それは本当に重要ですか??)

オプション2:

場所[表]
-ID
- 名前
-HasLogger

センサー[表]
-ID [PK]
--LocationId [FK]

SensorReading[表]
-ID [PK]
--SensorId [FK]
- 価値

LoggerReading
--LocationId [FK]
- 価値

アラート[表]
-ID [PK]

AlertCorrectiveAction[テーブル]
--AlertId [FK]
--CorrectiveActionId [FK]
--ByUserId [FK]

AlertAcknowledgement[表]
--AlertId [FK]
--ByUserId [FK]

SensorAlertReading
--AlertId [FK]
--SensorReadingId [FK]

LoggerAlertReading
 --AlertId [FK]
 --LoggerReadingId [FK]
  • 問題:「アラートごとに少なくとも1つの読み取り」ルールを適用しません。
  • 問題:複数のタイプの読み取りで同じアラートを参照できるようにします。

オプション3:

場所[表]
-ID
- 名前
-HasLogger

センサー[表]
-ID [PK]
--LocationId [FK]

SensorReading[表]
-ID [PK]
--SensorId [FK]
- 価値

LoggerReading
--LocationId [FK]
- 価値

アラート[テーブル]「スーパーテーブル」
-ID [PK]

LoggerAlert[テーブル]
--AlertId [PK、FK]
--LoggerReadingId [FK]

SensorAlert[表]
--AlertId [PK、FK]
--SensorReadingId [FK]

AlertCorrectiveAction[テーブル]
--AlertId [FK]
--CorrectiveActionId [FK]
--ByUserId [FK]

AlertAcknowledgement[表]
--AlertId [FK]
--ByUserId [FK]

SensorAlertReading[表]
--SensorAlertId [FK]
--SensorReadingId [FK]

LoggerAlertReading[テーブル]
 --LoggerAlertId [FK]
 --LoggerReadingId [FK]
  • 問題:同じアラートを参照するLoggerAlertとSensorAlertを停止するものはありません(オプション2と同じ問題)。
  • 問題:データベースをわかりにくくします(スーパーテーブルはOOの概念ではありませんか?データベースは純粋にリレーショナルであることが意図されていますね?)

これまでのところ、オプション1を選択していると思います。これは、テーブルを効果的に繰り返しているにもかかわらず、オプション1が非常にクリーンで、意図が明確であるためです(私は願っています!)。

私が今考えた唯一のわずかな問題は、さまざまなセンサーの読み取り値が1つのアラームに関連付けられる可能性があることです。

上記の選択肢について、人々の意見はどうなっているのだろうか。静かにすることをお勧めする「スーパーテーブル」をよく使用しますが、何らかの理由で正しく感じられません。特に、データの整合性を確保する方法を見ると、ちょっとしたハックのように感じます。リレーショナル設計よりもオブジェクト指向プログラミングに似ているようです。

ありがとう。

編集: 以下の質問のいくつかに答えるのに役立ついくつかのさらなる情報:

ほとんどの場合、データベースは、違いが生じる場合は、アプリケーションサーバーを介してのみ操作されます。

ライブアラートとロガーアラートは通常同じように扱われるため、ロガーアラートとライブアラートを異なる方法で処理するのではなく、ほとんどの場合、すべてのアラートを処理することになります。

ロガーには、ロケーションテーブルに存在するかなり特定の列があります。場所とロガーは1対1のマッピングになるので、別のロガーテーブルを使用しないことにしました。これまでのところ、問題なく機能し、シンプルに保たれているようです。列の例:LoggerRFID(int)、LoggerUpperLimit(float)、LoggerLowerLimit(float)など。ロガーはセンサーであるとほぼ主張できますが、私はその道を進みましたが、あまりうまくいきませんでした。

私はアラートを一般的なものにすることをほぼ受け入れることができますが、回答の1つが言ったように、私はこれについて非常に確信を持って努力しているので、特定のパスを選択する前にできるだけ長く調査を続けます。

4

3 に答える 3

1

この質問は、完全なデータモデルを使用して、他の質問で回答されたと思います。それ以外の場合(未解決のものがある場合)、この質問に編集を投稿してください。

Supertype-Subtype Relational構造に興味がある場合は、一般的な意味で、この質問に興味があるかもしれません。

この質問を閉じることをお勧めします。

于 2010-12-09T07:26:19.510 に答える
1

オプション1のミラーリングされたテーブルにObjectType列を追加し、SensorまたはLoggerのいずれかの値を指定できます。データベースの設計は次のようになります。

Location [Table]
- Id
- Name
- HasLogger

ObjectType [Table]
- Id [PK]
- Name -- either Sensor or Logger
- Description

Object [Table]
- Id [PK]
- LocationId [FK]
- ObjectTypeId [FK]

Reading [Table]
- Id [PK]
- ObjectId [FK]
- Value

ObjectReading
- ObjectId [FK]
- ReadingId [FK]

Alert [Table]
- Id [PK]
- ReadingId [FK]

AlertCorrectiveAction [Table]
- AlertId [FK]
- CorrectiveActionId [FK]
- ByUserId [FK]

AlertAcknowledgement [Table]
- AlertId [FK]
- ByUserId [FK]

この設計は、データベースの根本的な目的を少し曖昧にします。これは主に、「オブジェクト」よりも「センサーまたはロガー」を説明するのに適した単語が考えられなかったためです。場所、それは確かにデータベースの理解を容易にするでしょう。

テーブル内の非整数IDについて特に気にしない場合は、ObjectTypeからId列を削除し、Nameを主キーにすることもできます。ただし、主キーが整数ではないObjectTypeのようなテーブルで悪い経験をしたことがあるので、ほとんどの場合、主キーを使用します。

また、各テーブルの主キーIDには「Id」よりも長い名前を付ける必要があるという上記のKMの評価にも同意します。

于 2010-11-29T17:41:10.893 に答える
1

これに関するいくつかの考え(アイデアと意見、答えではありません):

「スーパーテーブル」(タイプ/サブタイプ)モデルは説得力がありますが、実装とサポートが難しい場合があります。いくつかのトリック:

ALERT
  AlertId    PK 1/2
  AlertType  PK 2/2  Check constraint (1 or 2, or better L or S)

...つまり、複合主キー。「タイプ」は常にL)ogまたはS)ensorである必要があります。

LOGALERT
  LogAlertId  PK 1/2  FK 1/2
  AlertType   PK 2/2  FK 2/2

(and again for SENSORALERT)

...つまり、同じ複合主キーであり、外部キーは両方の列にあります。このようにすると、特定のタイプテーブルに対してサブタイプテーブルは1つしか存在できず、一番上のテーブルには、どのサブタイプが関係しているかが明確に示されます。サブタイプテーブルに行が存在することを強制する方法はないため、データを慎重に設定してください。そして、クエリの複雑さの多くは、ビューを使用して処理(カバーされますか?)できます。

欠点は、複雑で、(まだ)慣れていない人には混乱を招き、追加のサポートと労力が必要になることです。本当の問題は、それだけの価値があるのか​​ということです。

  • ログやセンサーだけでなく、すべてのアラートにどのくらいの頻度で対処する必要がありますか?ほとんどの場合、どちらか一方だけを処理する必要がある場合は、おそらくそれだけの価値はありません。
  • ログまたはセンサー固有の詳細をどの程度処理する必要がありますか?個々のアラートに関連する実際のイベント以外に、追跡する無数の属性(列の詳細)は両方のタイプでどの程度類似していますか?ユーザー、確認応答、および修正措置が(十分に)同一である場合、それらをALERTの属性(列)にすることができますが、そうでない場合は、それらを適切なサブタイプの属性にする必要があり、スーパータイプの統合の利点が失われます。
  • そして、あなたは今、設計時にそれを正しくしなければなりません。研究し、質問をし、水晶玉をじっと見つめます(つまり、将来、すべての人の現在の仮定を無効にするために何が起こるかを考えます)。
于 2010-11-29T17:44:47.630 に答える