假设我有一个通用的内容管理系统,我保存一个节点表(具有相关权限的导航点),以及每种节点的表(博客文章,评论,附件等)。
我的节点表(在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)
如果您有子表(即具有指向表的外键的表),您很可能希望在父表上创建主键。
如果您有“叶桌”,那就不是必需的了。但是,仍然有一个好习惯。如果您仍然希望访问它,因为网站和用户创建的书签包含指向叶表中记录的链接,那么您很可能也想在此处添加主键。
换句话说,它确实取决于。
答案 1 :(得分:0)
如果这种情况始终是1:1关系,那么你的方式应该有效。
对于附件使用不同的uniqe id应该没有任何困难的理由。
答案 2 :(得分:0)
我现在已经离开了。引入一个额外的数字ID似乎是混淆的一个秘诀 - 如果你正在寻找附件11375,那是它的attachment_id还是它的node_id?
作为一般建议,我建议你在任何一张桌子上最多声明一个代理键,以及实际存在的真实密钥。代理键是一个数字键(例如int),当没有任何实际键适合包含在索引,FK引用等中时使用,例如varchar
列或(取决于具体情况) )跨越多列的键。