Dyl*_*lan 3 mysql performance foreign-key database-design primary-key
我有一个数据库:
DROP TABLE IF EXISTS `books`;
CREATE TABLE `books` (
`isbn` VARCHAR(255) NOT NULL,
`title` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`isbn`)
) COMMENT 'Books used at this school';
DROP TABLE IF EXISTS `classes`;
CREATE TABLE `classes` (
`class_id` INT(10) NOT NULL AUTO_INCREMENT,
`teacher_id` SMALLINT(5) NULL DEFAULT NULL,
PRIMARY KEY (`class_id`)
) COMMENT 'Classes at the school';
DROP TABLE IF EXISTS `b_c`;
CREATE TABLE `b_c` (
`isbn` VARCHAR(255) NOT NULL,
`class_id` INT(10) NOT NULL,
PRIMARY KEY (`isbn`)
) COMMENT 'Books to classes';
ALTER TABLE `b_c` ADD FOREIGN KEY (isbn) REFERENCES `books` (`isbn`)
ON UPDATE CASCADE;
ALTER TABLE `b_c` ADD FOREIGN KEY (class_id) REFERENCES `classes` (`class_id`)
ON UPDATE CASCADE;
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我想尽可能地规范化数据(我不希望将同一关系的多个条目输入到表中b_c
),但我只想存储绝对相关的数据.
我处理这个问题的第一个想法是只b_c
为由字段组成的表创建一个复合主键isbn
,class_id
这将解决表中存在重复关系的问题,但是,我听到强烈的意见,认为每个字段都有一个唯一标识符在这样的表中行。为每一行拥有唯一标识符的理由似乎是能够指定特定行很有用,尽管我没有看到这会变得有用的情况。有人可以提供一个例子吗?
我听到的另一个批评是,以这种方式使用复合 PK 会使JOIN
s 变得非常繁重。有人可以评论这两种不同方法的性能吗?
问题归结为“id
向b_c
表中添加字段是否值得,或者使用复合 PK 是否足以正确表示books
和classes
表之间的关系?
如果您对设计有任何其他与问题不直接相关的评论,我很想听听他们的意见,并提前感谢您的帮助。
FWIW ISBN 作为主键很糟糕。首先,如果您收到一本书想要预订,但 ISBN 尚未分配,会发生什么情况?当 ISBN 更改时会发生什么(是的,这会发生!)?当他们再次更改 ISBN 格式时会发生什么?我会说将其设为候选键,但对 PK 使用代理。
加上使用字符串作为键的其他问题,然后在您需要的复合键之上,我只是不明白为什么当您从这么多角度获得建议时要与代理作斗争。你知道很多推动你那样做的人都有很多经验,对吧?