2010-06-02 74 views
3

嗨我正在開發一個發票應用程序。發票和發票行:您如何存儲客戶地址信息?

所以總的想法是有兩個表:

發票(ID,日期,CustomerAddress,CustomerState,CustomerCountry,增值稅,合計); InvoiceLine(Invoice_ID,ID,Concept,Units,PricePerUnit,Total);

正如你所看到的,這個基本的設計會導致很多記錄的重複,客戶端將擁有相同的地址,州和國家。

因此,替代方法是有一個地址表,然後建立關係地址<-發票。

但是,我認爲發票是不可變的文件,應該按照它最初制定的方式存儲。有時客戶會更改他們的地址或狀態,以及是否來自地址目錄,這些地址目錄會更改所有先前製作的發票。

那麼你有什麼經驗?

客戶地址如何存儲在發票中?在發票表中?地址表?或者是其他東西?

您能提供指向書籍,文章或文檔的指針嗎?

回答

7

我強烈建議不要在發票中存儲任何客戶詳細信息。

相反,我會像一個結構:

Customer表,用ID的主鍵

客戶地址表中(因爲每個客戶可能有一段時間不同的地址),與客戶id作爲外鍵

發票表,地址字段是客戶地址表的外鍵。

順便說一句,我會考慮增加每行項目的增值稅字段。有些國家對不同的物料類型有不同的增值稅稅率。

+0

您不覺得發票表幾乎就像歷史表一樣,因此關於發票最初打印的信息的重複信息是否有效? – elviejo79 2010-06-02 00:43:40

+2

@elviejo,可以證明你是正確的,但你必須評估你是否想要一遍又一遍地存儲相同的信息,或者只是將一個foriegn密鑰存儲到所使用的地址。如果您存儲了foriegn密鑰,那麼它意味着一旦發票鏈接到它就不能更改舊地址,相反,任何更改都必須成爲新的地址記錄,並且只需在地址表上維護一個標誌,以指示地址是否有效。 – slugster 2010-06-02 00:58:42

+1

@elviejo您也可以在不必爲客戶更改整個地址維護過程的情況下執行此操作。當訂單成爲發票時,您可以鏈接到一個客戶實體和一個「匿名」地址實體(可能是賬單到發貨的角色),它們只包含發票時的地址。您查看所有地址欄並獲取代理鍵。這個「地址」歷史從不更新,只能插入。之前的地址只是重複使用。因此,您可以獲得時間點數據,而無需改變您的整個客戶維護設計。 – 2010-06-02 02:00:26

1

大多數標準的產品/訂單數據庫將有

a products table (ProductId, product info fields) 
a customers table (CustomerID, customer info like address etc) 
and an orders table (OrderNumber, CustomerID, date, etc) 

那麼你的訂單項目成爲訂單和產品之間的多對多的關係表。

orderItems (OrderNumber, ProductID, quantity, purchasePrice, vat, etc) 

要獲得完整的發票,您需要查詢訂單表並將其與OrderItems表一起加入。 OrderItem通常具有購買價格等因爲產品表中的價格可能會在創建訂單後發生變化,並且該信息通常對於存儲有用。

+1

雖然我同意你的一般設計,但過去我一直批評orderItems沒有遵循標準化,因爲你將在產品ID中擁有數千或數百萬(Billions?)相同的信息,價格等。你如何解釋這一點,或者這是一個正常化失敗的例子嗎? – JM4 2012-07-18 22:23:16

0

我認爲這樣做有三個表:Customer,InvoiceAddress,但它的構造,使一旦輸入地址,它永遠不會更新或刪除,只有棄用。您的地址表中可以有一個IsDeprecatedIsActive布爾型字段。然後,當您創建發票時,發票鏈接到客戶ID和當時正在使用的地址ID。當客戶更改其地址時,將使用新的AddressID創建一個新記錄,並用布爾字段廢棄舊記錄。或者,如果你真的想保持良好的記錄和/或將永遠需要查看這些數據,你可以有一個AddressActiveStartDateAddressActiveEndDate,但這會使查詢更復雜一點。

這樣,您仍舊保存舊地址,並且仍然與客戶鏈接以供參考,同時還允許客戶擁有多個列出的地址(例如一個用於裝運,一個用於開票)。

您可以根據需要添加更多表格,例如Product,InvoiceLineState