数据库
首页 > 数据库> > mysql – 如何在PHP中使用外键

mysql – 如何在PHP中使用外键

作者:互联网

所以我理解如何创建外键,我知道FK的目的是什么.但是我在理解如何使用它们时遇到了问题.我问了一个关于外键HERE(Click link)的问题

这是我做的:

CREATE TABLE user(
  id INT(11) NOT NULL AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL,
  password VARCHAR(20) NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE items(
  i_id INT(11) NOT NULL AUTO_INCREMENT,
  name TINYTEXT NOT NULL,
  price DECIMAL(8,2) NOT NULL,
  PRIMARY KEY (i_id)
);

CREATE TABLE user_purchase(
  i_id INT(11) NOT NULL,
  name TINYTEXT NOT NULL,
  id INT(11) NOT NULL,
  FOREIGN KEY (i_id) REFERENCES items(i_id),
  FOREIGN KEY (name) REFERENCES items(name),
  FOREIGN KEY (id) REFERENCES user(id)
);

现在我的问题是如何使用PHP充分利用它?从上面的链接,人们建议在user_purchase表中只使用一个外键是好的,但如果我想要多个列呢?为什么我们不为同一个表的不同列使用多个外键?

我正在使用mysql和php.如果你能展示一些如何使用带有外键的表来使用PHP来获取使用MYSQL命令获取信息的例子,我将不胜感激.我真的需要一个彻底的解释.

我还需要理解规范化和非规范化这两个术语.如果您能够通过示例详细解释这些术语,或者如果您对数据库设计,实现等初学者的一些好书有任何建议,我将不胜感激,我将非常感激.

非常感谢.

解决方法:

外键列/约束消除歧义

So I understand how to create foreign keys and I know what is the
purpose of the FK. But I have a problem in understanding How to use
them.

假设您指的是外键约束,简短的答案就是您不要使用它们.

这是一个漫长的:

我们习惯于将列作为其他表的外键引用.特别是在规范化过程中,诸如“user_purchase.i_id是项目表的外键”之类的短语将非常普遍.虽然这是描述关系的完美有效方式,但是当我们到达实施阶段时,它会变得有点模糊.

假设您已经创建了没有FOREIGN KEY子句的表:

CREATE TABLE user(
  id INT(11) NOT NULL AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL,
  password VARCHAR(20) NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE items(
  i_id INT(11) NOT NULL AUTO_INCREMENT,
  name TINYTEXT NOT NULL,
  price DECIMAL(8,2) NOT NULL,
  PRIMARY KEY (i_id)
);

CREATE TABLE user_purchase(
  i_id INT(11) NOT NULL,
  name TINYTEXT NOT NULL,
  id INT(11) NOT NULL,
);

请注意,在关系方面,仍然实现了外键列.有一个引用用户表(id)的列和另一个引用items表(i_id)的列 – 让我们把名称列放在一边.请考虑以下数据:

  user              user_purchase    items
| id  username |    | id  i_id |    | i_id  name            price |
| 23  john     |    | 55   10  |    |  10   chocolate bar    3.42 |
| 55  mary     |    | 70   10  |    |  33   mobile phone    82.11 |
| 70  fred     |    | 70   33  |    |  54   toothpaste       8.67 |
                    | 55   10  |    |  26   toy car          6.00 |
                    | 70   26  |

关系就在那里.它通过user_purchase表实现,该表保存有关谁购买了什么的信息.如果我们要在数据库中查询相关报告,我们会这样做:

select * from user_purchase p
join user u on (p.id=u.id)
join items i on (p.i_id=i.i_id)

这就是我们如何使用关系和所涉及的外键列.

现在,如果我们这样做:

insert into user_purchase (id,i_id) values (23,99)

显然,这是一个无效的条目.虽然有一个id = 23的用户,但没有i_id = 99的项目. RDBMS将允许这种情况发生,因为它不知道更好.然而.

这就是外键约束发挥作用的地方.通过在user_purchase表定义中指定FOREIGN KEY(i_id)REFERENCES项(i_id),我们基本上为RDBMS提供了一条规则:具有i_id值但未包含在items.i_id列中的条目是不可接受的.换句话说,当外键列实现引用时,外键约束强制引用完整性.

但请注意,上面的选择不会改变,只是因为您定义了FK约束.因此,您不使用RDBMS的FK约束来保护您的数据.

裁员

…what if I want several columns? Why don’t we use several foreign
keys for different columns of the same table?

问问自己:你为什么要这样?如果两个外键用于同一目的,冗余最终会让您遇到麻烦.请考虑以下数据:

 user_purchase                   items
| id  i_id  name           |    | i_id  name            price |
| 55   10   chocolate bar  |    |  10   chocolate bar    3.42 |
| 70   10   chocolate bar  |    |  33   mobile phone    82.11 |
| 70   33   mobile phone   |    |  54   toothpaste       8.67 |
| 55   10   toothpaste     |    |  26   toy car          6.00 |
| 70   26   toy car        |

这张照片出了什么问题?用户55买了两个巧克力棒,巧克力棒和牙膏吗?这种模糊性会导致为保持数据同步而付出很多努力,如果我们只保留一个外键,这将是不必要的.实际上,为什么不完全删除名称列,因为关系暗示了它.

当然,我们可以通过实现复合外键来解决这个问题,方法是为items表设置PRIMARY KEY(i_id,name)(或者定义一个额外的UNIQUE(i_id,name)索引,它并不重要)然后设置FOREIGN KEY(i_id,name)REFERENCES项目(i_id,name).这样,只有(i_id,name)夫妇存在于items表中才会对user_purchases有效.除了你仍然有一个外键的事实之外,这种方法是完全没有必要的,前提是i_id列已经足以识别一个项目(对于名称列不能说相同……).

但是,没有规则禁止对表使用多个外键.事实上,有些情况需要这种方法.考虑一个人(id,name)表和父(person,father,mother)表,其中包含以下数据:

 person             parent
| id  name    |    | person  father  mother |
| 14  John    |    |   21      14      59   |
| 43  Jane    |    |   14      76      43   |
| 21  Mike    |
| 76  Frank   |
| 59  Mary    |

显然,父表的所有三列都是人的外键.但是,不是同一种关系,而是三种不同的关系:既然一个人的父母也是一个人,那么两个相应的列必须引用同一个人的表.但请注意,这三个字段不仅可以而且还必须在同一父行中引用不同的人,因为没有人是他自己的父母而且没有人的父亲也是他的母亲.

标签:denormalization,mysql,database,normalization
来源: https://codeday.me/bug/20191001/1839208.html