2012-09-01 103 views
2

在我的數據庫中,我有一個有關它們的信息的用戶列表,而且我還有一個功能,允許用戶將其他用戶添加到候選列表中。我的用戶信息存儲在一個帶有用戶標識的主鍵的表中,並且我有另一個表作爲候選列表。候選名單表的設計使其具有兩列,基本上只是一對名稱列表。因此,要找到特定用戶的候選名單,可以從第二列中檢索所有名稱,其中第一列中的id是特定值。爲什麼我的數據庫表需要一個主鍵?

問題是,根據許多來源,如這個Should each and every table have a primary key?你應該在數據庫的每個表中有一個主鍵。

根據此來源http://www.w3schools.com/sql/sql_primarykey.asp - 一個唯一標識數據庫中的條目的主鍵。所以我的問題是:

  1. 我的數據庫中的表有什麼問題?爲什麼它需要一個主鍵?

  2. 我該如何給它一個主鍵?只需創建一個新的自動遞增列,以便每個條目都有一個唯一的ID?這似乎沒有多少意義。或者,我會以某種方式將表示候選名單的多個條目封裝到另一個表中的另一個實體中,並將​​其鏈接到?我很困惑。

+0

只用一個索引來嘗試它,您不需要主鍵。獲取性能沒有的數字,看看它是否足夠快。 –

+0

謝謝,我會嘗試。然而,從適當的關係角度來看,你會如何去做這樣的事情?這不像是你可以創建另一個表格來表示一個人的候選名單,因爲這還需要適應這樣一個事實,即我們不知道這個人會添加多少人。所以你不能爲每一個單獨列 - 你需要一個新的行 - 回到相同的情況哈哈! – user1058210

+0

您創建了一個具有兩個用戶標識作爲列的表,因此您可以將某個人與其他人關聯起來,並且如果要強制執行唯一性,請創建一個由兩列組成的主鍵。 –

回答

2

如果這些行是唯一的,那麼您可以擁有一個兩列主鍵,儘管這可能與數據庫有關。這裏有一個例子:

CREATE TABLE my_table 
(
col_1 int NOT NULL, 
col_2 varchar(255) NOT NULL, 
CONSTRAINT pk_cols12 PRIMARY KEY (col_1,col_2) 
) 

如果你已經有了表,該例子是:

ALTER TABLE my_table 
ADD CONSTRAINT pk_cols12 PRIMARY KEY (col_1,col_2) 
+0

是的,我想每一行都是唯一的。你會這樣做的方式是什麼?我唯一能想到的另一種方式就是用我的用戶信息表擴展入選的CSV值 - 雖然我不想這樣做,因爲搜索會很糟糕! – user1058210

+0

我添加了一個例子。我不確定這對於不同的數據庫是多麼便攜。 – David

2

主鍵唯一地標識每個記錄,因爲它是前面提到的,主鍵可以由多個的屬性(1列或更多列)。首先,我建議確保每個記錄在您的表格中都是獨一無二的。其次,據我所知,你離開表沒有主鍵,這是不允許的,所以是的,你需要爲它設置密鑰。

2

在這種特殊情況下,在shortlist表中存儲的同一對用戶ID中不會有多次存儲目的。畢竟,該表模擬一個集合,並且元素在集合中或者不在集合中。在集合中有一個「兩倍」的元素沒有意義。爲了防止這種情況,請創建一個組合鍵,由這兩個用戶ID字段組成。

無論該組合鍵也將是主要的,或者你有另一個鍵(這將作爲代理主鍵)是another matter,但無論哪種方式,你需要該組合鍵。

請注意,根據支持clustering (aka. index-organized tables)數據庫,PK往往也是聚集鍵,這可能對性能顯著反響。


不同於mutiset。

2

具有重複行的表不是關係的適當表示。這是一包行,而不是一組行。如果你讓這種情況發生,你最終會發現你的計數將會被關閉,你的資金將會關閉,你的平均數將會被關閉。簡而言之,當您使用它時,您會在數據中混淆錯誤。

聲明主鍵是防止重複行進入數據庫的一種便捷方式,即使其中一個應用程序出錯。您獲得的索引是一個副作用。

通過引用任何候選鍵可以創建對錶中單個行的外鍵引用。但是,如果將這些候選鍵中的一個聲明爲主鍵,然後使所有外鍵引用都引用主鍵,則會更加方便。這只是謹慎的數據管理。

現實世界中的實體與表中該實體的對應行之間的一一對應關係超出了DBMS領域。這取決於您的應用程序,甚至是您的數據提供者通過不爲現有實體創造新行並且不讓某些新實體滑過這些裂縫來維護該對應關係。

1

既然你問了,這是好的做法,但在少數情況下(數據不需要連接),它可能不是絕對必需的。但最大的問題是,你永遠不知道需求是否會改變,所以你現在真的想要一個,所以你沒有在事實後添加一個到10米記錄表.....

除了主鍵(它可以跨越多列順便說一句)我認爲這是一個很好的做法,有一個第二候選人的關鍵是一個單一的領域。這使聯接更容易。

首先是一些理論。你可能還記得HS或者大學代數中函數的定義是:y = f(x)其中f是一個函數,當且僅當每個x有一個y。在這種情況下,在關係數學中,我們會說在這種情況下y是functionally dependent

您的數據也是如此。假設我們正在存儲支票號碼,檢查賬戶號碼和金額。假設我們可能有多個支票賬戶,並且對於每個支票賬戶不允許有重複支票號碼,那麼金額在功能上取決於(賬戶,支票號碼)。一般而言,您希望將數據存儲在一起,這些數據在功能上依賴於同一事物,而無需傳遞依賴關係。主鍵通常是您指定爲主鍵的功能依賴關係。這然後識別行中的其餘數據(因爲它與該標識符相關聯)。把它看作是natural primary key.儘可能(即不使用MySQL)我喜歡將主鍵聲明爲自然鍵,即使它橫跨列。有時你可能有多個可互換的候選鍵,這會變得複雜。例如,考慮:

CREATE TABLE country (
    id serial not null unique, 
    name text primary key, 
    short_name text not null unique 
); 

此表真的可以有任何列作爲主鍵。這三個都是完全可以接受的候選鍵。假設我們有一個國家記錄(232,'美國','美國')。這些字段中的每一個都唯一標識記錄,因此如果我們知道其中一個我們可以知道其他字段。每一個都可以被定義爲主鍵。

我還建議擁有第二個人造候選鍵,它只是用於連接鏈接的機器標識符。在上面的例子中,country.id是這樣做的。這對於將其他記錄鏈接到國家/地區表格很有用。

需要候選關鍵字的例外情況可能是重複記錄真的可能存在的地方。例如,假設我們正在跟蹤發票。我們可能會有兩個項目獨立開具發票的情況,兩個項目中的每一個都會顯示一個項目。這些可能是相同的。在這種情況下,您可能希望添加一個人造主鍵,因爲它允許您稍後將事物連接到該記錄。你現在可能沒有必要這樣做,但你可能在將來!

相關問題