【问题标题】:Foreign key for multiple tables and columns?多个表和列的外键?
【发布时间】:2013-11-13 12:53:10
【问题描述】:

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

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,我如何仅从外键获取最大信息?

【问题讨论】:

    标签: mysql database database-design foreign-keys


    【解决方案1】:

    您不必在两个表中都包含项目名称。这称为非规范化解。 您应该只在项目表中拥有它并且只引用 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)
    );
    

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

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

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

    这是一种异常。

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

    Read more here about anomalies

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

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

    Normal forms in detail

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

    Functional Dependencies

    【讨论】:

    • 但是规范化和非规范化的东西呢?我一直在看到这种情况,但我似乎无法很好地解释这两个从谷歌看来非常重要的事情。你能解释一下吗?谢谢。
    • 希望对您有所帮助。如果您还有其他问题,请随时将它们包括在内。如果有些地方不明白,请告诉我,我可以说的更详细。
    • 你有详细解释规范化和非规范化内容的链接吗?或者也许是一本书?我很想详细了解这些内容。非常感谢:)
    • 简而言之,规范化结构是指没有重复数据(我猜除了 id)并且您永远不会有空值或缺失值。有整个研究领域致力于寻找自动方法来规范化数据。还有多个标准化水平,大多数人在中间找到一个水平,而不是完全标准化。在某些情况下,DBA 会选择非规范化表(一个大表)而不是规范化结构(许多较小的表),因为它们在某些情况下要快得多
    • 在这种情况下 - “数据重复”被称为冗余。冗余数据越多,范式越低,分解越不规范。
    【解决方案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)    
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      • 2021-05-02
      • 1970-01-01
      相关资源
      最近更新 更多