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

什么时候应该给SQL表指定自己的数字主键?,sql,mysql,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) REFEREN

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

我的节点表(在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');
使用此方法,我可以开发一个适用于节点的通用权限系统,而无需通过引用节点id为我的所有不同节点类型专门化它

在这种情况下,我没有给附件“自己的”数字主键,因为附件是一个与节点具有1:1关系的节点,它的主键基于节点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关系的表分配主键”的业务不一致。

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

如果你有一个“叶表”,它不是真的必要。然而,这可能是一个好的做法,仍然有一个。如果由于网站和用户创建的书签包含指向叶表中记录的链接,您仍然希望访问它,那么您很可能也希望在此处添加主键


换句话说,这要看情况而定。

如果这永远是一种1:1的关系,那么你的方式应该有效


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

我会让它保持目前的状态。引入一个额外的数字ID似乎会引起混淆——如果您正在查找附件11375,那么是它的附件ID还是它的节点ID


作为一般建议,我建议您在任何表上最多声明一个代理键,并且实际存在的实键数量应尽可能多。代理键是一个数字键(例如int),当没有一个真正的键适合包含在索引、FK引用等中时使用,例如作为
varchar
列或(取决于具体情况)跨多列的键。

顺便说一句,为什么这是一个好的做法?如果我在附件上创建主键有什么好处吗?@user572491:这就是为什么我说“这可能是一个很好的做法”。这取决于你和谁说话以及你喜欢什么关于优势:如果您在任何逻辑中都不需要该列,则没有优势,实际上它会占用更多的空间。但是,如果在某一点上您必须添加需要这样一个id的附加逻辑,那么您要么已经有了它,要么需要相应地更新表结构,这可能会产生副作用。-正如我所说,这真的取决于。附件上的node_id是否算作代理项键?@user572491-我会说是-它是代理项(因为它实际上与现实世界无关),它是一个键(因为它可以用来唯一地标识表中的特定行)