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_id
and呢?我是否必须触发两个查询?place_id
trips_places_asc
您希望保持存储新地点和旅行的动作的原子性,以及两者之间的交集。在 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 语句插入多行时。