我正在设计一个数据缓存系统,一次可以保存大量的记录,我需要知道要使用什么stl容器以及如何使用它。应用程序是我有一个非常大的用户记录数据库 - 当他们登录我的系统时,我想拉出他们的记录并缓存一些数据,如用户名和几个重要的属性。当他们与系统交互时,我会更新并访问他们的属性。有几个属性是非常不稳定的,我这样做是为了避免在许多事务上对数据库进行“敲击”。此外,我很少需要使用数据库进行排序或任何东西 - 我使用它就像一个美化的二进制保存文件(这就是为什么我很乐意将记录缓存到内存...);对我来说,一个更重要的目标是能够扩展到大量用户。
当用户注销,服务器关闭或以循环方式定期(以防万一..)时,我想将他们的数据写回数据库。
服务器保留自己的:
vector <UserData *> loggedInUsers;
使用UserData保存数据库中的用户名(字符串)和其他属性,以及网络句柄等其他临时数据。
我的第一个问题是,如果我需要在此向量中找到特定用户,那么最快的方式是什么?是否有一个不同的stl容器可以用来更快地完成此操作?我现在做的是创建一个迭代器,在loggedInUsers.begin()中启动并迭代到.end(),检查* iter-&gt; username ==“foo”并在找到它时返回。如果用户名位于向量的末尾,或者向量有5000个用户,则这是一个显着的延迟。
我的第二个问题是,我如何循环安排将这些数据写回数据库?每当我准备好向DB写入一些记录时,我都可以调用一个函数。但我不能保持向量的迭代器,因为它将变为无效。我想做的是有一个旋转队列,我可以访问队列的头部,将其保存到DB,然后将其旋转到队列的末尾。这似乎是一个很大的开销..我可以用什么类型更好地做到这一点?
我的第三个问题是,我正在使用MySQL服务器和libmysqlclient连接器/ C ..是否有任何类型的内置缓存可以“免费”解决这个问题,或者是否有完全不同的技术?我愿意接受建议
答案 0 :(得分:1)
你没有说你的系统做了什么或者如何访问它,但是这种技术可能无法很好地扩展(因为最终你会耗尽内存,而你用来查找信息的任何内容都不会作为数据库有效,并且不一定能正确处理并发用户,除非您确保可以在它们之间正确共享数据。
那说......你可能最好使用地图(http://www.cplusplus.com/reference/stl/map/),用户名作为密钥。
在将其写回数据库方面,为什么不存储每次将其写入数据库时都能清除的单独结构(队列)?只要你存储指针,它就不会使用更多的内存。这让我...而不是使用指针你应该看看智能指针(例如boost's shared_ptr),它可以让你传递它们而不用担心所有权。
答案 1 :(得分:1)
A1。你最好用地图,这是一个为你查找的树。使用map和(假设你有正确的编译器)或hash_map(它做同样的事情,但查找机制不同)进行测试。它们针对不同类型的数据存储工作负载具有不同的性能特征。
A2。列表可能对你更好 - 推到前面,拉出结束。 (也可以使用deque,但是如果你从中删除它就不能保留迭代器,你可以使用列表)。 push_back和pop_front(反之亦然)将允许您保留缓存数据的滚动队列。
A3。您可以尝试SQLite,这是一个专为简单的应用程序级数据库存储需求而设计的迷你数据库。它也可以工作entirely in-memory。