比方说,我有一个通用的内容管理系统,其中保存了一个节点表(具有关联权限的导航点)以及每种节点(博客文章,评论,附件等)的表格。什么时候应该给一个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关系的表分配主键”的业务不一致。
为什么它会是一个好习惯,顺便说一句?如果我在附件上创建主键,是否有任何优势? – user572491 2011-01-12 10:35:09
@ user572491:这就是为什么我说“它*可能是一个很好的做法”。这取决于你和谁交谈以及你喜欢什么。 - 关于优点:如果您不需要任何逻辑中的该列,则没有优势,实际上它会消耗更多空间。但是,如果在某个时候需要添加额外的逻辑需要这样一个ID,那么您要么已经拥有了它,要么需要相应地更新您的表结构,这可能会导致副作用。 - 正如我所说,这真的取决于。 – sjngm 2011-01-12 10:56:09