Maison  >  Questions et réponses  >  le corps du texte

Moyen efficace de remplir les valeurs manquantes dans une carte non ordonnée à partir d'une table SQL (SQL/C++)

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 。已删除数据集的 ids 不再在任何地方使用。这不可避免地会导致 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

. Cela s'applique exactement à la quantité 1

. 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

J'ai également réfléchi à des moyens d'interroger la liste des identifiants gratuits dans un vecteur et de les utiliser comme

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 momi 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 的表,其中包含 iddataset 列,均为 32 位带符号 INT。如何在 id 列中找到一系列间隙?例如,当表中的 id .

Supposons que j'ai une table appelée userdata qui contient des colonnes

et 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. 🎜
P粉476547076P粉476547076179 Il y a quelques jours360

répondre à tous(1)je répondrai

  • P粉252423906

    P粉2524239062024-04-05 00:12:20

    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 place 64bit 类型而不是 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.

    répondre
    0
  • Annulerrépondre