2013-04-07 75 views
4

我剛剛開始使用數據庫,並且遇到與member_address entitiy相關的規範化錯誤。由於沒有代表,我似乎無法發佈圖片,所以我會嘗試解釋我的表格。正常化成員地址

會員(表)
PK Member_ID
FK Member_Zip_Code
FK Membership_Type_code
ATT:將First_Name
ATT:LAST_NAME
ATT:Member_Phone
ATT:MEMBER_EMAIL

Member_Address(表)
PK Member_Zip_Code
FK Member_ID
ATT:成員地址
ATT:Member_State
ATT:Member_City

我不太明白如何處理這個。我在想,我需要兩個獨立的表格才能正確顯示數據,但看起來我的PK和FK在這裏並不完全正確。是不是最好有一個充滿國家和城市的桌子?或者有一個郵政編碼查找城市?相當迷茫...

+0

會會員已超過一個地址? – 2013-04-07 15:25:00

+0

@davidstrachan一個成員可能只有一個地址,但地址可能屬於多個成員 – user168403 2013-04-07 15:29:38

回答

6

在現實世界中,人們可以共享相同的地址,並且一個人可以有多個地址。此外,人們可以移動(不確定這對於你的模型是否重要),因此人與地址之間的關係應該具有date_from/date_through屬性(同樣,它在應用程序的上下文中可能不重要,因此可以跳過此部分) 。因此,我的東西去像

國家
COUNTRY_ID(PK)

國家
STATE_ID(PK)

COUNTRY_ID(FK)

地址
ADDRESS_ID(PK)
STATE_ID(FK)
COUNTRY_ID(FK)
城市
- 其他屬性,如地址行,unit_number,POSTAL_CODE等等

**注:爲簡單起見,我存儲STATE_ID和country_id在這裏,這在某種意義上打破了正常化。但是,你可能想讓人們不要進入國家,而不是所有國家都有國家。

Member_Address
member_address_id PK
member_id FK
ADDRESS_ID FK
date_from
date_thru
UNIQUE(member_id,ADDRESS_ID,date_from)

此外,您可能要添加地址目的實體,並在地址目的和會員地址之間添加關係(例如,如果您需要區分家庭地址/工作地址/郵件地址)。

進一步說,你會看到,郵寄地址,電話和電子郵件是所有通信手段,所以他們都可以被當作普通實體的亞型,例如communication_mechanism ...

+0

感謝您的幫助...對於這個實例國家不是一個因素,但您如何看待我更新的問題? [鏈接](https://www.dropbox.com/s/pxwegnrlpj7y04q/Drawing1.jpg) – user168403 2013-04-07 16:19:14

+0

@ user168403:它看起來對我來說很好(「更新後的表格」)。只需要注意一點:如果'member_address'只是一個鏈接表,就不需要添加代理PK(member_address_id),複合PK(member_id,address_id)就足夠好了。我將PK'member_address_id'添加到我的模型中,因爲表具有額外的屬性並可能有相關的實體。在你的模型中,你沒有這樣的屬性和進一步的關係,所以不需要它。無論如何,即使你離開它也不會傷害... – a1ex07 2013-04-07 16:29:02

+0

A1ex07,如果您願意與設計中的其他實體保持聯繫,我還有幾個問題想問一下。有沒有辦法在這裏的房間設置聊天? – user168403 2013-04-07 17:54:48

0

從實體和關係(概念設計)的角度思考,而不是直接構建物理模型(表格和索引);你在你的問題中描述了一種混合體。

然後,確定唯一標識每個實例的每個實體的屬性。這是一個(候選的,自然的)主鍵。對於每個實體,確定是否有其他(候選,自然)主鍵。

然後確定您的實體之間的每個關係,以及它的相應外鍵。對於此處的主 - 細節關係,請確定在主實體中映射到(候選自然)主鍵的詳細實體中的屬性集合,從而構成此關係的外鍵。

現在您已準備好設計概念設計的物理模型的表格和索引。

2

如果你看看http://en.wikipedia.org/wiki/Database_normalization,有很多關於標準化的有趣觀點。你當然應該研究正常化的不同程度。

就你而言,你有一些成員,每個成員都有地址。在設計中暗示一個成員只能有一個地址。同樣,您的設計意味着該成員只有一個電話和一個電子郵件地址。您可以以多種方式處理這個問題,但對於初學者來說,你可能會考慮是這樣的:

Member (Table) 
MemberID (PK) 
MemberAddressID (FK) 
MembershipType (FK) -- To a dictionary-table with membership types. 
FirstName (ATT) 
LastName (ATT) 
Phone (ATT) -- (*OR* it could be placed in a separate side-table with phonenumbers) 
Email (ATT) -- (*OR* it could also be placed in a separate side-table) 

Member_Address (Table) 
Member_ID (FK) 
Member Address (ATT) 
Member_Zip_Code (ATT) -- (*OR* it could be FK to a separate table with Zip-codes, states and cities) 
Member_City (ATT) 
Member_State (ATT) 

隨着Member_cityMember_State你嚴格來說違反了第二範式,因爲我認爲城市和國家都隱含在郵政編碼。將電話和電子郵件作爲屬性保留在表上時,您違反了規範化,因爲您的設計無法處理多個電話號碼(家庭/工作/單元)或電子郵件地址。

通常情況下,通過添加一些額外的屬性解決了即時問題,但保持違反規範化的情況下,通過務實的方式解決這個問題。乾淨/正確的解決方案是將這些信息放在一個單獨的邊欄表中,就像已經存在的地址一樣,然後通過FK/PK關係鏈接到該邊。