PK和FK表设计之间的混淆

时间:2017-12-30 08:28:59

标签: php mysql sql sql-server

我有一个person表和一个score表。 Person表基本上存储了人的信息,而score表存储了一个人有什么样的分数。我将score表中的FK约束设置为ON DELETE: CASCADE

person
- id
- name
- scored_id (FK)

score
- id (PK)
- bmi
- weight

因此,在表格设置中score.id与人scored_id相关联。当我删除score中的记录时,也会删除一个人。但是为什么当我删除person中的记录时,他的分数记录不会被删除?

3 个答案:

答案 0 :(得分:2)

了解如何构建表并使用外键,如果/当删除person表中的用户时,将使用外键删除记分表中的记录。 score表应该引用用户 - pid,用作外键依赖。我觉得分数取决于用户,所以没有用户,没有分数。

create table `person` (
    `id` int(10) unsigned not null auto_increment,
    `name` varchar(50) null default null,
    primary key (`id`)
)
collate='latin1_swedish_ci'
engine=innodb
auto_increment=4;


mysql> describe person;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(50)      | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+




create table `score` (
    `id` int(10) unsigned not null auto_increment,
    `bmi` int(10) unsigned not null default '0',
    `weight` int(10) unsigned not null default '0',
    `pid` int(10) unsigned not null default '0',
    primary key (`id`),
    index `pid` (`pid`),
    constraint `fk_sc_pid` foreign key (`pid`) references `person` (`id`) on update cascade on delete cascade
)
collate='latin1_swedish_ci'
engine=innodb
auto_increment=4;



mysql> describe score;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| bmi    | int(10) unsigned | NO   |     | 0       |                |
| weight | int(10) unsigned | NO   |     | 0       |                |
| pid    | int(10) unsigned | NO   | MUL | 0       |                |
+--------+------------------+------+-----+---------+----------------+





mysql> select * from person;
+----+------+
| id | name |
+----+------+
|  1 | bob  |
|  2 | rita |
|  3 | sue  |
+----+------+


mysql> select * from score;
+----+-----+--------+-----+
| id | bmi | weight | pid |
+----+-----+--------+-----+
|  1 |  34 |     34 |   1 |
|  2 |  56 |     41 |   2 |
|  3 |  56 |     77 |   3 |
+----+-----+--------+-----+



mysql> delete from person where id=3;
Query OK, 1 row affected (0.00 sec)

/* delete a user, the score disappears too which makes sense */

mysql> select * from score;
+----+-----+--------+-----+
| id | bmi | weight | pid |
+----+-----+--------+-----+
|  1 |  34 |     34 |   1 |
|  2 |  56 |     41 |   2 |
+----+-----+--------+-----+

答案 1 :(得分:1)

您的问题是对任务的语义理解,而不是语法。直观地说你的关系看起来不对。一个特定的分数,例如75公斤和20分钟的bmi,不太可能需要将多个关系链接到具有相同分数的人。这将是任意的。更有可能的是,您希望,一个人随着时间的推移有不同的分数,然后当您删除一个人时,您希望删除他们的相关值。表关系应该是:

person
- id (Primary Key)
- name

score
- id (Primary Key)
- bmi
- weight
- scoreDate
- personID (Foreign Key to person)

得分日期将是一个有用的补充。

这种结构将允许一个人有很多分数的历史,并看到他们的体重和体重指数随时间的波动。一个语义上有用的任务,与现实产生共鸣,因此遵循现实世界应用之后的实体分析和表结构的概念。

Helpful discussion of ERD and table structure levels and relations

答案 2 :(得分:0)

在你的表中,“人”表有“得分”表的引用(FK)所以当你删除“得分”表中的记录时,要删除“用户”表中的mysql搜索相关记录。

但“得分”表没有“人”表的任何参考(FK)。

如果你想在删除个人记录时删除分数记录,你可以尝试下面的表格结构但是如果分数记录将被删除则人员记录仍然是安全的

equals()