2017-08-04 58 views
1

對於一個學校學科,我必須製作一個具有不同類型關係的小應用程序:一對一,一對多,多對多。數據庫設計:從單個表格到一對一的關係?

如果例如來自同一個表'用戶'的2個用戶ID之間的關係狀態(與/關係結婚)仍然是一對一關係?

例如:

表1: '用戶'

USER_ID(PK)|用戶名|密碼| date_registered

表2: '關係'

user_one_id(FK)| user_two_id(FK)|狀態

這是一對一數據庫的正確示例,還是它本身必須是連接2個表與外部表之間的連接?

+0

盡你所能。我一直在這樣做,我從來沒有見過一對一的關係是合適的情況。然而,你的情況似乎是學術的,這意味着它不一定代表現實生活。對於你的問題中的例子,問問你自己,你的數據模型是如何處理關係結束的。 –

回答

2

簡短的回答並不是真的。

一對一關係是您在建立兩個表的主鍵之間的關係時得到的。

以你的想法:說我們有一堆的用戶,但我們在這樣一個表來跟蹤他們的登錄信息:

CREATE TABLE users (
    user_id int NOT NULL PRIMARY KEY, 
    username varchar, 
    password varchar); 

而另一個表是這樣的:

CREATE TABLE user_personal(
    user_id int NOT NULL PRIMARY KEY, 
    age int, 
    firstname varchar, 
    lastname varchar) 

一旦創建了這兩個表格,很容易看到每個表格中都有一列具有相同數據類型(user_id)的列,該列用作該表的主鍵。

如果您使用user_id作爲鍵在兩個表之間建立關係,則您建立了一對一關係,因爲user_id只能在任一表中出現一次。

這看起來有點不可思議,因爲您可能會問爲什麼要將數據分離出來。爲什麼要在一個表中包含哪些數據字段而不是另一個表中區分?一個簡單的解決方案是數據隔離。說我們修改第二個表顯示此:

CREATE TABLE user_personal(
    user_id int NOT NULL PRIMARY KEY, 
    age int, 
    firstname varchar(255), 
    lastname varchar(255), 
    home_address varchar(255), 
    social_security_number int) 

我們可能想給訪問一些數據的一些人,而不是其他人。如果你有你的用戶關係表,可能很好地向一些人展示人與人之間的家庭/友誼關係,但你不想放棄他們的社會安全號碼和家庭住址。您可能會將數據分離出來的另一個重要原因是,如果您的表格中包含大量數據(請參閱數百列),並且只有某些數據會在特定時間更新。如果您有數百萬條記錄得到更新,但只有某些列一起更新,而其他列保持相當靜態,則可以將該表分成兩個具有一對一關係的表,以防止數據庫性能在整個過程中停滯不前更新過程。

+0

謝謝!這是非常有用的信息。我會在明天進一步研究它,並將在我的應用程序中實施它。 – user1992

1

如果通過「連接它們的外部表格」表示第三個表格,則表示不需要。

雖然您的關係表可以使用一些工作。你不希望有兩個字段與用戶ID。那會讓你後來頭疼。我建議設置這些表像這樣:

USER 

user_id (pk) 
username 
password  --Potential security problems, but for academic purposes, sure. 
date_registered 
family_unit_id 


RELATIONSHIP 

family_unit_id (fk) 
user_id (fk) 
spouse_type --(e.g. husband, wife, etc.) 

現在你可以讓你的多對多的關係做這個:

SELECT r.family_unit_id, r.user_id, u.username 
FROM RELATION r LEFT JOIN USER u ON r.user_id = u.user_id 

你一對一的關係將是東西是獨一無二的到表格之間的相同記錄。在你描述的情況下,與user_id(妻子)相關的user_id(丈夫)不是一對一的關係。通過您提供的內容,您可以通過連接數據的子集來建立一對一的關係,例如本例。

SELECT r1.family_unit_id, r1.username as HusbandName, r2.username as WifeName 
FROM (SELECT * FROM RELATION WHERE spouse_type = 'Husband') r1 
LEFT JOIN (SELECT * FROM RELATION WHERE spouse_type = 'Wife') r2 
    ON r2.family_unit_id = r1.family_unit_id 

上面的查詢基本上得到兩個表family_unit_ids獨特的主鍵,並用丈夫或妻子相關聯的用戶ID。然後,你們一起加入他們。因爲我們假設在這個例子中,在已婚家庭單位中永遠不會有兩個以上的配偶,這將是一對一的關係。

如果你想獲得一個一對多的關係,您可以選擇一切從用戶表,然後在關係表連接,以顯示誰是合作伙伴的關係:

SELECT u.username, r.user_id 
FROM USER u LEFT JOIN RELATIONSHIP r ON r.family_unit_id = u.family_unit_id 

當然,這會是一個微不足道的結果,因爲你會有記錄說約翰與約翰和瑪麗有關係。但它說明了這一點。通常情況下,通過在此混合中添加更多表格,您將獲得更多有用的一對多關係結果。

+0

感謝您的評論。我有點困惑。我想知道除了列的命名(user_one_id,user_two_id和user_id,family_unit_id)之外,我的表(關係)和你的區別是什麼。 – user1992

+0

將user_one_id和user_two_id合併到一個字段中:user_id。或者,您可以指定家庭位置:husband_user_id,wife_user_id。指定一個/兩個的問題是,任何一個人都可以符合標準,所以稍後搜索和加入會更困難。 – SandPiper

+0

當你遇到非傳統家庭時,丈夫/妻子領域硬編碼的缺點是。丈夫/丈夫,妻子/妻子等等。所以,這取決於你的數據庫目標是什麼以及你想接受什麼樣的數據。 – SandPiper