我应该在多对多表中使用复合 PK 还是替代 PK?

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为由字段组成的表创建一个复合主键isbnclass_id这将解决表中存在重复关系的问题,但是,我听到强烈的意见,认为每个字段都有一个唯一标识符在这样的表中行。为每一行拥有唯一标识符的理由似乎是能够指定特定行很有用,尽管我没有看到这会变得有用的情况。有人可以提供一个例子吗?

我听到的另一个批评是,以这种方式使用复合 PK 会使JOINs 变得非常繁重。有人可以评论这两种不同方法的性能吗?

问题归结为“idb_c表中添加字段是否值得,或者使用复合 PK 是否足以正确表示booksclasses表之间的关系?

如果您对设计有任何其他与问题不直接相关的评论,我很想听听他们的意见,并提前感谢您的帮助。

Aar*_*and 6

FWIW ISBN 作为主键很糟糕。首先,如果您收到一本书想要预订,但 ISBN 尚未分配,会发生什么情况?当 ISBN 更改时会发生什么(是的,这会发生!)?当他们再次更改 ISBN 格式时会发生什么?我会说将其设为候选键,但对 PK 使用代理。

加上使用字符串作为键的其他问题,然后在您需要的复合键之上,我只是不明白为什么当您从这么多角度获得建议时要与代理作斗争。你知道很多推动你那样做的人都有很多经验,对吧?