1

我有一个 C++ 程序需要访问这个风数据,每 6 小时刷新一次。由于服务器的客户端需要数据,服务器查询数据库并将数据提供给客户端。客户端将使用 lat、lon 和 mb 作为键来查找这 ​​5 个值。

+------------+-------+-----+-----+----------+----------+-------+------+------+
| id         | lat   | lon | mb  | wind_dir | wind_spd | uv    | vv   | ts   |
+------------+-------+-----+-----+----------+----------+-------+------+------+
| 1769584117 | -90.0 | 0.0 | 100 |      125 |        9 | -3.74 | 2.62 | 2112 |
| 1769584118 | -90.0 | 0.5 | 100 |      125 |        9 | -3.76 | 2.59 | 2112 |
| 1769584119 | -90.0 | 1.0 | 100 |      124 |        9 | -3.78 | 2.56 | 2112 |

因为数据很少更改,所以我希望数据由服务器缓存,因此如果客户端需要先前查询的数据,则不需要第二个 SQL 查询。

我试图确定最有效的内存数据结构,就存储/速度而言,但更重要的是,易于访问。

我最初的想法是一个由 lat 键控的映射,包含一个由 lon 键控的映射,包含一个由 mb 键控的映射,其值为包含 wind_dir、wind_speed、uv、vv 和 ts 字段的映射。

但是,这很快就会变得复杂。当然,另一个想法是包含最后 5 个字段的结构的 3 维数组(lat、lon、mb 索引)。

当我坐在这里时,我想出了将 lat、lon 和 mb 组合成一个字符串的想法,它可以用作地图的索引,因为我 99% 确定 lat、lon 和mb 永远是独一无二的。

还有哪些有意义的想法?

编辑:下面评论的更多细节

在数据方面,数据集中有 3,119,040 行。这将是相当稳定的,尽管随着新报告站的增加,它可能会随着这些年的增加而缓慢增长。通常有 700 到 1500 个客户端请求数据。客户是飞行模拟器。默认情况下,他们将每 5 分钟请求一次数据,但可能的最大频率为每 30 秒一次。没有其他信息 - 您在上面看到的是想要返回的数据。

最后一点我忘了提:我对我的 C++ 尤其是 STL 的东西很生疏,所以越简单越好。

4

3 回答 3

1

您可以使用std::map三部分键和合适的小于运算符(这是 Crazy Eddie 提出的,用一些代码行扩展)

struct key
{
    double mLat;
    double mLon;
    double mMb;
    key(double lat, double lon, double mb) :
        mLat(lat), mLon(lon), mMb(mb) {}
};

bool operator<(const key& a, const key& b)
{
    return (a.lat <  b.lat ||
            a.lat == b.lat && a.lon <  b.lon ||
            a.lat == b.lat && a.lon == b.lon && a.mb < b.mb);
}

定义并插入地图如下所示:

std::map<key, your_wind_struct> values;
values[key(-90.0, 0.0, 100)] = your_wind_struct(1769584117, 125, ...);
于 2012-05-13T19:48:52.980 回答
0

排序的向量也很有意义。您可以为它提供一个较少的谓词来比较您的三部分键。你可以对地图或集合做同样的事情。哈希...取决于您选择哪个容器的很多因素。

于 2012-05-13T17:02:55.510 回答
0

另一个选项是 c++11 unordered_set,它使用哈希表而不是红黑树作为内部数据结构,并且(我相信)红黑的平均查找时间为 O(1) vs O(logn) . 您使用哪种数据结构取决于相关数据的特征 - 有多少条数据,可能访问特定记录的频率等。我同意几位评论者的观点,即使用结构作为键是最干净的方法。如果将来发生变化,它还允许您更简单地更改唯一密钥是什么;你只需要在你的关键结构中添加一个成员,而不是创建一个全新的地图级别。

于 2012-05-13T17:06:41.127 回答