mySQL-表锁定与行锁定

mySQL-表锁定与行锁定,mysql,database,transactions,insert,Mysql,Database,Transactions,Insert,应用程序说明 我有一个表,其中存储的id代表地图上的区域。每张地图包含1000个区域。领土是地图上任何数量的接触区域。用户争夺地图不同区域的所有权 数据库设计 目前我有一张地图表、一张领土表和一张地区表 tblMaps: MapID, MapName tblTerritories: TerrID (unique game wide), MapID, OwnerID, Status, Modified tblAreas: AreaID (1-1000), TerrID 目前,tblAreas

应用程序说明

我有一个表,其中存储的id代表地图上的区域。每张地图包含1000个区域。领土是地图上任何数量的接触区域。用户争夺地图不同区域的所有权

数据库设计

目前我有一张地图表、一张领土表和一张地区表

tblMaps: MapID, MapName

tblTerritories: TerrID (unique game wide), MapID, OwnerID, Status, Modified

tblAreas: AreaID (1-1000), TerrID
目前,tblAreas仅存储地图中的占用区域-无论是否有人拥有,它都不包含每个地图的1000条记录

当用户试图获得某些区域的所有权时,应用程序必须连接三个表,并查询该地图中的所有已获取区域。如果其中任何一个被拿走,它应该拒绝他的所有权尝试。如果所有区域都是自由的,则应创建一个新区域,并在tblAreas中添加相关区域

问题

我意识到我需要一个基于事务的系统,这样两个用户就不会同时“拥有”这个区域。现在就我所知,我必须锁定整个区域表,查询区域是否空闲,插入一个新区域及其区域,提交它并解锁表。。。或者,Areas表应该包含每个地图的所有1000个区域,并且锁应该只应用于该地图的行


希望有更好的选择,因为在我看来。锁定表将意味着所有区域数据在该秒内不可用,或者行锁定时,表中充满了无用的未占用区域。

如果您在tblAreas.AreaID上有索引,则任何包含(…)中tblAreas.AreaID的
事务都将锁定这些项的索引。行本身是否存在并不重要。该锁将阻止另一个事务为这些ID插入任何条目。所以我认为你不需要做任何一个建议。只需查询查看您的区域是否所有可用的区域,就可以获得以原子方式插入区域所需的锁


这可能有点问题,因为您的区域ID不是游戏范围内唯一的,所以在不同地图中具有相同ID的区域之间可能存在一些错误的序列化。将mapID添加到tblAreas表中可能会有所帮助,这样您就可以创建(mapID,areaID)索引来进行查找,从而避免索引上的错误冲突。(这将使您的模式非规范化,您可能出于其他原因不想这样做。)

我很困惑-究竟什么是区域?地图,我明白了。领土只是地图的一部分,可以拥有(我想是吧?)。一个地区是一组领土吗?或者一个区域是一组区域?对不起,我已经编辑过了。。这张地图由1000个区域组成。territory是一个用户拥有的相邻区域的集合。我是否可以将mapID锁定在TbAlterritories中以阻止任何人插入新条目?非规范化是如此诱人。。。这将使可用区域的查询变得更加容易(只需查询tblarea..而不是将三个表连接在一起..)。。。但我认为这会降低效率。你怎么看?是的,我想如果你通过mapID查询TBlteritories,这会阻止其他人在你的交易中插入另一个区域。