我试图增加我的 MySQL 数据库架构的约束,为每个表添加外键约束 .
表1: USERS
+---------+----------+-------------
| id | username | Other fields
+---------+----------+-------------
| 1 | John |
| 2 | Mark |
+---------+----------+-------------
id INT(11)UNSIGNED NOT NULL AUTO_INCREMENT username`VARCHAR(50)NOT NULL PRIMARY KEY(id)
表2: DISKS (与 USERS 的关系为 one to many )
+---------+----------+-----------+-------------
| id | id_user | disk_name | Other fields
+---------+----------+-----------+-------------
| 1 | 1 | disk A |
| 2 | 2 | disk B |
+---------+----------+-----------+-------------
id INT(11)UNSIGNED NOT NULL AUTO_INCREMENT id_user INT(11)NOT NULL,PRIMARY KEY(id,id_user)INDEX fk_disks_idx(id ASC)CONSTRAINT fk_disks FOREIGN KEY(id)REFERENCES database.USERS(id)ON DELETE NO ACTION ON更新无动作)
表3: FILES (与 DISKS 的关系为 one to many )
+---------+----------+----------+-----------+-------------
| id | id_disk | id_user | file_name | Other fields
+---------+----------+----------+-----------+-------------
| 1 | 1 | 1 | |
| 2 | 2 | 2 | |
+---------+----------+----------+-----------+-------------
id INT(11)UNSIGNED NOT NULL AUTO_INCREMENT id_user INT(11)NOT NULL id_disk INT(11)NOT NULL PRIMARY KEY(id,id_disk,id_user)INDEX fk_files_idx(id ASC,id_user ASC)CONSTRAINT fk_files FOREIGN KEY(id_disk,id_user ,id_user)REFERENCES database.DISKS(id)ON DELETE NO ACTION ON UPDATE NO ACTION)
表2: FILES_ON_NAS (与 FILES 的关系为 one to one )
+-------+----------+----------+----------+-----------+-------------
| id | id_files | id_user | id_disk | file_name | Other fields
+-------+----------+----------+----------+-----------+-------------
| 1 | 1 | 1 | 1 | |
| 2 | 1 | 2 | 2 | |
+-------+----------+----------+----------+-----------+-------------
id INT(11)UNSIGNED NOT NULL AUTO_INCREMENT id_files INT(11)NOT NULL,id_user INT(11)NOT NULL,id_disk INT(11)NOT NULL,PRIMARY KEY(id,id_files,id_user,id_disk)INDEX fk_files_on_nas_idx(id ASC )CONSTRAINT fk_files_on_nas FOREIGN KEY(id_files,id_user,id_disk)REFERENCES database.FILES(id,id_user,id_disk)ON DELETE NO ACTION ON UPDATE NO ACTION)
问题:
正如您所看到的那样,级联中的I引用表越多,我获得的主键就越多 . 如何设计数据库以避免复制主键,从而避免数据重复?我应该删除每个表的自动递增键吗?这是一个好习惯吗?
谢谢
3 回答
磁盘的ID足以唯一标识磁盘 . 因此没有理由将用户的ID包含在磁盘的主键中 . 这甚至是一个非常糟糕的主意,因为这意味着如果磁盘的用户发生变化,则需要修改主键 .
对于文件也是如此 . 文件ID唯一标识文件 . 因此没有理由将磁盘ID添加到文件的主键中 .
我强烈建议不要删除自动增加的键 .
但是,您不需要每次都创建一个新的主键:
如果您希望多个用户共享一个磁盘,只需将
id_disk
的外键放在 USERS 中如果您希望一个用户可以拥有多个磁盘,则将
id_user
的外键改为 DISKS .当您面对多对多关系时,只使用这样的主键 . 在这种情况下,您需要创建一个新表来连接两个表;将两个表的主键作为外键,与您一样制作耦合主键 .
您可能想要阅读一些关于Database Normalization的内容 . 在您的情况下,我会使surrogate key
id
成为表中唯一的主键 . 就像是:对于
files
,您将不得不回答以下问题:文件所有权是直接依赖于文件,还是传递给磁盘所有权,还是所有权独立? John拥有的一个由Jack拥有的磁盘上的文件?对我来说似乎没问题,但您的域名可能有不同的规则 . 在这种情况下,从文件表中删除user_id(否则您的数据库将不在Third normal form中) .