Nous sommes en cours d'exécution d'une base de données soutenu application web pour l'analyse des données, fondées sur des C#.NET avec EntityFramework sur le serveur, et principalement en HTML+Javascript côté client (basé sur le web).
Notre application reçoit régulièrement la mesure X/Y points de données groupées en grandes quantités, c'est à dire 1e6 ou plus, téléchargées par les utilisateurs ou reçus par d'autres infrastructures.
Actuellement, nous avons un tableau dans MSSQL appelé Values
avec id, series_id as int; x, y, z as float
. Ce tableau est BULK INSERT
rempli avec des données lorsqu'un client télécharge, et les métadonnées sont enregistrées dans un Series
table. Le total de la db taille est actuellement en approchant de 1 to, 99,99% des qui est Values
les données.
Cette approche a été simple à mettre en œuvre, mais il a plusieurs inconvénients qui ont fait qu'il est compliqué et lent au fil du temps:
- nous avons à insérer dans les morceaux pour ne pas surcharger le processus IIS qui prétraite il (actuellement 200'000 points de données par morceau)
- Processus IIS besoins en mémoire au cours de l'INSERT sont énorme (>1500MB pour 200 mo de données)
- l'insertion est beaucoup trop lent (5 millions de dossiers sont de 100 mo, ce qui prend plus de 30 secondes pour insérer même à l'aide de l'instruction BULK INSERT)
- pendant INSÉRER l'ensemble de la table est verrouillée, c'est à dire un seul utilisateur peut insérer à un moment
- la récupération des données est également très lent, de demander 1e6 enregistrements prend parfois plus de 10 secondes
- la suppression de la série avec >1e6 enregistrements cause régulièrement des délais d'attente sur l'application web côté.
Les données ne sont jamais partiellement sélectionné, de sorte que nous n'avons pas vraiment besoin de l'avoir dans une table. MAIS il est "éclaircis" pour afficher avant envoi aux clients, c'est à dire 1e6 dossiers sont, par défaut, c'est à dire dans 99% des cas d'utilisation - réduit à 2000 ou 10'000 enregistrements avant de les envoyer au client. Ceci est mis en cache sur le client, mais si un nouveau client demande le même ensemble, il est traité à nouveau. Les Valeurs de la table a également un indice sur series_id
ce qui prend le plus d'espace disque que la table elle-même.
Je me demande s'il ne serait pas judicieux de changer ce format de stockage pour un stockage BLOB dans les "Valeurs" avec son propre format de données au format CSV (ou JSON ou binaire), et - peut-être - colonnes supplémentaires avec prétraitées "réduite" des ensembles de données pour l'affichage qui peut être poussé à des clients sans changement (par exemple. en JSON). Ainsi, le nouveau Values
format de tableau serait quelque chose comme
id, series_id, data(blob), reduced_data(blob)
et il y en avait juste un Value
par Series
entrée, pas 1e6 ou plus. Le jeu de données réduit sera créé une fois lors du téléchargement de données est reçu et ensuite utilisé pour l'affichage de la demande des clients, il
Je vais perdre partielle choisit de values
par ID ou X/Y de la valeur, mais les Valeurs ne sont jamais Sélectionnés sur la base de rien d'autre que id
ou series_id
c'est donc actuellement pas une limitation. Voici donc mes questions:
- Cela fait-il sens? J'attends la création et la suppression d'un grand BLOB jeu de données pour être toujours nettement plus rapide que la création et la suppression de 1 000 000 d'enregistrements unique. Vrai?
- BLOB binaire ou CSV/JSON/.. BLOB? L'approche la plus simple pour le stockage BLOB est bien sûr la création d'un immense CSV ou JSON morceau et enregistrer (éventuellement gzippé) dans la base de données. Une coutume format de données binaire serait encore plus petite, mais elle devrait être converti en JSON avant d'être envoyées aux clients.
J'ai un sentiment supplémentaire de tracas à venir avec des formats de données binaires peuvent ne pas être en vaut la peine et c'est mieux pour gzip le CSV/JSON blob que de s'inventer un format binaire. Vrai?
Comment sur les autres inconvénients de Gouttes que je ne peut même pas être au courant? Les limites de la taille ne semble pas être un problème, varbinary(MAX)
est suffisante. Je n'ai pas besoin d'un index sur les valeurs à l'intérieur de la goutte, juste sur les métadonnées (qui est dans la Série de table).
Pensées?