使用生成的主键引用表

时间:2015-04-29 16:36:17

标签: mysql hibernate

我正在尝试增加 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 一对多关系

    +---------+----------+-----------+-------------
    | 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(idid_user)   INDEX fk_disks_idxid ASC)

     

约束fk_disks

     

FOREIGN KEY(id

     

参考databaseUSERSid

     

开启删除操作

     

ON UPDATE NO ACTION)

表3: FILES (与 DISKS 一对多关系

    +---------+----------+----------+-----------+-------------
    | 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(idid_diskid_user)   INDEX fk_files_idxid ASC,id_user ASC)

     

约束fk_files

     

外键(id_diskid_userid_user

     

参考databaseDISKSid

     

开启删除操作

     

ON UPDATE NO ACTION)

表2: FILES_ON_NAS (与 FILES 一对一关系)

    +-------+----------+----------+----------+-----------+-------------
    | 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(idid_filesid_userid_disk)   INDEX fk_files_on_nas_idxid ASC)

     

约束fk_files_on_nas

     

外键(id_filesid_userid_disk

     

参考databaseFILESidid_userid_disk

     

开启删除操作

     

ON UPDATE NO ACTION)


问题:

正如您所看到的那样,级联中的I引用表越多,我获得的主键就越多。如何设计数据库以避免复制主键,从而避免数据重复?我应该删除每个表的自动递增键吗?这是一个好习惯吗?

由于

2 个答案:

答案 0 :(得分:3)

磁盘的ID足以唯一标识磁盘。因此没有理由将用户的ID包含在磁盘的主键中。这甚至是一个非常糟糕的主意,因为这意味着如果磁盘的用户发生变化,则需要修改主键。

同样的文件。文件ID唯一标识文件。因此没有理由将磁盘ID添加到文件的主键中。

答案 1 :(得分:1)

您可能希望阅读一些关于Database Normalization的内容。在您的情况下,我会使surrogate key id成为表中唯一的主键。类似的东西:

create table users (
    id integer not null auto_increment,
    username varchar(50),
    ...,
    primary key (id)
);

create table disks (
    id integer not null auto_increment,
    user_id integer,
    diskname varchar(50),
    ....,
    primary key (id),
    foreign key (user_id) references users (id)
);

对于files,您将不得不回答以下问题:文件所有权是直接依赖于文件,还是传递给磁盘所有权,还是所有权独立? John拥有的一个由Jack拥有的磁盘上的文件?对我来说似乎没问题,但您的域名可能有不同的规则。在这种情况下,从文件表中删除user_id(否则您的数据库不会在Third normal form中)。

create table files (
    id integer not null auto_increment,
    disk_id integer,
    user_id integer, -- you have to decide whether this is necessary
    filename varchar(50),
    ....,
    primary key (id),
    foreign key (disk_id) references disks (id),
    foreign key (user_id) references users (id)
);