大概你会使用类似这样的 MySQL 特定的 SQL:
INSERT INTO location (user_id,long, lat) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE long=?, lat=?;
在具有如下定义的表上:
CREATE TABLE location (
user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
long FLOAT NOT NULL DEFAULT 0,
lat FLOAT NOT NULL DEFAULT 0,
PRIMARY KEY (user_id)
);
这可能是您可以为此目的使用的最简单的表格。如果您需要根据位置搜索表格,您可能还需要此索引来进行边界框搜索。
INDEX location_lat_long_user_id (lat, long, user_id)
因此,MySql 至少每次更新都需要访问user_id 键,并且可能还需要更新其他索引。
如果您在该表中放入更多信息或更多索引,则您的插入和更新将变得更加复杂,MySql 无法处理。
每秒 10K 的事务对于单个 MySQL 服务器来说是一个非常高的数字。如果您正确配置节点连接池,您的 MySQL 服务器将不会崩溃。但是您的节点服务器可能会慢下来,甚至内存不足。
如果您的应用扩展到 10K/秒,您可能需要考虑设置MySQL cluster。但是,YAGNI,在您的应用扩大规模之前不要这样做。获得成千上万的用户需要一段时间。与此同时,您的时间和金钱花在功能上比花在基础设施上要好得多。 (当你有一两个小时的空闲时,问我怎么知道的。)
但是,还有更多的方法可以优雅地处理这种工作负载。
使用 nodejs 内置的固有队列机制。对于这些位置更新,使用相当小的 MySQL 连接池。当池中的所有连接都处于活动状态时,节点将或多或少地自动将您传入的位置报告 API 请求排队。这将允许您的服务器在获得短暂的位置更新时优雅地放慢速度。
不要太频繁地记录位置数据。普通的 GPS 数据最多只能精确到几米。如果您的拍摄对象正在行走,则他们至少需要几秒钟才能移动一米。
仅当您知道受试者的手机已移动超过一定距离时才更新数据库。最好的方法是在您的应用程序中。使其仅在主体移动一定距离时报告新位置。这样,您将避免来自固定主题的重复更新。这将为手机节省大量电量。
-
您的更新还以度/秒为单位发送了时间戳和运动矢量。并且,仅在位置或运动矢量发生显着变化时发送它。您的更新可能如下所示:
time long lat dlong dlat
1581106542 -73.98508 40.74780 -0.0004 -0.0005
然后,如果您需要猜测您的主题的当前位置,您可以将向量乘以时间差并将其添加到该位置。如果您的对象快速移动(飞机、火车和汽车)并且您需要在后端准确猜测它们的位置,这将很有帮助。