Nous concevons une application Android qui a beaucoup de données ("clients", "produits", "commandes" ...), et nous don ne veux pas interroger SQLite chaque fois que nous avons besoin d'un enregistrement. Nous voulons éviter d'interroger la base de données autant que possible, nous avons donc décidé de garder certaines données toujours en mémoire.Meilleure pratique pour conserver les données en mémoire et la base de données en même temps sur Android
Notre idée initiale est de créer deux classes simples:
"MemoryRecord": une classe qui contiendra essentiellement un tableau d'objets (string, int, double, datetime, etc ...), ce sont les données d'un enregistrement de table, et toutes les méthodes pour obtenir ces données dans/hors de ce tableau. "MemoryTable": classe qui contiendra essentiellement une carte de [Key, MemoryRecord] et toutes les méthodes pour manipuler cette Map et insérer/mettre à jour/supprimer des enregistrements dans/de la base de données.
Ces classes seront dérivées à chaque type de table que nous avons dans la base de données. Bien sûr, il existe d'autres méthodes utiles non énumérées ci-dessus, mais elles ne sont pas importantes à ce stade. Ainsi, au démarrage de l'application, nous chargerons ces tables d'une base de données SQLite en mémoire en utilisant ces classes, et chaque fois que nous aurons besoin de changer certaines données, nous changerons en mémoire et les publierons dans la base de données juste après. Mais, nous voulons de l'aide/des conseils de votre part. Pouvez-vous suggérer quelque chose de plus simple ou efficace pour mettre en œuvre une telle chose? Ou peut-être quelques classes existantes qui le font déjà pour nous?
Je comprends ce que vous essayez de me montrer, et je vous en remercie. Mais, disons que nous avons une table avec 2000 enregistrements, et j'ai besoin de lister ces enregistrements. Pour chacun d'entre eux, je dois interroger 30 autres tables (certaines avec 1000 enregistrements, d'autres avec 10 enregistrements) pour ajouter des informations supplémentaires dans la liste, et ce pendant qu'il "vole" (et comme vous le savez, nous devons être très rapides à ce moment là).
Maintenant, vous allez dire: "construisez simplement votre requête principale avec toutes ces" jointures ", et apportez tout ce dont vous avez besoin en une étape SQLite peut être très rapide, si votre base de données est bien conçue, etc. .. ".
OK, mais cette requête deviendra très compliquée et sûre, même si SQLite est très rapide, elle sera "trop" lente (2 à 4 secondes, comme je l'ai confirmé, et ce n'est pas un moment acceptable pour nous). Un autre complicateur est que, en fonction de l'interaction de l'utilisateur, nous devons "re-interroger" tous les enregistrements, car les tables impliquées ne sont pas identiques et nous devons "rejoindre" un autre ensemble de tables. Donc, une alternative est d'apporter seulement les enregistrements principaux (cela ne changera jamais, peu importe ce que fait ou veut l'utilisateur) sans jointure (c'est très rapide!) Et interroger les autres tables chaque fois que nous voulons des données. Notez que sur la table avec 10 enregistrements seulement, nous allons chercher les mêmes enregistrements plusieurs fois et plusieurs fois. Dans ce cas, c'est une perte de temps, car peu importe SQLite rapide, il sera toujours plus coûteux de faire des requêtes, des curseurs, des fetchs, etc ... que de simplement saisir l'enregistrement d'une sorte de "cache mémoire". Je tiens à préciser que nous n'avons pas l'intention de conserver toutes les données en mémoire, seulement quelques tables que nous interrogeons très souvent.
Et nous sommes arrivés à la question initiale: Quelle est la meilleure façon de "mettre en cache" ces enregistrements? J'aime vraiment centrer la discussion sur cela et non pas "pourquoi avez-vous besoin de mettre en cache des données?"
"Nous voulons éviter d'interroger autant que possible la base de données, nous avons donc décidé de conserver certaines données en mémoire." - avez-vous utilisé Traceview pour confirmer qu'il s'agit d'un problème pour votre application? "Nous voulons de l'aide/des conseils de votre part" - mon conseil est: prouver qu'il y a un problème en premier. Vous avez très peu de RAM avec laquelle travailler. Construire un grand cadre pour faire face à un problème inexistant serait un gaspillage d'efforts. Si vous avez démontré que c'est un problème, j'aimerais un pointeur sur l'article de blog où vous l'avez rédigé, car je suis toujours intéressé par les résultats des tests de performance. – CommonsWare
@CommonsWare: Je comprends votre point de vue et je suis entièrement d'accord avec vous. Mais, en tant que développeurs PalmOS et .NetCF, nous sommes déjà confrontés à ce problème auparavant. Dans PalmOS, toutes les données sont stockées dans la mémoire (.pdb) et il n'y a aucun problème de performance lors de l'obtention de données. D'un autre côté, dans WM, nous sommes confrontés au «problème», puis nous avons créé cette «solution» listée ci-dessus. Mais maintenant, sous Android, nous souhaitons faire de la "bonne manière". Nous voulons savoir si nous allons faire face à des problèmes de performances lorsque nous demandons à la base de données "à chaque fois". Nous avons donc décidé de demander des suggestions ici. Merci quand même. – Christian
"Nous voulons savoir si nous allons devoir faire face à des problèmes de performances lorsque nous demandons des bases de données à chaque fois" Nous avons donc décidé de demander des suggestions ici. " -- non tu ne l'as pas fait. Je voudrais que tu l'aies. Au lieu de cela, vous avez déclaré qu'un problème existait ("nous ne voulons pas interroger sqlite à chaque fois que nous avons besoin d'un enregistrement") et que vous vouliez de l'aide pour votre solution. Comme pour la plupart des plates-formes, la réponse à la question "si vous allez faire face à des problèmes de performances lors d'une requête de base de données" est "cela dépend des requêtes". Croyez-moi, juste parce qu'il y a un problème sur WM ne signifie pas le même problème existe ailleurs. Utilisez Traceview. – CommonsWare