我正在使用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只是让我感到不舒服。


当前回答

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

在做其他事情之前,先看看这个。

Make sure you have P_ID (parent ID on both parent and child table). Of course it will be already filled in the parent. Not necessarily in the child in a true and final way. So for instance P_ID #3 (maybe many times in the child table will be pointing to original P_ID at parent table). Go to SQL tab (I am using phpMyAdmin, should be similar in other ones) and do this command: ALTER TABLE child_table_name ADD FOREIGN KEY (P_ID) REFERENCES parent_table_name (P_ID) Click on child table, than structure, finally on relational view. Finish your DB planning there. There was a nice answer before this one about cascade, restrict, etc. Of course it could be done by commands...

其他回答

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

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

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

这是一篇维基百科文章的摘要。它指定了可以在PHPmyadmin中规定的不同类型的关系。我把它放在这里,因为它与@Nathan关于设置“更新/删除”外键选项的评论有关,但对于评论来说太大了。

级联

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

限制

如果外键表中存在引用引用表中的值的行,则不能更新或删除该值。类似地,只要外键表中有对该行的引用,就不能删除该行。

不采取行动

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

设置为空

更新或删除引用行的时候,引用行的外键值被设置为NULL。只有在引用表中各自的列为空时才可能这样做。由于NULL的语义,外键列中包含NULL的引用行不需要引用行。

设置默认

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

确保你的mysql存储引擎是Innodb而不是MYISAM,因为Innodb存储引擎支持mysql中的外键。

在phpmyadmin创建外键的步骤:

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

在Relation视图页面中,您可以在字段(被创建为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);

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

MySQL要求在外键和引用键上建立索引,以便 外键检查可以快速且不需要表扫描。

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

要设置一个外键,使CHILD表中的PID列引用PARENT表中的ID列,可以执行以下操作:

For both tables, go to the operations tab and change their type to "INNO DB" Make sure ID is the primary key (or at least an indexed column) of the PARENT table. In the CHILD table, define an index for the PID column. While viewing the structure tab of the CHILD table, click the "relation view" link just above the "add fields" section. You will be given a table where each row corresponds to an indexed column in your CLIENT table. The first dropdown in each row lets you choose which TABLE->COLUMN the indexed column references. In the row for PID, choose PARENT->ID from the dropdown and click GO.

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