我正在使用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 楼

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

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

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

评论


提示:“关系”视图在您的表格下方是一个很小的链接,我很难一开始就找到它

–Mladen Janjetovic
14年2月18日在9:33

除非在该情况下未显示该链接,否则在这种情况下:确保您的表的类型为InnoDB(在phpMyAdmin的“操作”选项卡下),以免发生这种情况。

–muttley91
14-10-16在2:44



@ muttley91我的表是InnoDB。我仔细检查了。链接仍然没有显示。

– afilina
15年9月22日在15:28

@afilina在新版本的phpMyAdmin中,它在“结构”选项卡内部的顶部,显示“浏览”,“结构”等的选项卡行的下方可见。

– Astitva Srivastava
18年4月2日在18:42

#2 楼

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

要设置外键,以便PID列在名为CHILD的表中引用在名为PARENT的表中的ID列,您可以执行以下操作:对于两个表,请转到操作选项卡并将其类型更改为“ INNO DB “
确保ID是PARENT表的主键(或至少是索引列)。
在CHILD表中,定义PID列的索引。
在查看结构时CHILD表的“标签”标签中,单击“添加字段”部分上方的“关系视图”链接。
将为您提供一个表,其中每一行都对应于CLIENT表中的索引列。每行的第一个下拉列表使您可以选择索引列引用的TABLE-> COLUMN。在PID的行中,从下拉列表中选择PARENT-> ID,然后单击GO。

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

评论


哇,非常重要的事情要知道。在寻求有关添加外键的帮助时,该页面并不是我发现的第一件事,我希望能经常提及该页面。

–user1299656
2014年3月16日17:03

#3 楼

这是维基百科文章的摘要。它指定您可以在PHPmyadmin中规定的不同类型的关系。我将其放在此处是因为它与@Nathan关于设置“在更新/删除时”的外键选项有关的注释有关,但对于注释而言太大了-希望对您有所帮助。

CASCADE

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

RESTRICT

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

NO ACTION

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

SET NULL

参照行中的外键值当更新或删除引用的行时,将它们设置为NULL。仅当引用表中的各个列为可空时,才有可能。由于NULL的语义,在外键列中具有NULL的引用行不需要被引用的行。

SET DEFAULT

类似于SET NULL(外键)更新或删除引用行时,引用行中的值将设置为默认列。

评论


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

– kmoser
17年1月13日在17:44

#4 楼

在phpmyadmin中,您可以仅通过其GUI分配外键。单击表格,然后转到“结构”选项卡。在表格的下面找到“关系视图”(如下图所示)。



您可以在主密钥附近的列表框中分配锻造密钥(请参见下图)。并保存



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

#5 楼

对于那些刚接触数据库的人,需要更改现有表。很多事情似乎很简单,但是在A和B之间总是存在某些东西。

在进行其他操作之前,请先看一下。


请确保您具有P_ID(父级和子级表上的父级ID)。
当然,它已被填充到父级中。不一定以真实和最终的方式对待孩子。因此,例如P_ID#3(子表中的许多次可能会指向父表中的原始P_ID)。

转到“ SQL”选项卡(我使用的是phpMyAdmin,应该与其他类似)并执行以下命令:
表,而不是结构,最后是关系视图。在那里完成数据库计划。在此之前,有一个关于级联,限制等的好答案。
当然,这可以通过命令来完成...


#6 楼

外键表示表的非素数属性引用phpMyAdmin *中另一个
*的素数属性首先将要设置外键的列设置为索引

,然后单击RELATION VIEW

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

#7 楼

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 Long)
09年10月2日,11:43

@Nathan:这就是我在帖子中所说的。您也可以在模型级别进行处理。您可以从模型上实现删除级联。

–马库斯
09年10月2日在12:52

您几乎总是将参照完整性添加到数据库表中。数据库应保护自己免受错误的应用程序编程的侵害。不要仅依靠您的应用程序来维护数据完整性。当然,每条规则总是有例外,但我还没有为此找到例外。

– Harv
2012年6月1日于20:15

#8 楼

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

例如,如果一列是INT类型,另一列是tinyint类型,则会出现以下错误:

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

#9 楼

步骤1:
您必须添加以下行:
default-storage-engine = InnoDB
在mysql配置文件(my.cnf或my.ini取决于您的操作系统)并重新启动mysqld服务。


步骤2:
现在创建表时,您将看到表的类型为:InnoDB



步骤3:
创建父表和子表。现在,打开“子”表并选择要具有外键的U列:
从操作标签中选择索引键,如下所示。



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


步骤5:
选择列U希望具有外键作为从下拉列表中选择父列。
dbName.TableName.ColumnName

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


#10 楼

这是旧线程,但是可以回答,因为如果对任何人都有用。 />这里customer是主表,而customer_id是主键



步骤3。创建外键表并提供索引

这里customer_addresses作为相关表并存储客户地址,因此在这里customer_idcustomer表的关系

当创建表时,如下所示我们可以直接选择索引



如果创建表时忘记提供索引,则可以从表的结构选项卡中提供索引,如下所示。



步骤4。一旦索引提供给在字段中,转到结构选项卡,然后单击“关系视图”,如下图所示。图片



步骤5。现在,选择“删除”和“更新”您要执行的操作,从当前表中选择列,选择DB(SAME DB),选择关系表和主键从该表中如下图所示,并将其保存



现在检查是否成功建立了关系,转到外表数据列表并单击外键值,将重定向到主表记录,然后成功建立关系。

#11 楼

首先将存储引擎设置为InnoDB



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



评论


您的第一步是正确的,但是接下来呢,请逐步编写所有过程。

– kunal shaktawat
19/12/30在5:57

#12 楼

确保已选择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);


#13 楼

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


MySQL要求在外键和引用键,因此
外键检查可以快速进行,而无需进行表扫描。


#14 楼

较新版本的phpMyAdmin不再具有“关系视图”选项,在这种情况下,您将必须执行一条语句以实现同一目的。例如,

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


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