2010-11-29 71 views
3

我想要決定一個數據庫設計。更具體地說,這是更大設計的一個子部分。基本上,有「位置」 - 每個位置可以有任何數量的傳感器與它相關聯,它可以有一個記錄器(但只有1個)。數據庫「超級」對比更多的表vs普通表

我有傳感器讀數,我有記錄器讀數,每個不同,我認爲需要單獨的表格。

如果傳感器讀數超出範圍,則會生成警報。雖然傳感器讀數超出範圍,但他們仍然與該警報關聯,因此您最終會收到1條包含許多讀數的警報,以便稍後繪製警報,以便我可以發現趨勢等。

與記錄儀讀數相同。

這裏是我的想法3到目前爲止,用於存儲這樣的數據:

選項1:

 
Location [Table] 
- Id [PK] 
- Name 
- HasLogger 

LiveSensor [Table] 
- LocationId [FK] 
- Id [PK] 

LiveSensorReading [Table] 
- Id [PK] 
- SensorId [FK] 
- Value 

LiveSensorAlert [Table] 
- Id [PK] 
- SensorReadingId [FK] (may not be needed - enforces need to always have at least 1 reading) 

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

LiveSensorAlertAcknowledgement [Table] 
- LiveSensorAlertId [FK] 
- ByUserID [FK] 

LiveSensorAlertReading [Table] 
- SensorAlertId [FK] 
- SensorReadingId [FK] 

LoggerReading [Table] 
- LocationId [FK] 
- Value 

LoggerAlert [Table] 
- Id [PK] 
- LoggerReadingId [FK] (may not be needed - enforces need to always have at least 1 reading) 

LoggerAlertReading [Table] 
- LoggerAlertId [FK] 
- LoggerReadingId [FK] 

LoggerAlertCorrectiveAction [Table] 
- LoggerAlertId [FK] 
- CorrectiveActionId [FK] 
- ByUserId [FK] 

LoggerAlertAcknowledgement [Table] 
- LoggerAlertId [FK] 
- ByUserID [FK] 
  • 問題:重複表的地段(這個真的還重要,雖然??)

選項2:

 
Location [Table] 
- Id 
- Name 
- HasLogger 

Sensor [Table] 
- Id [PK] 
- LocationId [FK] 

SensorReading [Table] 
- Id [PK] 
- SensorId [FK] 
- Value 

LoggerReading 
- LocationId [FK] 
- Value 

Alert [Table] 
- Id [PK] 

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

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

SensorAlertReading 
- AlertId [FK] 
- SensorReadingId [FK] 

LoggerAlertReading 
- AlertId [FK] 
- LoggerReadingId [FK] 
  • 問題:不強制規則 「至少1 每個警報讀書」。
  • 問題:允許多個類型的 讀取引用相同的警報。

選項3:

 
Location [Table] 
- Id 
- Name 
- HasLogger 

Sensor [Table] 
- Id [PK] 
- LocationId [FK] 

SensorReading [Table] 
- Id [PK] 
- SensorId [FK] 
- Value 

LoggerReading 
- LocationId [FK] 
- Value 

Alert [Table] "super table" 
- Id [PK] 

LoggerAlert [Table] 
- AlertId [PK, FK] 
- LoggerReadingId [FK] 

SensorAlert [Table] 
- AlertId [PK, FK] 
- SensorReadingId [FK] 

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

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

SensorAlertReading [Table] 
- SensorAlertId [FK] 
- SensorReadingId [FK] 

LoggerAlertReading [Table] 
- LoggerAlertId [FK] 
- LoggerReadingId [FK] 
  • 問題:沒有停止 LoggerAlert和SensorAlert 引用相同的警報(同樣的問題 作爲選項2)。
  • 問題:數據庫模糊處理

我認爲到目前爲止,我prefering(不 超霸表更面向對象概念的 數據庫是爲了純粹 關係是不是?)選項1,因爲它看起來很乾淨,意圖很清楚(我希望!),即使我有效地重複表格。

我剛纔想到的唯一的小問題是,不同傳感器的讀數仍可能與一個警報關聯。

我想知道人們對上述選項的看法。我已經看到使用「超級表」經常會推薦安靜,但出於某種原因,它只是感覺不對 - 它幾乎感覺有點像黑客,特別是當我看到嘗試確保數據完整性的方法時。它看起來更像OO編程而不是關係設計。

謝謝。

編輯: 一些進一步的信息,以幫助回答以下一些問題:

大多數的數據庫只能通過應用服務器操作的時候,如果有什麼差別。

實時警報和記錄器警報通常被視爲相同,所以我可能會在大多數時間處理所有警報,而不是以不同方式處理記錄器警報和實時警報。

記錄器具有相當特定的列,位於位置表中。由於位置和記錄器是1對1的映射,因此我決定不使用單獨的記錄器表,到目前爲止它似乎工作得很好並保持簡單。示例列:LoggerRFID(int),LoggerUpperLimit(float),LoggerLowerLimit(float)等等。您幾乎可以認爲記錄器是一個傳感器,但是我沿着這條路走下去,結果並沒有太好。

我幾乎可以接受使警報通用,但作爲答案之一,我試圖對此非常確定,因此在選擇特定路徑之前儘可能繼續研究。

+4

如果我不得不在這些表上工作,我寧願你不會有任何名爲「Id」的列。對我而言,FK列和PK列具有相同的名稱會更容易。只需在「SensorAlert」表中將「Id」名稱展開至「SensorReading」表中的「SensorReadingId」即可。這有助於在需要搜索大量代碼時(您在「Id」上獲得了100萬次虛假搜索,但在「SensorReadingId」上只有很少的次數),或者對許多表進行大量查詢,每個表都有一個「Id」列。 – 2010-11-29 17:24:18

+0

積分 - 這是我總是這樣做的,但肯定會考慮改變我的方式,因爲論證看起來有效。 – Mark 2010-11-30 09:42:47

回答

1

的幾點思考這個(想法和意見,而不是答案):

的「超表」(類型/子)模型是引人注目的,但很難實現和支持。一些技巧:

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

...也就是說,化合物主鍵,其中 「類型」 必須總是L)OG或S)恩索爾。

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

(and again for SENSORALERT) 

...也就是說,相同的複合主鍵,並且外鍵在兩列上。以這種方式完成,對於給定的類型表,只能有一個子類型表,頂部表清楚地顯示涉及哪個子類型。沒有辦法強制在子類型表中存在一行,因此請仔細設置您的數據。而查詢的複雜性大部分可以使用視圖來處理(掩蓋?)。

缺點是,對那些還不熟悉的人來說,這很複雜,令人困惑,並且需要額外的支持和努力。真正的問題是,它值得嗎?

  • 必須多久應對所有警報,不僅登錄或只傳感器?如果大多數情況下你只需要處理一個或另一個,這可能是不值得的。
  • 您需要處理多少特定​​於日誌或傳感器的詳細信息?除了與單個警報相關的實際事件之外,這兩種類型之間的相似程度如何,您將跟蹤的是無數屬性(列中的詳細信息)?如果用戶,知識庫和糾正措施(足夠)是標準化的,則可以將它們設置爲ALERT的屬性(列),但如果不是,則必須使它們成爲適當子類型的屬性,並且失去了超類型的整合優勢。
  • 現在,您必須在設計時間內弄清它的正確性。研究,提出問題,凝視水晶球(即思考未來可能會發生什麼,使每個人的假設無效),因爲如果你現在錯了,那麼你和你的後繼者可能不得不永遠與它共處。
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」更長的名稱。

+0

這與我的想法很相似。在我輸入/子類型警報的地方,@jwiscarson將其升級爲日誌/傳感器。我專注於警報,因爲它們看起來很相似,而且我猜測日誌/傳感器有更多獨特的細節需要管理......但是如果沒有,是的,在這個級別輸入/子類型。 – 2010-11-29 17:48:30

1

我認爲這個問題已經在您的other question回答了,有完整的數據模型;否則(如果有任何未完成的),請發佈編輯到此問題。

如果您對Supertype-Subtype感興趣,一般意義上的關係結構this question可能會對您感興趣。

我可以建議你關閉這個問題。