2012-08-26 71 views
0

此表包含用戶的照片(縮略圖和完整)。
大部分查詢都會有一個「WHERE user_id =?」條件。兩列作爲主鍵或一列作爲PK +索引?

CREATE TABLE photos (
    "photo_id" serial, -- serial is postgres' autoincrement 
    "user_id" integer not null, -- foreign key to users table 
    "filename_thumbnail_50" varchar not null, 
    "filename_thumbnail_75" varchar not null, -- 75px x 75px thumbnail 
    "filename_full" varchar not null, 
    PRIMARY KEY ("photo_id", "user_id") 
); 

什麼是最好的設計和/或性能設計這個用例:
- 像上面例子中的兩列主鍵?
- 一個主鍵(photo_id)和user_id上的索引?

+2

你擁有的兩列主鍵並沒有什麼意義,恕我直言。不應該是'(photo_id)'或'(user_id,文件名)'? –

+0

對不起,我已更新我的示例,因此它有點複雜 – younes0

+1

對於表中的每一行,每個列值都應該依賴於「密鑰,整個密鑰,除了密鑰外」。 「依賴於」表示「正確的值由......標識」。將「user_id」添加到串行列將打破第二部分;你的牌桌不會處於第二常態,並且會受到相關異常的影響。查看關於關係數據庫規範化的任何書籍或文章。 – kgrittn

回答

4

主鍵應該遵循您的業務規則,沒有別的。由於照片本身沒有「真實」(即自然)主鍵,因此使用序列作爲PK絕對有意義。

將主鍵擴展爲user_id沒有任何意義,也沒有任何用途(因爲無論如何photo_id都是唯一的,只會增加索引維護的開銷)。而隨着user_id是在索引的第二列這是不太可能會被用於上user_id(不是不可能,但可能性不大)

所以我會去堅持使用PK上photo_id和添加索引限制查詢在user_id(無論如何索引外鍵列總是一個好主意)。

+0

感謝您的解釋,我應該瞭解更多關於索引。 – younes0

+1

@ younes0:我可以強烈推薦這個網站:http://use-the-index-luke.com它非常適合解釋索引的工作原理。 –

+0

會做!謝謝 – younes0

2

由於user_id是密鑰中的第二列,因此寫入的主鍵不可用於通過user_id進行搜索。

您的第二個選擇是最好的 - 僅在photo_id上使用主鍵,因爲這是記錄的唯一標識符,並在user_id上爲您的查詢添加單獨的索引。

0

如果你有一個沒有增加的ID,我不認爲你需要user_id作爲主鍵。你爲什麼不使用user_id的密鑰到你的用戶表(我想你有)?

0

如果您有專門用於識別目的的列(在本例中爲photo_id),則不需要有第二個關鍵列。

如果您的情況可能有多個記錄具有相同的photo_id和不同的user_ids,那麼我認爲最好有一箇中間表來創建多對多關係並保留單個主鍵。例如:

CREATE TABLE photos (
    "photo_id" serial, 
    -- other columns 
    PRIMARY KEY ("photo_id") 
); 

CREATE TABLE users (
    "user_id" serial, 
    -- other columns 
    PRIMARY KEY ("user_id") 
); 

CREATE TABLE photos_users (
    "photo_user_id" serial, 
    "photo_id" integer, -- not sure if this datatype is correct for postgres 
    "user_id" integer, -- not sure if this datatype is correct for postgres 
    PRIMARY KEY ("photo_user_id") 
); 

據我所知 - 需要一個第二個鍵列那裏是有問題的表中沒有特定ID列,如果只有1鍵用於可能有重複。這樣的一個例子是下面:

CREATE TABLE Person (
    "FirstName" varchar NOT NULL, 
    "LastName" varchar NOT NULL, 
    "PostalCode" varchar NOT NULL, 
    PRIMARY KEY ("FirstName", "LastName", "PostalCode") 
); 

在上述情況下FirstName將不足以唯一具有作爲主鍵,也不會FirstNameLastName,所以在這種情況下,至少3列將被使用。當然最好有一個IDPersonID列並將其用作主鍵。

就性能而言,主鍵不會產生太大的影響。擔心索引。確保將在WHERE子句或JOINAGGREGATE中使用的任何列都有索引。

+0

謝謝,會上課 – younes0