2014-01-06 69 views
3

我有一個問題,如何更改數據庫的模式:數據庫體系結構多到多到很多

現在我們已經預定義的表格Categories 和假設表PlacesPeople可分配以類別,所以它看起來是這樣的:

People <=> PeopleCategories <=> Categories <=> PlaceCategories <=> Places 

(人們可以有很多種類,類別可以有很多的人,地方可以有很多種類,類別可以有很多地方)

但現在有一個新的要求:

在個人資料顯示基於類別(迄今沒有問題)的所有相應的地方,並添加一個建模某些屬性(例如在前端顯示爲最喜歡的地方)的勾選框。另一方面,Place profile個人用同一個勾號框標記至少一個同一類別的人。

我不知道是否有一些不錯的方式來模擬這個 - 我唯一想到的是添加一個新的PeoplePlaces表,但是我必須手動控制人或地點是否沒有改變他們的類別,他們是仍然分配等等 - 我將不得不在應用程序層上管理數據的一致性,這會帶來相當大的問題。

我可能做的第二件事就是完全刪除類別並僅在PeoplePlaces級別上使用,但我將失去用戶的一些簡單性:有10個預定義的類別供用戶選擇,以便People和Places之間的鏈接是相當自動的前端,只有管理員應該看到哪些地方分配給哪些人,並管理我正在談論的那個複選框

你對這個架構有何建議?提前致謝! (這是一個MySQL數據庫,如果它對某種解決方案很重要,但這是更通用的架構的東西)

+1

這與DBA.SE上的這個問題類似:[是否有DBMS允許引用視圖的外鍵(而不僅僅是基表)?](http://dba.stackexchange.com/questions/17853/are-there-dbms-that-allow-a-foreign-key-that-references-a-view-and-not-only-bas)請閱讀所有答案和評論中的討論,這不是微不足道的實現。 –

+0

@ypercube:是的,正是我所面對的,我看到你提出了這個問題。最後你用了什麼?我可能會嘗試約束解決方案,因爲我的表格可能不會經常更改。謝謝你的鏈接! – kuncajs

+0

這對我來說更是一個理論問題,而非實際問題。對於MySQL,我想我會使用約束解決方案(這也將需要'PeopleCategories'和'PlaceCategories'表的DELETE觸發器或其他方式來定製這兩個表上的DELETE操作。) –

回答

2

如果我理解正確你的問題,你需要確保一個人有利於一個地方,與該人自己連接到同一類別?

如果是的話,看看下面的模型:

enter image description here

我們不鏈接直接「端點」,而是「鏈接的鏈接」。這使我們能夠將PERSON_CATEGORY.CATEGORY_ID和PLACE_CATEGORY.CATEGORY_ID遷移到FAVORED_PLACE表中,並將它們「合併」,產生一個FAVORED_PLACE.CATEGORY_ID字段(上圖中的註釋FK1,FK2)。

因此,如果一個人連接到一個地方,必須通過一個共同的類別來完成。此外,因爲CATEGORY_ID在PERSON_CATEGORY的PK之外,所以人和地點的特定組合只能使用一次,即使它們通過多個類別匹配也不例外。實際上,你選擇一個普通類別爲「特殊」。如果某個地點(或人)從特殊類別中刪除,則需要選擇另一個常用類別作爲特殊類別。如果沒有公共類別,FAVORED_PLACE中的相應行將不再存在。

+0

我真的很喜歡這種模式,但據我瞭解,應用程序層還有一些邏輯 - 如果一個人取消了某個類別,我可以填充級聯刪除但不總是,因爲他們可以通過其他類別鏈接 - 這是什麼應用程序必須檢查(或者可能觸發器可以解決這個問題,但我不允許現在使用它們)。我對嗎?感謝您的回答! – kuncajs

+0

它不必位於應用程序層。你可以寫一個DELETE過程(用於'Person_Category'表和另一個表的另一個表)來處理它。然後讓你的應用程序只執行刪除操作來調用這些過程。 –

+0

@kuncajs如果你想移動到不同的「特殊」類別,那麼是的,有一些特殊的邏輯(否則你可以在ON DELETE CASCADE上)。如果由於某種原因,您無法將該邏輯封裝在觸發器中,您仍然可以將其封裝爲使重用變得容易(如ypercube建議)。 –

0

我不認爲刪除類別是一個好主意。

你正在做的是引入一個新的實體 - PersonsFavouritePlaces - 直接關聯人員和地點,而不是通過類別。明智的做法是PersonsFavouritePlace僅限於按類別鏈接的Person和Place,所以它應該引用PeopleCategories和PlaceCategories而不是People和Category表。

表看起來像:

create table PeopleFavourtiePlace 
(
    ID int not null, -- Primary key 
    PeopleCategoriesId int not null, -- FK to PK of PerpleCategories 
    PlaceCategoriesId int not null -- FK to PK of PlaceCategories 
) 

我不知道MySQL的是否支持級聯刪除這樣做,但如果是這樣兩個FK的應該有開啓所以當有人取消選擇一個類別(刪除PeopleCategories行)如果它鏈接到該類別中最喜歡的地方,它也會被刪除。

但是,如果一個人的聯繫通過多個類別,那麼情況就變得複雜的地方....

+0

這太簡單了。它允許在此表中添加行,將Person與沒有加入類別的地方聯繫起來。 –