Meilleur moyen (gratuit) de stocker des données? Qu'en est-il des mises à jour du système de fichiers?

StackOverflow https://stackoverflow.com/questions/142114

  •  02-07-2019
  •  | 
  •  

Question

J'ai une idée de la façon de résoudre ce problème, mais je voulais savoir s'il y avait quelque chose de plus facile et plus extensible à mon problème.

Le programme sur lequel je travaille a deux formes de données de base: les images et les informations associées à ces images. Les informations associées aux images ont déjà été stockées dans une base de données JET d’une extrême simplicité (quatre tables), ce qui s’est avéré à la fois lent et incomplet dans les champs stockés. Nous passons à une nouvelle implémentation du stockage de données. Étant donné la simplicité des structures de données impliquées, je pensais qu’une base de données était excessive.

Chaque image possède ses propres informations (paramètres de capture), fait partie d’un groupe d’images interdépendantes (prises dans la même période de trente minutes, par exemple), puis fait partie d’un groupe plus important (prise de la même personne). En ce moment, je stocke les gens dans un dictionnaire avec un identifiant unique. Chaque personne dispose alors d'une liste des différents groupes d'images et chaque groupe d'images d'une liste d'images. Toutes ces classes sont sérialisables et je ne fais que sérialiser et désérialiser le dictionnaire. Des choses assez simples. Les images sont stockées séparément afin que le dictionnaire ne devienne pas astronomique.

Le problème est le suivant: que se passe-t-il lorsque je dois ajouter de nouveaux champs d'information? Existe-t-il un moyen simple de configurer ces structures de données pour tenir compte des révisions potentielles futures? Auparavant, je gérais cela en C: créer une structure sérialisable avec beaucoup d'octets vides (au moins un k) pour une extensibilité future, l'un des octets de la structure indiquant la version. Ensuite, lorsque le programme lirait la structure, il saurait quelle désérialisation utiliser en se basant sur une instruction switch massive (et les anciennes versions pourraient lire de nouvelles données, car les données superflues entreraient simplement dans des champs ignorés).

Un tel schéma existe-t-il en C #? Par exemple, si j'ai une classe qui est un groupe d'objets String et Int et que j'ajoute un autre objet String à la structure, comment puis-je désérialiser un objet à partir du disque et y ajouter la chaîne? Dois-je me résigner à avoir plusieurs versions des classes de données et une fabrique qui prend un flux de désérialisation et gère la désérialisation en fonction de certaines informations de version stockées dans une classe de base? Ou bien une classe comme Dictionary est-elle idéale pour stocker ce type d'informations, car elle désérialisera automatiquement tous les champs sur le disque, et si de nouveaux champs sont ajoutés, je peux simplement intercepter des exceptions et substituer ces valeurs à Strings et Ints vierges?

Si j'utilise l'approche du dictionnaire, y a-t-il un impact rapide associé aux lectures / écritures de fichiers ainsi qu'aux temps de récupération des paramètres? Je suppose que s'il n'y a que des champs dans une classe, la récupération de champ est instantanée, mais dans un dictionnaire, il existe une petite surcharge associée à cette classe.

Merci!

Était-ce utile?

La solution

Mon cerveau est frit pour le moment, je ne suis donc pas sûr de pouvoir vous conseiller pour ou contre une base de données, mais si vous recherchez une sérialisation agnostique en version, vous seriez fou de ne pas au moins vérifier tampons de protocole .

Voici une liste rapide des implémentations que je connais pour C # /. NET:

Autres conseils

SQLite est ce que vous voulez. Il s'agit d'une base de données rapide, intégrable, à fichier unique, qui relie la plupart des langues.

En ce qui concerne l'extensibilité, vous pouvez stocker vos modèles avec des attributs par défaut, puis créer un tableau séparé pour les extensions d'attributs en vue de modifications ultérieures.

Un an ou deux plus tard, si le code est toujours utilisé, vous serez heureux que 1) les autres développeurs n'aient pas à apprendre une structure de code personnalisée pour gérer le code, 2) vous pouvez exporter, Affichez, modifiez les données avec des outils de base de données standard (il existe un pilote ODBC pour les fichiers sqlite et divers outils de requête), et 3) vous pourrez passer à une base de données avec un minimum de modifications de code.

Juste un petit mot d’avertissement, SQLLite, Protocol Buffers, mmap, etc. / p>

La simplicité peut consister simplement à passer à SQL (Express) (vous serez peut-être surpris par le gain de performance) et à corriger tout ce qui manque dans la conception actuelle de la base de données. Ensuite, si le problème persiste, commencez à explorer ces autres technologies.

Il existe un schéma de base de données, dont je ne me souviens plus du nom, qui peut gérer ce type de situation. Vous avez essentiellement deux tables. Une table stocke le nom de la variable et l'autre stocke la valeur de la variable. Si vous souhaitez regrouper les variables, ajoutez une troisième table avec une relation un à plusieurs avec la table de noms de variables. Cette configuration présente l’avantage de vous permettre d’ajouter sans cesse différentes variables sans avoir à modifier constamment le schéma de votre base de données. Mon bacon m’a sauvé plusieurs fois lorsque je traite avec des départements qui changent souvent d’avis (comme le marketing).

Le seul inconvénient est que la table des valeurs de variable devra stocker la valeur réelle sous forme de colonne de chaîne (varchar ou nvarchar en fait). Ensuite, vous devrez gérer les difficultés liées à la conversion des valeurs en leurs représentations natives. Je maintiens actuellement quelque chose comme ça. La table de variables contient actuellement environ 800 millions de lignes. C'est encore assez rapide, car je peux toujours récupérer certaines variations de valeurs en moins d'une seconde.

Je ne suis pas un programmeur C #, mais j'aime bien l'appel de mmap () et j'ai vu qu'il y a un projet qui fait de même pour C #.

Voir carte .

  

Les fichiers structurés sont très performants s'ils sont adaptés à une application spécifique, mais ils sont difficiles à gérer et constituent une ressource de code difficilement réutilisable. Une meilleure solution est une implémentation de type mémoire virtuelle.

     
      
  • Jusqu'à 4 gigaoctets d'informations peuvent être gérés.
  •   
  • L'espace peut être optimisé à la taille réelle des données.
  •   
  • Toutes les données peuvent être visualisées sous forme de tableau unique et accédées à l'aide d'opérations de lecture / écriture.
  •   
  • Pas besoin de structurer pour stocker mais simplement d’utiliser et de stocker.
  •   
  • Peut être mis en cache.   Est hautement réutilisable.
  •   

Allez donc avec sqllite pour les raisons suivantes:
1. Vous n'avez pas besoin de lire / écrire toute la base de données à partir du disque à chaque fois
2. Il est beaucoup plus facile d'ajouter à même si vous ne laissez pas assez d'espaces réservés au début
3. Plus facile à rechercher en fonction de tout ce que vous voulez
4. plus facile de modifier les données d'une manière qui dépasse la conception de l'application

Problèmes liés à l'approche du dictionnaire
1. Sauf si vous avez créé un dictionnaire intelligent, vous devez lire / écrire l'intégralité de la base de données à chaque fois (sauf si vous concevez soigneusement la structure de données, il sera très difficile de maintenir une compatibilité ascendante)

----- a) si vous n'avez pas laissé assez de titulaires de place au revoir

2. Il semble que vous deviez effectuer une recherche linéaire dans toutes les photos afin de rechercher l'un des attributs de capture.
3. Une image peut-elle être dans plus d'un groupe? Une image peut-elle être sous plus d'une personne? Deux personnes peuvent-elles être dans le même groupe? Avec les dictionnaires, ces choses peuvent devenir poilues ....

Avec une table de base de données, si vous obtenez un nouvel attribut, vous pouvez simplement dire Modifier l'image de la table et ajouter un attribut DataType. Ensuite, tant que vous ne créez pas de règle indiquant que l'attribut doit avoir une valeur, vous pouvez toujours charger et enregistrer des versions plus anciennes. Dans le même temps, les nouvelles versions peuvent utiliser les nouveaux attributs.

De plus, vous n'avez pas besoin de sauvegarder l'image dans la base de données. Vous pouvez simplement stocker le chemin d'accès à l'image dans la base de données. Ensuite, lorsque l'application a besoin de l'image, chargez-la simplement à partir d'un fichier disque. Cela réduit la taille de la base de données. De plus, le temps de recherche supplémentaire nécessaire pour obtenir le fichier sur disque sera probablement insignifiant par rapport au temps de chargement de l'image.

Votre table devrait probablement être
Image (PictureID, GroupID ?, Chemin du fichier, Paramètre de capture 1, Paramètre de capture 2, etc.)

Si vous voulez plus de flexibilité, vous pouvez créer un tableau. CaptureParameter (PictureID, ParameterName, ParameterValue) ... Je vous le déconseille car il est beaucoup moins efficace que de les mettre dans une seule table (sans parler des requêtes permettant d'extraire / de rechercher les paramètres de capture, ce serait plus compliqué).

Person (PersonID, attributs Any Person tels que Name / Etc.)
Group (GroupID, Nom du groupe, PersonID?)
PersonGroup? (PersonID, GroupID)
PictureGroup? (GroupID, PictureID)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top