在 phpMyAdmin 中设置外键?

Posted

技术标签:

【中文标题】在 phpMyAdmin 中设置外键?【英文标题】:Setting up foreign keys in phpMyAdmin? 【发布时间】:2016-08-07 16:13:35 【问题描述】:

我正在使用 phpMyAdmin 建立一个数据库。我有两个表(foobar),索引在它们的主键上。我正在尝试在它们之间创建一个关系表 (foo_bar),使用它们的主键作为外键。

我将这些表创建为 MyISAM,但后来将这三个表都更改为 InnoDB,因为我读到 MyISAM 不支持外键。所有id 字段均为INT(11)

当我选择foo_bar 表时,单击“关系视图”链接,并尝试将FK 列设置为database.foo.iddatabase.bar.id,它显示“未定义索引!” 在每列旁边。

我错过了什么?

澄清/更新

为了简单起见,我想继续使用 phpMyAdmin。我目前正在使用 XAMPP,它很容易让我专注于 PHP/CSS/javascript,它带有 phpMyAdmin。

此外,虽然我还不能设置显式外键,但我确实有一个关系表,并且可以执行如下连接:

SELECT * 
FROM foo 
INNER JOIN foo_bar 
ON foo.id = foo_bar.foo_id 
INNER JOIN bar
ON foo_bar.bar_id = bar.id;

没有在数据库中明确定义 FK 让我感到不舒服。

【问题讨论】:

【参考方案1】:

确保您已将 mysql 存储引擎选择为 Innodb 而不是 MYISAM,因为 Innodb 存储引擎支持 Mysql 中的外键。

在phpmyadmin中创建外键的步骤:

    点击将具有外键的表的结构。 为要用作外键的列创建INDEX。 点击位于表格结构下方的关系视图

    在“关系”视图页面中,您可以在字段前面看到选择选项(该字段已成为 INDEX)。

UPDATE CASCADE指定当被引用的列更新时该列也会更新,

DELETE CASCADE在删除引用的行时将删除指定的行。

或者,您也可以触发相同的 sql 查询

ALTER TABLE table_name
ADD CONSTRAINT fk_foreign_key_name
FOREIGN KEY (foreign_key_name)
REFERENCES target_table(target_key_name);

【讨论】:

【参考方案2】:

较新版本的 phpMyAdmin 不再具有“Relation View”选项,在这种情况下,您必须执行一条语句才能实现相同的目的。例如

ALTER TABLE employees
    ADD CONSTRAINT fk_companyid FOREIGN KEY (companyid)
    REFERENCES companies (id)
    ON DELETE CASCADE;

在此示例中,如果删除了公司中的一行,则具有该 companyid 的所有员工也将被删除。

【讨论】:

【参考方案3】:

这是旧线程,但回答是因为如果对任何人有用。

第 1 步。您的数据库存储引擎设置为 InnoDB

第 2 步。创建主表

这里customer 是主表,customer_id 是主键

第 3 步。创建外键表并给出索引

这里我们有customer_addresses 作为相关表并存储客户地址,所以这里customer_idcustomer 表有关系

我们可以在创建表时直接选择索引如下

如果你在建表的时候忘记给索引,那么你可以从表的结构标签中给索引,如下所示。

第 4 步。一旦索引给该字段,转到结构选项卡并单击关系视图,如下图所示

第 5 步。现在选择 ON DELETE 和 ON UPDATE 你想要做什么,从当前表中选择列,选择 DB(SAME DB),从该表中选择关系表和主键,如下图所示,保存

现在检查关系是否成功,进入外表数据列表并点击外键值,您将重定向到主表记录,然后关系成功。

【讨论】:

【参考方案4】:

首先将存储引擎设置为InnoDB

然后在结构菜单中启用关系视图选项

【讨论】:

你的第一步是正确的,但下一步呢,请一步一步写出所有的过程。【参考方案5】:

对于那些刚接触数据库的人......并且需要 ALTER 现有的表。很多事情看起来很简单,但在 A 和 B 之间总有一些东西……。

先看看this。

    确保您有 P_ID(父表和子表上的父 ID)。 当然它已经填入了父项。不一定以真实和最终的方式在孩子身上。因此,例如 P_ID #3(可能在子表中多次指向父表中的原始 P_ID)。

    转到 SQL 选项卡(我使用的是 phpMyAdmin,其他的应该类似)并执行以下命令:

    ALTER TABLE child_table_name    
    ADD FOREIGN KEY (P_ID)   
    REFERENCES parent_table_name (P_ID)
    

    单击子表,然后单击结构,最后单击关系视图。在那里完成你的数据库计划。在此之前有一个关于级联、限制等的很好的答案。 当然可以通过命令来完成...

【讨论】:

【参考方案6】:

这是***文章的摘要。它指定了您可以在 PHPmyadmin 中规定的不同类型的关系。我把它放在这里是因为它与@Nathan 关于设置“更新/删除”的外键选项的评论相关,但对于评论来说太大了 - 希望它有所帮助。

级联

每当主(引用)表中的行被删除(相应更新)时,具有匹配外键列的子(引用)表的相应行也将被删除(相应更新)。这称为级联删除(resp. update[2])。

限制

当外键表中存在引用被引用表中的值的行时,无法更新或删除该值。同样,只要有外键表中的引用,就不能删除行。

无操作

NO ACTION 和 RESTRICT 非常相似。 NO ACTION 和 RESTRICT 之间的主要区别在于,使用 NO ACTION 时,参照完整性检查是在尝试更改表后完成的。 RESTRICT 在尝试执行 UPDATE 或 DELETE 语句之前进行检查。如果引用完整性检查失败,这两个引用操作的行为相同:UPDATE 或 DELETE 语句将导致错误。

设置为空

更新或删除引用行时,引用行中的外键值设置为 NULL。这只有在引用表中的相应列可以为空时才有可能。由于 NULL 的语义,外键列中有 NULL 的引用行不需要引用行。

设置默认值

与 SET NULL 类似,当引用行被更新或删除时,引用行中的外键值被设置为列默认值。

【讨论】:

更好的是,直接转到 MySQL 源文档:dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html【参考方案7】:

来自https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html的官方 MySQL 文档:

MySQL 需要外键和引用键的索引,以便 外键检查可以很快而且不需要表扫描。

【讨论】:

【参考方案8】:

第 1 步: 您必须添加以下行: 默认存储引擎 = InnoDB 在你的 mysql 配置文件(my.cnf 或 my.ini 取决于你的操作系统)的 [mysqld] 部分下并重新启动 mysqld 服务。

第 2 步: 现在,当您创建表时,您将看到表的类型是:InnoDB

第 3 步: 同时创建父表和子表。现在打开 Child 表并选择列 U like to have the Foreign Key: 从 Action Label 中选择 Index Key 如下所示。

第 4 步: 现在在打印视图附近从底部打开同一个子表中的关系视图,如下所示。

第 5 步: 选择列 U 喜欢将外键设置为 从下拉列表中选择父列。 dbName.TableName.ColumnName

为 ON DELETE 和 ON UPDATE 选择适当的值

【讨论】:

【参考方案9】:

如果你想使用 phpMyAdmin 建立关系,你必须做两件事。首先,您必须在引用表中的外键列上定义一个索引(在您的情况下是 foo_bar.foo_id)。然后,转到关系视图(在引用表中)并选择引用列(在您的情况下为 foo.id)以及更新和删除操作。

如果您有多个相互链接的表,我认为外键很有用,特别是如果您正确设置引用选项,您的删除脚本将变得非常短。

编辑:确保两个表都选择了 InnoDB 引擎。

【讨论】:

提示:关系视图是你桌子下的小链接,我一开始很难找到它 除非该链接没有显示在那里,在这种情况下:确保您的表是 InnoDB 类型(在 phpMyAdmin 的“操作”选项卡下),以免发生这种情况。 @muttley91我的表是 InnoDB。我仔细检查了一遍。链接仍然没有显示。 @afilina 在新版本的 phpMyAdmin 中,它在“结构”选项卡的顶部可见,就在显示“浏览”、“结构”等的选项卡行下方。【参考方案10】:

在 phpmyadmin 中,您可以简单地通过其 GUI 分配外键。单击表并转到结构选项卡。在表格的下方找到关系视图(如下图所示)。

您可以从主键附近的列表框中分配锻造键。(见下图)。并保存

相应的SQL查询自动生成并执行。

【讨论】:

【参考方案11】:

外键表示一个表的非主属性引用另一个表的主属性 *在phpMyAdmin中*首先设置你要设置外键的列作为索引

然后点击关系视图

你可以找到设置外键的选项

【讨论】:

【参考方案12】:

phpMyAdmin 允许您使用它们的“关系”视图定义外键。但由于 MySQL 仅支持对“INNO DB”表的外部约束,所以第一步是确保您使用的表属于该类型。

要设置外键,以便名为 CHILD 的表中的 PID 列引用名为 PARENT 的表中的 ID 列,您可以执行以下操作:

    对于这两个表,转到操作选项卡并将其类型更改为“INNO DB” 确保 ID 是 PARENT 表的主键(或至少是索引列)。 在 CHILD 表中,为 PID 列定义一个索引。 查看 CHILD 表的结构选项卡时,单击“添加字段”部分正上方的“关系视图”链接。 您将获得一个表,其中每一行对应于 CLIENT 表中的一个索引列。每行中的第一个下拉列表允许您选择索引列引用的 TABLE->COLUMN。在 PID 行中,从下拉列表中选择 PARENT->ID,然后单击 GO。

通过对 CHILD 表进行导出,您应该会看到已为 PID 列创建了外键约束。

【讨论】:

哇,很重要的事情要知道。这个页面不是我在寻求添加外键帮助时发现的第一件事,我希望这个页面被更多地提及。【参考方案13】:

不要忘记两列应该具有相同的数据类型。

例如,如果一列是 INT 类型而另一列是 tinyint 类型,您将收到以下错误:

在 [PID 列] 上创建外键时出错(检查数据类型)

【讨论】:

【参考方案14】:

InnoDB 允许您使用 ALTER TABLE 向表中添加新的外键约束:

ALTER TABLE tbl_name
    ADD [CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

另一方面,如果 MyISAM 在您的上下文中比 InnoDB 具有优势,那么您为什么要创建外键约束呢?您可以在应用程序的模型级别处理此问题。只需确保您要用作外键的列已编入索引!

【讨论】:

外键约束为我节省了大量的精力和潜在的错误。例如,假设我要从我的系统中删除一个用户。我可以编写代码来指定数据库中存在有关该用户的数据的每个位置,并告诉它删除它。但是我必须始终保持该删除功能是最新的。另一方面,如果所有与用户相关的数据都具有用户 ID 的 FK 并设置为删除时级联,那么我的所有代码都必须说“删除此用户”,并且数据库将负责删除所有具有对该用户的 FK 引用。维护起来更干净。 @Nathan:这就是我在帖子中所说的。您也可以在模型级别处理它。您可以从模型中实现删除级联。 您几乎总是将参照完整性添加到您的数据库表中。数据库应该保护自己免受不良应用程序编程的影响。不要仅依靠您的应用程序来维护数据完整性。当然,每条规则总有例外,但我还没有找到一个例外。

以上是关于在 phpMyAdmin 中设置外键?的主要内容,如果未能解决你的问题,请参考以下文章

在 phpMyAdmin 中设置外键?

如何在 Spring JPA 中设置外键列

如何在MySQL中设置外键约束以及外键的作用

怎么在SQL中设置外键

在 PHPUnit/DBUnit 中设置外键约束

如何在 SQL Azure 中设置外键?