Question
Il existe actuellement un système d'identifiants uniques commençant par id
)及其附加数据集从 SQL 表读取到无序映射中。这些数据集过去以 id
1, mais l'ajout et la suppression d'ensembles de données prennent environ 10 millisecondes. Notez que tous les ensembles de données ne sont pas toujours chargés dans la RAM
Lorsque le programme démarre, il lit dans la base de données SELECT MAX(id)
,并继续向计数器变量添加 +1,该变量将用作任何添加的数据集的 id
。已删除数据集的 id
s 不再在任何地方使用。这不可避免地会导致 id
Il y a des lacunes dans la séquence et un jour elle débordera.
Je recherche un moyen performant pour combler le plus petit écart dans les valeurs id
. Également cohérent avec les tables SQL et la mémoire programme partiellement chargées. Les données en mémoire peuvent prendre plusieurs minutes ou immédiatement pour être enregistrées dans la table SQL.
Pensées
Une solution que j'ai trouvée consistait à effectuer une requête coûteuse sur chaque ensemble de données créé au moment de l'exécution pour trouver le plus petit écart dans la table SQL, à vérifier si cela id
是否作为无序映射中的值存在,然后再次使用来自计数器变量作为备份,以避免无休止地查询免费的 id
。这完全适用于 1 id
existe en tant que valeur dans la carte non ordonnée, puis à utiliser à nouveau le compteur des variables comme sauvegarde pour éviter des requêtes interminables gratuitement
. Ensuite, il reste libre dans SQL, mais est récupéré dans la carte non ordonnée jusqu'à ce que la mémoire soit à nouveau sauvegardée. id
,直到向量为空,然后(或经常)对更多 ID 进行新查询。但我想不出一个查询来查找表中 X 数量的间隙,该表可能有也可能没有以 1 开头的 id
pour de nouveaux ensembles de données jusqu'à ce que le vecteur soit vide, puis (ou souvent) de faire de nouvelles requêtes pour plus d'identifiants. Mais je ne peux pas penser à une requête pour trouver un nombre X de lacunes dans une table qui peut ou non avoir mo
和 mi
colonnes commençant par 1.
Je suis tombé sur Comment trouver des « lacunes » lors de l'exécution d'un compteur en utilisant SQL ? , mais j'ai deux problèmes avec la première réponse : apparemment, elle ne trouve qu'un seul espace, alors que j'ai besoin de beaucoup d'espaces, et je ne comprends pas son utilisation de userdata
的表,其中包含 id
和 dataset
列,均为 32 位带符号 INT。如何在 id
列中找到一系列间隙?例如,当表中的 id
.
Supposons que j'ai une table appelée userdata
qui contient des colonnes
dataset
, toutes deux des INT signés 32 bits. Comment trouver une série de lacunes dans une colonne 🎜 ? Par exemple, lorsque les 🎜 du tableau sont 1,6,7,9, je souhaite que la requête renvoie 2,3,4,5,8. 🎜
🎜Toute indication de solutions possibles serait également appréciée. 🎜
S'il y a un changement de base de données toutes les 10 millisecondes, cela représente 100 changements par seconde. Un
int
signé peut contenir environ 2 147 483 648 valeurs, soit 21 474 846 secondes, soit environ 8 mois. Après cela, il n’est plus possible de disposer d’un nouvel identifiant.La première solution consiste à utiliser le type
64bit
à la place64bit
类型而不是int
. Cela vous donne environ 13 600 ans (pour signé 64b), ce qui semble suffisant :)Une autre solution est d'avoir un vecteur contenant tous les identifiants possibles. Stockage vectoriel
bool
(ID utilisé/inutilisé). La demande d'un nouvel identifiant se fait en déplaçant le vecteur vers la première position marquée comme inutilisée.Ce vecteur utilise beaucoup de RAM, bien que std::vector ait une version spécifiquement pour bool qui nécessite moins de RAM.
La troisième solution consiste à stocker une liste chaînée (éventuellement doublement liée) d'identifiants supprimés (lire : réutilisables).
Lors de la demande d'un nouvel identifiant, la liste fournit son en-tête, ou la taille du tableau si la liste est vide.
Lorsqu'un ensemble de données est supprimé, son identifiant est correctement inséré dans la liste, la liste est donc toujours triée.
Lorsqu'un identifiant est réutilisé, il sera supprimé de la liste.
Supprimer le dernier enregistrement de la table peut également supprimer le dernier nœud de la liste puisqu'ils sont inutiles (ID de cas > taille de la table). C'est pourquoi je recommande d'utiliser une liste doublement chaînée afin que le dernier nœud puisse être supprimé rapidement.
Ainsi, la liste utilise rapidement « nouveau » et « supprimer » sur ses nœuds, et s'exécute également fréquemment de haut en bas (pour les liens doubles) pour insérer de nouveaux nœuds.
C'est un peu lent, mais j'espère que la liste n'est pas trop longue et que le temps requis n'est pas mauvais.
Notez également que cette liste vous donne l'éventail des lacunes dont vous avez besoin.