2

我有一個數據庫(一個寵物坐在公司):許多人在MS Access包含表格的以下許多關係

  • 客戶
  • 緊急聯繫人
  • 電話號碼
  • 手機類型

電話號碼存儲在一個單獨的表中,以允許有效存儲幾乎無限數量的電話號碼s每個客戶。除主鍵以外,電話號碼錶還存儲客戶ID和電話類型ID。我的問題是 - 是否允許緊急聯繫人與電話號碼記錄具有相同的功能以在電話號碼錶「緊急聯繫人ID」中添加另一個字段?還是應該將緊急聯繫人存儲在與客戶相同的表中(並將其重命名爲個人)?如果是這樣,請告訴我如何在同一個表中的記錄之間建立關係。

非常感謝, 傑西卡

回答

0

你必須問自己一個問題:你應該在多大程度上尊重數據規範化規則?

我不知道是什麼PhoneTypes表將包含,但如果是喜歡的事情的清單移動工作首頁iPhone你可能會有點過頭了已經:你並沒有構建一個聯繫人應用程序,你正在構建一個Pet Sitting應用程序,可能會有更重要的軟件領域需要你的開發時間。

增加軟件的複雜性是代價高昂的:實現功能的時間往往會增加,複雜性也隨之增加,出現錯誤的風險,維護成本以及性能往往受到影響。

這些聯繫人詳細信息實際上只是客戶的屬性。

客戶可以有多個電話號碼和多個緊急聯繫人。
通常這些應按重要性排列,所以如果需要出現,您可以先打電話給最相關的人。

沒有更多的信息,我會處理這個問題的方式只是在我的Customer表中留下2個備忘錄字段,應用程序的用戶可以以任何她喜歡的方式輸入數據,以便她可以按照正確的順序,必要時做註釋(週一只有打電話,客戶的媽媽,上午11:00以後纔打電話等)。

如果您願意,您可以進一步限制數據輸入,例如在用戶輸入詳細信息之前單擊用戶輸入詳細信息,然後單擊將數據附加到該字段的「添加」按鈕,例如通過使用半conlon或CrLf來分隔記錄。數據然後可以分割在分號或CrLf上,並顯示在表單上的列表框中以便更好地呈現。
您可以用同樣的方式處理客戶電話號碼和緊急聯絡電話號碼。

這使事情變得簡單:所有客戶數據都在一張表中,而不是在多個表中拆分,沒有不必要的連接,它不會佔用比使用多個表更多的空間(實際上,它將節省空間)。它使報告變得簡單(您可以簡單地顯示客戶列表,並且可以顯示所有客戶的所有可用電話號碼,而無需執行任何操作),它還使搜索變得輕鬆。

在單個字段中有多個值對外設數據很常見。
除非您絕對需要分開聯繫人,並根據它們製作複雜的報表或確保可以重新使用它們,否則不必爲每一個信息都創建表格。讓應用程序用戶輸入與客戶相關的內容。
限制數據輸入格式化並檢查其一致性(如果需要),但最終,除非軟件的目的是維護複雜的聯繫人列表,否則不要讓它比應該更難。一點VBA和一些字符串操作足以限制數據,允許它以用戶最相關的順序重新排列,並且它會通過避免一些複雜性讓你的應用更加快速。

無論如何,無論如何,我會從簡單的事情開始,稍後再看看如果將多個表格中的數據進行分割是合理的。
避免過早優化。

但是,如果你覺得你真的需要通過這本書來處理這個問題,我可能會處理這件事如下:

存儲所有信息到Contact表,可能有這樣的特性:

  • ID:唯一接觸式ID
  • PhoneNumber:TEXT
  • PhoneTypeID:(不管它是什麼,如果它鏈接到你的PHONETYPE表)
  • IsEmergencyContact:BOOLEAN
  • ContactName:文本,自由,如何解決聯繫人
  • CustomerID:外鍵鏈接到客戶表
  • Notes:備忘錄,有關接觸
  • Rank任何有用的信息: INTEGER,對此聯繫人重要的排序等級

如果要將客戶與聯繫人分開,那麼您可以重新使用聯繫人多個客戶,那麼你需要一箇中間表:

Contact表將成爲:

  • ID:唯一接觸式ID
  • PhoneNumber:TEXT
  • PhoneTypeID:(不管它是什麼,如果它鏈接到您的PhoneType表格)
  • ContactName:TEXT,自由格式,如何解決聯繫人
  • Notes:備忘錄,有關接觸

而且CustomerContact表中的任何有用的信息(這使得許多一對多的關係可能):

  • CustomerID:外鍵鏈接到客戶表
  • ContactID:外鍵鏈接到聯繫表
  • IsEmergencyContact:BOOLEAN
  • Rank:INTEGER,重要的這個接觸的排序排名

顯示和管理聯繫人和緊急聯繫人名單列表中,你只需要篩選的每種您展示基於是否IsEmergency信息列表框或窗體是真的還是假的。現在

,如果你想在同一聯繫人有多個電話號碼,你將不得不拆分一切更進一步:

Contact表將成爲:

  • ID:唯一接觸式ID
  • ContactName:TEXT,freeform,如何解決聯繫人
  • Notes:備忘錄,有關聯繫人的任何有用信息

一個PhoneNumber表將包含:

  • ID:電話記錄ID
  • ContactID:外鍵鏈接到聯繫表
  • PhoneNumber:TEXT
  • PhoneTypeID:(不管它是什麼,如果它鏈接到您的PhoneType表格)
  • Notes:MEMO,關於這個特定的電話號碼的任何有用的信息

現在你有4個表來存儲你所需要的所有信息,並共享任何你想要的方式,讓客戶可以有多個聯繫人(緊急與否),聯繫人可以有多個電話號碼,聯繫人可以翻過客戶共享(這樣一個客戶的聯繫是另一個客戶的緊急聯繫人):

  • Customer
  • Contact
  • PhoneNumber
  • CustomerContact

正如我所說的,做正確的方式將需要更大量的複雜性比也許你真正需要的。

小心不要過早地增加複雜性。預測最糟糕的情況是很好的,但通常這意味着您過早地進行了優化,因此花在軟件領域的時間並不像應用程序的核心那麼重要。
你總是要問自己:我應該花兩天時間來實現這個目標,還是花兩天時間來完善UI,測試或添加代碼以確保數據的完整性等等。

更多的,往往不是YAGNI

+0

非常感謝你這麼徹底的回答!這正是我所期待的。我想按照這本書去閱讀,因爲我將它作爲一個更復雜的數據庫的練習,我將爲我的日常工作建立一個更復雜的數據庫。但你絕對是對的 - 我會牢記大局。 – intruesiive

0

我保存它以同樣的方式爲您存儲的電話號碼;在自己的桌子上。這使您能夠存儲多個號碼,並且有些人可能有多個緊急聯繫電話號碼。在設計數據庫時,您總是要考慮可伸縮性,並計劃最複雜的情​​況。例如,我可以想象寵物坐在那裏很多客戶會通過口頭傳達,而且很可能你會爲多個客戶使用相同的聯繫人。

+0

感謝您回答Johnny!這有很大幫助 - 雷諾對我進行了擴展。 – intruesiive

0

你的第一直覺(存儲客戶和聯繫人在一個表中)是正確的。如果你仔細想想,客戶和聯繫人都是人。只是客戶和緊急聯繫人都是人員的特殊情況。我們可以使用關係數據庫對此進行建模。

讓我們創建一個表,用於存放人信息:

create table tblPeople (
    ID autoincrement primary key 
, FirstName varchar(100) 
, LastName varchar(100) 
, Notes memo 
) 

現在,讓我們有一個表,用於存放客戶信息,但執行的事實,客戶還必須以人:

create table tblCustomers (
    ID long primary key 
    constraint Customers_ID 
    references tblPeople (ID) 
, EmergencyContactID long 
    constraint Customers_EmergencyContactID 
    references tblPeople (ID) 
) 

這稱爲一對一關係,用於實現專業化 - 就像面向對象編程中的繼承。

您在這裏有一個選擇。你想讓每個人擁有任意數量的任意類型的電話號碼嗎?這顯然更普遍,更強大。但也比較複雜。還是你想回去爲每個人儲存固定數量的電話號碼?

比方說,你想要做前者只是爲了一路走來。在這種情況下,你需要一個表來保存電話號碼:

create table tblPhoneNumbers (
    ID autoincrement primary key 
, PhoneNumber varchar(15) 
) 

注意如何在這裏我們不指定它是什麼類型的電話號碼什麼。這部分是下一:

create table tblPhoneNumberTypes (
    ID autoincrement primary key 
, PhoneNumberType varchar(20) not null 
) 

現在我們每個人提供一個電話號碼和類型相關聯:

create table tblPeople_to_PhoneNumberTypes_to_PhoneNumbers (
    PersonID long not null 
    references tblPeople (ID) 
, PhoneNumberTypeID long not null 
    references tblPhoneNumberTypes (ID) 
, PhoneNumberID long not null 
    references tblPhoneNumbers (ID) 
, constraint People_to_PhoneNumberTypes_to_PhoneNumbers_PK 
    primary key (
    PersonID 
    , PhoneNumberTypeID 
    , PhoneNumberID 
) 
) 

這裏的每個人(因此每個客戶和每個緊急聯繫人)可以有任意數量的任意類型的電話號碼。因此,這實際上是一個多對多到多個鏈接表。我相信這是你的聯繫電話型電話號碼模式的關鍵(或者讓我們說'祕密')。

在像上面這樣的鏈接表中,我更喜歡使用多列主鍵,因爲我覺得整數主鍵列沒有用處。在這裏,主鍵強制實施這樣的事實:每個人員和電話號碼組合應該僅列出一次,並且具有一個電話號碼類型。

請注意,以上都是有效的Access ANSI-92 SQL。

+0

非常感謝Yawar。在發佈時,我不太明白你在說什麼,但現在重新閱讀,我明白了。回覆較晚,抱歉! – intruesiive

+0

@intruesiive無後顧之憂,樂於助人。如果有什麼不清楚的,請告訴我。 – Yawar