2010-01-20 48 views
0

我正在使用MS Visio建模數據庫,部分模型包含事務類別 - 父表具有transactionId,timestamp,amount和transactionType。有三張子表 - 支票,銀行轉帳和信用卡,所有這些都與transactionId的父項有關。MS Visio到SQL Server的分類關係

這種類型的關係是在SQL Server中實現的具體方式,還是僅僅是一個概念模型,讓實現依賴於我?如果後者,爲什麼在父表中有一個transactionType列,如果這些表都與transactionId相關 - 是否只是縮小我的查詢?也就是說,如果父表中的行將「check」指定爲transactionType,那麼我知道我只需查詢/加入檢查子表?

它剛剛發生在我身上 - 這只是一個ISA層次結構,在這種情況下,我會創建三個不同的表,每個表都包含在ISA父實體中標識的列?

回答

1

這基本上是多表繼承,雖然你可以在域中建模爲一個簡單的引用關係。

有很多很好的理由讓選擇器字段/屬性。顯而易見的一點是,應用程序或服務可以獲得有關如何加載細節的提示,因此它不必從每個可以想到的表中加載所有可能的行(當您有20種不同類型的事務時嘗試此操作)。

另一個原因是,大部分時間,最終用戶不一定需要知道事務的細節,但確實需要知道類型。如果您正在查看來自某個財務或計費系統的A/R報告,則大多數情況下,您需要知道的基本報告的前一個餘額,金額和後續餘額以及交易類型。沒有這些信息,就很難閱讀。分類賬不一定會顯示每筆交易的詳細信息,有些系統甚至可能根本不會跟蹤詳細信息。

這種類型的模型最常見的替代方案是單個表,每個不同的事務類型都有一大堆可爲空的列。雖然我個人鄙視這個模型,但它是許多隻支持單表繼承的對象關係映射器的要求。這是您希望(或不想)在數據庫中建模的唯一方式。

+0

「多表繼承」原來是我一直在尋找的搜索關鍵字。谷歌提出了這一點:http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server 該文章回答了幾個問題。其次是如何強制一個交易成爲唯一可用的子類型之一。它看起來像是父表中的transactionType列的一半。 謝謝! – Matt

1

父表的TRANSACTIONTYPE是有用的,如果你想查詢的所有交易金額,例如總結各交易類型的金額:

select transactionType, sum(amount) 
from transactions 
group by transactionType 

沒有列,你仍然可以做到這一點在子表上查詢:

select 
    case when c.transactionId is not null then 'CHEQUE' 
     when cc.transactionId is not null then 'CREDIT CARD' 
     ... 
    end 
, sum(amount) 
from transactions t 
left join cheque c on t.transactionId = c.transactionId 
left join creditcard cc on t.transactionId = cc.transactionId 
... 
group by 
    case when c.transactionId is not null then 'CHEQUE' 
     when cc.transactionId is not null then 'CREDIT CARD' 
     ... 
    end 

正如您所看到的那樣,這很難,並且需要擴展您添加的每種事務類型的查詢。

+0

不僅困難,而且它也是狗慢。大多數情況下,選擇器列將被編入索引,但鳥巢的連接幾乎不可能優化。 – Aaronaught