当前位置: 首页 > 面试题库 >

如何在phpMyAdmin中设置表之间的关系

孟泽宇
2023-03-14
问题内容

我的问题是,例如,当我创建一个表时:table1以下几列:

  • customerId
  • CustomerName
  • Address
  • State

哪里customerIdPRIMARY KEYAUTO_INCREMENT

然后table2以列为例:

  • purchaseId
  • customerId
  • product
  • cost

PRIMARY KEYpurchaseId与外键是customerIdtable1

应该是说我已经建立的关系table1table2使用customerId

这两个表最初都是空的,因此我编写了以下SQL命令:

INSERT INTO table1 (CustomerName,Address,State) VALUES('value1','value2','value3')

这很好用,但是当我尝试插入子表(table2)时,它告诉我:

错误外键约束

所以基本上我想要做的是插入到父表,然后到子表,以便customerId显示出来的table2(子表)的外键,相当于用customerIdtable1(父表)。

我必须先创建两个表,而无需使用外键,然后再尝试建立关系。一直在说,只要关系存在就存在约束。


问题答案:

table2外键约束意味着任何table2客户ID值都必须在表1中显示为客户ID。之所以出现错误,是因为您正在将未在table1中出现的customerID插入到table2中。

由于DBMS通过自动递增生成table1客户ID,所以如果您插入一行,则必须获取该值,以便使用该customerID将一行插入table2。

我猜您说“我已经在table1和table2之间建立了关系”的意思是“我声明了外键约束”。我猜您认为这意味着“插入表1后,DBMS将在插入表2时将自动生成的键值用作外键值”。但这并不意味着那样。你必须自己做。外键约束仅意味着DBMS检查每个table2
customerId值是否都显示为table1 customerId值。

当您插入具有外键的表时,您可以并且必须使用任何先前插入的键值作为相应值。

要获取由DBMS生成的自动递增的键值,请使用LAST_INSERT_ID():

INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(LAST_INSERT_ID(),'valueA','valueB');

这就是它的目的。但是,如果不使用它,就会出现问题。

首先,如果您不在序列化事务中,则必须使用LAST_INSERT_ID()。因为在table1插入之后但在table2插入之前,其他人可能已经添加了行和/或删除了行(包括新行)和/或更改了行(包括新行)。因此,在table1插入后获得您知道已添加的某些customerId值之后,就不能依赖于查询table1。

其次,假设您正在进行序列化事务,并且不使用LAST_INSERT_ID()。

如果(CustomerName,Address,State) 也是 table1 的超键 ,即它的值是唯一的,即在其所有或某些列上声明了SQL
UNIQUE / KEY / PK,那么您可以使用它来查询关联的新customerId :

set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName = 'value1'
    AND Address = 'value2'
    AND State = 'value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

但是,如果(CustomerName,Address,State) 不是 table1 的超键
,那么您将无法执行此操作。因为该子行的其他重复行可能在table1中。这样您可以返回多行。因此,您将不知道哪个是最新的。取而代之的是,您必须在插入之前查询table1,然后插入,然后找到新旧客户ID集之间的区别:

CREATE TEMPORARY TABLE table1old (
    customerId (int) PRIMARY KEY
    );
INSERT INTO table1old
SELECT customerId FROM table1;

INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');

set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName NOT IN table1old);
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

只需使用LAST_INSERT_ID()。

PS:有趣的是,给定表定义,理想情况下可以这样写:

INSERT INTO (
    SELECT CustomerName,Address,State,A,B
    FROM table1 JOIN table2
    USING (CustomerId))
VALUES('value1','value2','value3','valueA','valueB')

因为只会产生一对新的table1和table2值。通过SQL中的视图有一些合法的更新,尽管目前没有涉及MySQL中的多个表的更新



 类似资料:
  • 问题内容: 我正在使用Airflow计划批处理作业。我有一个DAG(A)每晚运行,另一个DAG(B)每月运行一次。B取决于A已成功完成。但是B需要很长时间才能运行,因此我想将其保存在单独的DAG中,以实现更好的SLA报告。 如何使运行DAG B依赖于同一天DAG A的成功运行? 问题答案: 您可以使用名为ExternalTask​​Sensor的运算符来实现此行为。将安排DAG(B)中的任务(B1

  • 问题内容: 我正在使用phpMyAdmin建立数据库。我有两个表(和), 在它们的主键上建立了索引 。我正在尝试使用它们的主键作为外键在它们之间创建一个关系表()。 我将这些表创建为MyISAM,但是后来将这三个表都更改为InnoDB,因为我读到MyISAM不支持外键。所有字段均为。 当我选择表格时,单击“关系视图”链接,然后尝试将FK列设置为和,它显示 “未定义索引!” 每列旁边。 我想念什么?

  • 我有一个医院(点)的空间表,它与(非空间)价表(卷曲、紧急等)具有一对多关系。 医院(id,name,geom);化合价(id,名称,化合价) “name”是公共字段。 如何在PostgreSQL/Postgis中构造一个有效的Geojson,其中每个医院(点)可以有一个或多个价? 我已经尝试了这个查询的一些变体,但是总是给出相同的错误“作为表达式使用的子查询返回了多行”。 非常感谢!

  • 我试图在javaFx程序中显示一个2列网格。这就是我设置网格的方式: 问题是。我想展示一个小空间,在一列结束和另一列开始之间。然而,这些柱子却像胶水一样粘在一起。 以下是一个截图: 这里每一列都包含项目名称和处理、编辑、删除按钮。 你可以看到柱子是如何粘在一起的。我希望它们之间有一些空间。 我该怎么解决这个问题? 我的整个UI的层次结构如下: 场景

  • null 从Spring Security项目中,只需从https://github.com/spring-projects/spring-security/blob/master/settings.gradle中选择几行代码 和gradle项目本身的一个小片段,来自https://github.com/gradle/gradle/blob/master/settings.gradle

  • 我使用Laravel7和Corcel连接到WordPress安装的数据库。 连接工作正常,到目前为止从WordPress获取数据没有问题: