2011-01-12 16 views
1

比方說,我有一個通用的內容管理系統,其中保存了一個節點表(具有關聯權限的導航點)以及每種節點(博客文章,評論,附件等)的表格。什麼時候應該給一個SQL表格自己的數字主鍵?

我的節點表(在MySQL)看起來像這樣:

CREATE TABLE node_types (
    type_id INT PRIMARY KEY AUTO_INCREMENT, 
    type_parent INT, 
    type_name VARCHAR(31) UNIQUE KEY, 

    FOREIGN KEY (type_parent) REFERENCES node_types(type_id) 
) ENGINE = InnoDB; 

CREATE TABLE nodes (
    node_id INT PRIMARY KEY AUTO_INCREMENT, 
    type_id INT, 
    parent_id INT, 

    FOREIGN KEY (type_id) REFERENCES node_types (type_id), 
    FOREIGN KEY (parent_id) REFERENCES nodes (node_id) 
) ENGINE = InnoDB; 

然後創建不同類型的節點,我做這樣的事情:

CREATE TABLE attachments (
    node_id INT PRIMARY KEY, 
    attachment_filename VARCHAR(255), 
    attachment_title VARCHAR(255), 

    FOREIGN KEY (node_id) REFERENCES nodes (node_id) 
) ENGINE = InnoDB; 
INSERT INTO node_types (type_name) VALUES ('attachment'); 

使用這種方法,我可以開發一種普通權限系統適用於節點,而無需通過引用node_id將其專用於所有不同的節點類型。

在這種情況下,我沒有爲附件提供「自己的」數字主鍵,因爲附件是與節點1:1關係的節點 - 其主鍵基於node_id。但有些人會/做。附件表可以很容易地改寫爲:

CREATE TABLE attachments (
    attachment_id INT PRIMARY KEY, 
    node_id INT UNIQUE NOT NULL, -- a node is-a attachment. 
    attachment_filename VARCHAR(255), 
    attachment_title VARCHAR(255) 

    FOREIGN KEY (node_id) REFERENCES nodes (node_id) 
) ENGINE = InnoDB; 
INSERT INTO node_types (type_name) VALUES ('attachment'); 

你認爲什麼是重要的原因,爲什麼不能一會放給一個數字唯一的主鍵ID到表?特別是,我覺得我有時與「沒有爲具有1:!is-a關係的表分配主鍵」的業務不一致。

回答

0

如果您有一個子表(即具有指向該表的外鍵的表),則最有可能要在父表上創建一個主鍵。

如果你有一個「葉桌」,它並不是真的有必要。但是,仍然有一個很好的做法。如果由於網站和用戶創建包含葉表中記錄鏈接的書籤而仍然希望訪問它,那麼您最有可能還想在此處添加主鍵。

換句話說,它確實取決於。

+0

爲什麼它會是一個好習慣,順便說一句?如果我在附件上創建主鍵,是否有任何優勢? – user572491 2011-01-12 10:35:09

+0

@ user572491:這就是爲什麼我說「它*可能是一個很好的做法」。這取決於你和誰交談以及你喜歡什麼。 - 關於優點:如果您不需要任何邏輯中的該列,則沒有優勢,實際上它會消耗更多空間。但是,如果在某個時候需要添加額外的邏輯需要這樣一個ID,那麼您要麼已經擁有了它,要麼需要相應地更新您的表結構,這可能會導致副作用。 - 正如我所說,這真的取決於。 – sjngm 2011-01-12 10:56:09

0

那麼,如果這將永遠是1:1的關係,你的方式應該工作。

不應該有任何困難的理由使用不同的uniqe編號的附件。

0

我會離開它,因爲你目前擁有它。引入額外的數字ID似乎是混淆的祕訣 - 如果您正在尋找附件11375,那麼它的attachment_id或其node_id?

作爲一般性建議,我建議您最多隻有一個在任何表上聲明的代理鍵,以及實際存在的許多實際鍵。代理鍵是一個數字鍵(例如int),當沒有真正的鍵適合包含在索引,FK引用等中時,使用該鍵,例如是varchar列或(取決於具體情況)跨度多列。

相關問題