2009-08-03 7 views
0

Disons que j'ai un ensemble de données où chaque ligne est une paire de coordonnées: (X, Y). Associé à chaque point, j'ai des métadonnées arbitraires, telles que {color: yellow} ou {age: 2 years}. J'aimerais pouvoir stocker les données et les métadonnées de telle sorte que je puisse interroger les métadonnées (par exemple: [rows where {age: 2 years, color: yellow}]) et recevoir en retour toutes les rangées de coordonnées correspondantes.Stocker des données et effectuer une recherche par métadonnées?

Il n'existe aucune colonne ou valeur de métadonnées prédéfinie et toutes les lignes de coordonnées n'ont pas nécessairement les mêmes colonnes de métadonnées. Quel serait le meilleur moyen de stocker ces données pour l'accès le plus rapide? Serait-il possible d'utiliser quelque chose comme Tokyo Cabinet (sans Tokyo Tyrant) ou SQLite, ou y a-t-il une meilleure option?

+0

Les données sont-elles d-only, read-most ou est-ce que la performance en écriture est également importante? Combien de données avez-vous? Quelle est la quantité typique et la sélectivité des prédicats? Ce sont tous des facteurs importants si vous voulez de meilleures performances. Mais essayez quelque chose de simple comme SQLite d'abord, il pourrait être assez bon. –

Répondre

2

Toute base de données relationnelle devrait être capable de gérer quelque chose comme ça (vous alliez simplement faire une jointure entre deux tables, une pour les données et une pour les métadonnées). SQLite devrait fonctionner correctement.

Votre première table aurait les données elles-mêmes avec un ID unique pour chaque entrée. Ensuite, votre deuxième table aurait quelque chose comme 3 colonnes de travail: clé de métadonnées, valeur de métadonnées et identifiant d'entrée associé.

Exemple table de données:

ID Data 
-------- 
1 (1,1) 
2 (7,4) 
3 (2,3) 

table de métadonnées Exemple:

ID  Key   Value 
-------------------------- 
1  "color"  yellow 
1  "age"  3 
2  "color"  "blue" 
2  "age"  2 
3  "color"  "blue" 
3  "age"  4 
3  "loc"  "usa" 

Alors si vous voulez rechercher tous les points de données avec un âge d'au moins 3, vous utiliseriez une requête comme ceci:

SELECT * from datatable WHERE datatable.ID = metadatatable.ID AND metadatatable.Key="age" AND metadatatable.Value >= 3 
+0

Comment feriez-vous une recherche pour plusieurs conditions? Par exemple, comme mentionné dans mon message d'origine: [toutes les lignes de coordonnées où âge = 2 et couleur = bleu] –

+0

Vous utiliseriez l'opérateur INTERSECT. – Amber

+0

http://www.techonthenet.com/sql/intersect.php pour la syntaxe. – Amber

0

Comme les colonnes ne sont ni prédéfinies ni cohérentes sur toutes les lignes, vous devez soit aller avec des implémentations de type BigTable tels que Google AppEngine (modèles exapndo w/ListProperty) ou cassandra/HBase etc. (voir http://en.wikipedia.org/wiki/BigTable)

Pour les implémentations simples à l'aide sqlite vous pouvez créer un champ de chaîne formatée comme

f1 | f2 | metadata as string 
x1 | y1 | cola:val-a1 colb:val-b1 colc:val-c1 
x2 | y2 | cola:val-a2 colx:val-x2 

and use SELECT * from table WHERE metadata like "%cola:val-a2%" 
1

En utilisant le schéma de @ Dav, un moyen d'obtenir "[toutes les rangées de coordonnées où age = 2 et color = blue]" est (en supposant que (ID, Key, Value) est Unique en métadonnées, c.-à-d. :

SELECT datatable.Data 
    FROM datatable 
    JOIN metatadatable AS m USING(ID) 
    WHERE (m.Key="age" AND m.Value=2) 
    OR (m.Key="color" AND m.Value="blue") 
    GROUP BY datatable.ID, datatable.Data 
    HAVING COUNT()=2 
Questions connexes