簡體   English   中英

從數據庫中指定關系可以得到什么?

[英]What do I gain from specifying relationships in my database?

我正在MS Access 2010中建立一個項目。我以前在Oracle中有經驗。 我正在閱讀有關MS Access的信息,並不斷看到對表關系的引用。 它看起來像是一種協助普通人進行數據輸入和驗證以及進行查詢構建的便捷方法,但是我僅以SQL模式編寫查詢,並為具有自己驗證規則的表單的用戶強制執行數據輸入。

加強關系真的必要嗎? 看起來它並沒有真正使我獲得任何高級幫助,並且實際上可能給我或最終導致我接管維護工作的其他人帶來問題。 我以前從未使用過它們,現在也沒有真正受益。 有人可以闡明這一點嗎?

您說您曾經有過Oracle的經驗。 您是否從未在Oracle中定義外鍵約束? 如果這樣做了,那么這就是在Access中定義關系時要做的事情。 您可以使用它來加強參照完整性(如果子記錄仍然存在,則不允許刪除父記錄),或者,如果使用了cascade delete選項,則可以在刪除父記錄時自動刪除子記錄。 這是一個有用的備份,用於覆蓋編碼錯誤,在這些錯誤中,您可能忘記了可能的子記錄,如果未定義關系(FK),這些子記錄將被孤立。

對於僅查詢數據的人,關系並不是那么重要。 但是,從應用程序的角度來看,即使不是很重要,它們也非常有用。

例如,您可能有一個客戶表,然后說一個訂單表。 業務規則是,除非先擁有一個客戶,否則您無法創建訂單。 因此,如果您自由編寫一些SQL以添加沒有客戶的訂單,則您的更新/插入查詢將不起作用。 而且,如果您需要刪除客戶,那么該客戶的所有訂單都可以/將自動為您刪除,而不必編寫復雜的delete SQL語句。 例如,您可能想刪除所有5或10年以上的客戶(因此他們是不活躍的)。 當您刪除這些客戶時,您希望所有訂單也都被刪除。 (如果您必須刪除具有強制關系的每個客戶的子記錄,這是一個很難編寫的查詢,那么所有子記錄將自動為您刪除(強制級聯刪除))。

從報告的角度來看,這也很重要。 如果您編寫查詢以顯示本月的所有客戶及其帳單總額,那么您將獲得一個總計結果。 但是,如果您決定不希望顯示/包含客戶,則可以僅點擊訂單表並以這種方式獲得總額。 問題出在沒有RI的情況下,那么您可能(偶然或什至只是一些啟動訂單的用戶)已經輸入了訂單信息(總金額),但沒有客戶。

現在發生的事情是,當您運行兩個不同的報告/查詢時,您發現總數是不同的! 在一個復雜的應用程序中,“為什么”兩個報告不同可能需要幾天的時間,或者甚至需要一周才能獲得大量數據,以弄清為什么兩個月度銷售報告彼此不一致。 如果您執行業務規則,除非他們有客戶,否則無法將訂單輸入系統,那么您就可以消除報告中的此類錯誤。 您可以“說”自己是SQL的完美用戶,但是擁有大量的代碼,大量的數據輸入形式,如何確保沒有客戶輸入訂單。 數據輸入期間的用戶可能會忘記以該訂單形式輸入客戶。 而且,即使您以該訂單的形式編寫代碼以確保必須選擇客戶,也許您在編寫某些SQL的過程中偶然將訂單記錄插入到沒有客戶的系統中。 但是,您的每月客戶總計報告查詢“假設”您有一個客戶記錄,然后將其加入訂單總計數據中。

但是,某些報告必須僅基於訂單數據運行(每月匯總總數不需要包括客戶)。 現在問題出在系統中某處,您的訂單記錄中包含沒有客戶的總數據。 結果是不同的報表,現在對銷售總額的詢問不同意。 這是一場徹頭徹尾的噩夢。

因此,應用程序代碼中可能會出現一些錯誤或錯誤,導致現在應該具有“孤立”記錄的關系數據。 也許您的業務規則允許在不分配客戶的情況下輸入訂單,但是您的月度銷售報告將必須顯示該事實,或者任何命中訂單表但不包括客戶的查詢都必須“檢查”那些可能性查詢尚無客戶記錄存在。

上面只是刮擦出現的GAZILLION問題的表面而已。 因此,盡管您可能只是在數據上創建簡單的查詢,但問題在於系統中數據是否正確關聯? 關於垃圾進來=垃圾出的老話在這里是正確的。

最終,當您使用SQL查詢具有MULTIPLE表的拉取數據時,您就必須對該數據及其關系完整性(RI)做出假設。 因此,當您編寫該查詢以顯示客戶及其訂單總數時,您將ASSUME拖放到客戶表中,然后在訂單表中進行關系聯接。 但是,如果存在沒有客戶記錄的訂單,那么您的查詢將不會產生正確的值。 更糟糕的是,命中訂單表的報告現在將產生不同的結果。

如果您強制執行RI,那么無論如何,在沒有FIRST創建客戶記錄之前,您都無法偶然或強制輸入訂單。 如果您不執行此類規則,那么您的數據將產生錯誤的結果。

一個典型的復雜應用程序將具有40或70個相關表。 而且,這些表中的每個表都將基於您的一組業務假設,對是否假設“假設”已正確創建了父(或子)記錄進行了假設。

您可能有一個旅游預訂系統。 客戶可能會打電話,付了定金,但還沒有被預訂參加特定的旅行。 如果您允許此設置,則本月對客戶的查詢及其預訂的游覽必須考慮到這一點。 但是,可能的業務規則是,系統中放下錢的任何客戶也必須預訂旅行團(因此,您查詢以獲取該信息將考慮此規則)。

如果您始終進行的每個查詢都不會包含多個表中的數據,那么執行關系數據可能不會給您帶來太多好處。 但是,當您開始將查詢與多個表捆綁在一起時,您必須知道有關該數據的假設,然后才能編寫查詢。 那么,您是否允許沒有系統預訂的客戶預訂旅行團? 該規則將決定您必須如何編寫該查詢。 如果強制執行RI,那么您可以查詢客戶的“預訂”,並知道它將附加到巡回活動中。 如果任何預訂+押金不需要預訂,情況也是如此-但是您必須知道有關該數據的假設。

因此,基於對數據所做的假設是基於這些假設創建查詢以提取數據的唯一實用方法。 而且,如果您執行RI,那么您至少知道必須與數據相關並根據這些假設進行設置。

在一天結束時? 任何在不強制執行RI的情況下創建可對業務應用程序和規則建模的數據庫的人,都在建造沒有方向舵和指南針的船。

從每個表中導出數據是一個非問題。 但是,如果該數據是一團糟並且具有孤立的記錄,那么最終只能將不正確的數據模型導出到另一個數據庫,而所有問題仍然存在。

如果僅在SQL模式下構建查詢,則定義關系可能對您沒有任何影響。 唯一有用的是,如果您構建了某個東西,但是幾個月后再也不看它,您將能夠在概念上快速重新熟悉自己。

對於使用Access查詢構建器的任何人,定義關系都可以使您快速向查詢中添加表,而Access會自動為查詢JOIN構建適當的(GIGO)關系。 同樣,如果您正在使用SQL編寫代碼,那么您可能已經這樣做了,因此在查詢構建方面對您沒有太大幫助。

底線-至少在您嘗試將表導出到“真實的” RDBMS之前,它更像是一種圖形化工具,可以簡化查詢過程,就像其他人已經提到的那樣。

如果不是用例的要求,則不必使用它。 在“基於訂單的方案”中可能是“需要”一個用例。

假設您有一個創建和跟蹤訂單的數據庫。 每個訂單可以有多個綁定到同一訂單的行。 但是出於標准化的目的,大多數人會將它們分成兩個單獨的表。 OrderHead和OrderDetail。 您可能要在此處強制執行“引用完整性”,以確保OrderDetail中永遠不會有子記錄不鏈接回父訂單。

我敢肯定,沒有它,您可以阻止類似的事情,但是它主要只是強制執行它。

關系有助於保持數據的完整性,我同意您的觀點,即如果用戶是從訪問表單進入的,則由於完整性而導致錯誤的可能性較小。 但是將來,如果用戶從MS Access轉向純RDBMS,這種關系肯定會有所幫助。

盡管關系的目標不是在以后的某個時間點遷移,但對於您而言,這是我可以想到的一個正當理由。

除此之外,對於具有自己的窗體關系的MS Access,可能不會添加特定的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM