我什么时候应该给SQL表自己的数字主键?

时间:2011-01-12 10:07:03

标签: sql mysql

假设我有一个通用的内容管理系统,我保存一个节点表(具有相关权限的导航点),以及每种节点的表(博客文章,评论,附件等)。

我的节点表(在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关系的表分配主键”的业务不一致。

3 个答案:

答案 0 :(得分:0)

如果您有子表(即具有指向表的外键的表),您很可能希望在父表上创建主键。

如果您有“叶桌”,那就不是必需的了。但是,仍然有一个好习惯。如果您仍然希望访问它,因为网站和用户创建的书签包含指向叶表中记录的链接,那么您很可能也想在此处添加主键。

换句话说,它确实取决于。

答案 1 :(得分:0)

如果这种情况始终是1:1关系,那么你的方式应该有效。

对于附件使用不同的uniqe id应该没有任何困难的理由。

答案 2 :(得分:0)

我现在已经离开了。引入一个额外的数字ID似乎是混淆的一个秘诀 - 如果你正在寻找附件11375,那是它的attachment_id还是它的node_id?

作为一般建议,我建议你在任何一张桌子上最多声明一个代理键,以及实际存在的真实密钥。代理键是一个数字键(例如int),当没有任何实际键适合包含在索引,FK引用等中时使用,例如varchar列或(取决于具体情况) )跨越多列的键。