1

我一直在学习外键,我想知道在下面的示例中我使用它的方式是否正确:

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,我怎样才能从外键中获得最大的信息?

4

2 回答 2

2

您不必在两个表中都包含项目名称。这称为非规范化解。您应该只在项目表中拥有它并且只引用 id,然后如果您需要名称,您也可以根据主键(id)加入它。否则在我看来完全没问题。

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 (id) REFERENCES user(id)
);

有时,当性能至关重要时,您必须使用非规范化表。它可以更快。

标准化对于避免不同的异常很重要。如果您有高级正常形式的表格,那么您的表格将不会是多余的并且不会有这些异常。例如,如果您将某些内容存储在多个位置,则必须照顾以使所有冗余数据保持最新。这使您有机会错误地执行此操作并最终出现不同的异常。

在您的情况下,拥有外键可以帮助您保持数据完整性,但如果没有名称的外键,您将能够在项目表中不存在购买名称的项目。

这是一种反常现象。

这种情况有很多种,最好尽量避免。

在此处阅读有关异常的更多信息

在某些情况下,你必须去正规化。因此,由于性能问题,冗余存储了一些数据。这样,您可以节省一些可能会耗费大量时间的连接操作。

归一化的细节由不同范式的主题涵盖:NF0、NF1、NF2、NF3 和 BCNF

范式详解

有关无损分解为更高范式的数学基础的更多详细信息,请参阅“函数依赖关系”。这将帮助你理解为什么你可以保持 ids “冗余”。实际上,它们是必要的冗余,因为您需要它们以便以后能够重建原始数据集。这将是不同范式的定义。允许何种级别的冗余?

功能依赖

于 2013-11-02T12:11:45.747 回答
2

你有一个i_id作为主键,你不需要设置一个名字作为外键。顺便说一句,外键必须引用唯一属性。

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 UNIQUE 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 (id) REFERENCES `user`(id)    
);
于 2013-11-02T12:27:07.090 回答