在 phpMyAdmin 中设置外键?
Posted
技术标签:
【中文标题】在 phpMyAdmin 中设置外键?【英文标题】:Setting up foreign keys in phpMyAdmin? 【发布时间】:2010-10-02 08:08:19 【问题描述】:我正在使用 phpMyAdmin 设置数据库。我有两个表(foo
和 bar
),索引在它们的主键上。我正在尝试在它们之间创建一个关系表 (foo_bar
),使用它们的主键作为外键。
我将这些表创建为 MyISAM,但后来将这三个表都更改为 InnoDB,因为我读到 MyISAM 不支持外键。所有id
字段均为INT(11)
。
当我选择foo_bar
表时,单击“关系视图”链接,并尝试将FK 列设置为database.foo.id
和database.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_id
与customer
表有关系
我们可以在创建表时直接选择索引,如下所示
如果你在建表的时候忘记给索引,那么你可以从表的结构标签中给索引,如下所示。
第 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 步: 同时创建父表和子表。现在打开子表并选择列 U 喜欢有外键: 从 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 中设置外键?的主要内容,如果未能解决你的问题,请参考以下文章