如何在连接表中为多对多关系插入值?

xyz*_*xyz 7 mysql rdbms database-design relational-theory

我在数据库中有三个表:

 trips(trip_id(pk), trip_name(unique), user_id(fk))

 places(place_id(pk), place_name(unique))

 trips_places_asc(trip_id(fk), place_id(fk))
Run Code Online (Sandbox Code Playgroud)

由于多次旅行可以有很多地方,因此我有一个如上所示的连接表。

如果用户在行程中插入地点,地点将被添加到places表格中,并且行程将与trips_places_asc表格中的地点相关联。

因此,如果我编写如下查询:

INSERT INTO places (place_name)
VALUES ('XYZ')

INSERT INTO trips (trip_name)
VALUES ('MyTrip')
Run Code Online (Sandbox Code Playgroud)

那么如何在 Junction 或 Association 表中存储trip_idand呢?我是否必须触发两个查询?place_idtrips_places_asc

Joe*_*own 8

您希望保持存储新地点和旅行的动作的原子性,以及两者之间的交集。在 MySQL 中,您可以使用START TRANSACTION/COMMIT事务包装器执行此操作。

您使用 MySQL 函数LAST_INSERT_ID()(请参阅文档;类似于 SQL Server 变量@@IDENTITY)来获取最近分配的自动增量值的值。

要添加一个地点和一次旅行并将两者关联起来,您可以编写如下代码:

START TRANSACTION

DECLARE placeKey int

INSERT INTO places (place_name)
VALUES ('XYZ')

SET placeKey = LAST_INSERT_ID()

DECLARE tripKey int

INSERT INTO trips (trip_name)
VALUES ('MyTrip')

SET tripKey = LAST_INSERT_ID()

INSERT INTO trips_places_asc(trip_id, place_id)
VALUES (tripKey, placeKey)

COMMIT
Run Code Online (Sandbox Code Playgroud)

您应该在上面添加错误处理,如果中途发生错误,请使用该ROLLBACK命令撤消部分完成的工作。

您还应该阅读 LAST_INSERT_ID() 以确保您知道它是如何工作的。在某些情况下,它可能会给您带来不希望的结果,例如当您使用单个 insert 语句插入多行时。