2009-08-11 9 views
1

J'ai une table "colors" dans ma base de données.Enregistrer des distances dans MySQL

L'utilisateur saisit une couleur dans l'interface utilisateur et le moteur recherche la couleur la plus similaire existant dans la table de couleurs, calculant la distance des couleurs dans l'espace HCL.

Je vais mettre en œuvre un algorithme de mise en cache, qui devrait stocker la distance entre les distances de couleur précédemment calculées, pour éviter les opérations mathématiques répétées. Quelle est la meilleure disposition de table à cette fin?

+0

Comment stockez-vous une couleur? Comme un triple d'entiers? Voulez-vous mettre en cache la distance entre les distances? Comment définiriez-vous cette distance? Ou cachez simplement les distances entre les couleurs? –

+0

La couleur est stockée comme ceci [: id,: nom,: rouge,: vert,: bleu] La distance est un nombre décimal. Je vais seulement mettre en cache les distances entre les couleurs – astropanic

+0

Quelle est votre contribution à la requête? Si vous pouvez stocker les données de manière à pouvoir les interroger directement avec votre saisie, ce serait la solution la plus simple. – Makis

Répondre

3

Comme Osama dit, cela ressemble à l'optimisation prématurée. D'après votre description de l'algorithme, je voudrais:

  • pré-calculer les vecteurs HCL pour toutes les couleurs dans la base de données et stocker une table qui associe un identifiant de couleur à son vecteur HCL.
  • La table doit être stockée en utilisant le MySQL Spatial Extensions, qui vous permet d'interroger les voisins d'un point.
  • Lorsqu'une nouvelle couleur est choisie, transformez-la en HCL et interrogez les voisins de son point dans l'espace HCL.
  • Si la mise en cache est nécessaire, je mettrais en cache les couleurs à grain grossier, de sorte qu'il y a des chances que les utilisateurs reviennent sur une couleur précédemment sélectionnée.
0

Je ne connais pas trop le langage HCL, mais d'après la description de Color::Similarity::HCL, il semble que deux couleurs soient nécessaires pour la distance.

Donc, je pense qu'au moins deux ensembles de RVB et la distance entre eux doivent être stockés. Je ne suis pas sûr de votre cas d'utilisation, mais si la plage de choix est sélectionnée, vous pouvez également stocker la sélection de l'utilisateur.

Il semble qu'il n'y aurait qu'un nombre fini de combinaisons? Il semble que vous pourriez faire le calcul une fois pour chaque combinaison, et juste avoir une table de recherche?

+0

Vous avez mal compris ma question. Devrais-je placer les deux color_ids et la distance entre eux dans une rangée? ou placer les distances et les couleurs dans une table séparée? – astropanic

3

vous pouvez le faire:

table colors(r,g,b) 
table colordistance(user_r,user_g,user_b,r,g,b,distance) 

mais attendez-vous à vos utilisateurs de garder entrer les mêmes chiffres ??? Le nombre maximal de lignes dans cette table est 16777216 si vous incluez uniquement la couleur la plus proche. Je suspecte toujours que l'accès à la base de données est plus lent que le calcul, donc je pense à la citation "l'optimisation prématurée est la racine de tous les maux".

Je l'exécuterais sans mise en cache du calcul jusqu'à ce que je le vois comme un problème réel.

1

Je suppose que vos couleurs "distances" sont calculées quelque chose comme:

sqrt((r1-r2)^2 + (g1-g2)^2 + (b1-b2)^2) 

En supposant que vous utilisez 8 pixels de bits, il y aurait (256^3)^2 correspondances distinctes dans votre table. C'est beaucoup d'espace de table. (Vous pouvez probablement compacter beaucoup, mais ... voir le point suivant.)

L'autre chose que vous devez considérer est le coût d'une recherche de base de données pour trouver une distance de couleur par rapport au coût de faire le calcul. Ma conjecture serait qu'une consultation de base de données prendrait une milliseconde ou plus, mais le calcul de métrique devrait prendre 1 microseconde ou moins. Dans l'ensemble, l'utilisation d'une table de base de données semble être une très mauvaise idée pour moi.

0

Voici ce que je recommande:

table colors(color_id, color_name, r, g, b) 

table color_distances(color_1_id, color_2_id, distance) 

Index: primaire (color_1_id, color_2_id) INDEX (color_1_id, distance, color_2_id)

color_distances contiendraient toutes les combinaisons color_id possibles, et ne sera mis à jour au besoin.

Sélection serait alors simple:

Questions connexes