2010-12-07 3 views
2

J'ai le sentiment que cela a déjà été répondu, mais je ne connais pas la bonne terminologie et je n'ai rien trouvé dans ma recherche.Réduire la redondance des données pour le stockage dans MySQL

Je travaille sur un système de recommandation de produits. Et j'ai une base de données d'éléments, et je suis en train de déterminer quels éléments sont similaires. Par exemple ItemID 1 est similaire à 5, 7 et 8. Le problème est que les données sont redondantes. En boucle I à l'ensemble complet de l'article que je finirai avec quelque chose comme ceci:

1 5,7,8
5 7,8,1
7 8,5,1
8 5,1 Quelle est la meilleure façon de stocker cela dans MySQL, donc je peux l'interroger et trouver les éléments liés à 1, 5, 7 ou 8. Dans la vraie vie, il y aura un nombre impair d'éléments dans chaque ensemble. Je suis préoccupé par la vitesse plus que l'espace de stockage, mais il semble qu'il devrait probablement y avoir un juste milieu, ou si j'ai de la chance, c'est rapide et économiser de l'espace.

Répondre

1

C'est ce qu'on appelle une "structure de données graphiques". Les nombres (1,5,7,8) sont les noeuds. Chaque connexion (1-5,1-7,1-8,5-7, etc.) sont les bords.

http://en.wikipedia.org/wiki/Graph_(data_structure)

MySQL, vous devez stocker les bords comme un bord par ligne. Si chaque arête se connecte dans les deux sens, vous devez ajouter chaque arête dans les deux directions (par exemple 1-5 et 5-1). Je configuration la table quelque chose comme ceci:

TABLE edges (
    id PRIMARY KEY AUTO_INC, 
    from INT, 
    to INT 
) 

Vous voulez un index sur (de), ou peut-être (de, à) en fonction. Pour trouver tous les objets liés à celui que vous cherchez à:

SELECT to FROM edges WHERE from = X; 

Un grand nombre des améliorations pourraient être apportées à ce modèle simple, mais il est un début. Editer: Peut-être que certains de ces noms de colonnes sont des mots clés. Ma faute.

1

Plutôt qu'une colonne pour l'élément et une autre colonne pour une liste de ce qui est similaire, ce qui entraîne chaque élément ayant une ligne dans la table, considérez stocker chaque paire (source, destination) dans une ligne distincte.

Au lieu de (1, {5,7,8}), (5, {7,8,1}) vous auriez (1, 5), (1, 7), (1, 8), (5, 7), (5, 8), (5, 1). Ensuite, pour voir quels éléments sont similaires à l'élément 8, vous devez simplement sélectionner source où destination = 8.

+0

+1 Bonne réponse. Bienvenue à SO Charley! –

1

Chris a raison et tort en même temps. Il a raison de dire qu'il s'agit d'une «structure de données graphiques», mais omet de mentionner que son approche vous obligerait à vous retrouver dans plusieurs sous-requêtes pour trouver un graphique.

S'il vous plaît faites-vous plaisir et jetez un oeil au modèle Nested Set. Vous pourriez vouloir vous diriger vers le MySQL manual pour vous aider à démarrer.

Cordialement

+1

c'est une solution flexible, mais je ne sais pas si cela s'applique bien à seulement besoin d'un niveau d'imbrication comme c'est ce que je comprends de ce post. sauf que c'est définitivement plus rapide pour obtenir des catégories n-tier, cependant. Ayant fait cela avant, il faut aussi un certain degré d'entretien pour être sûr que l'arbre. J'aime [ceci] (http: //articles.sitepoint.com/article/hierarchical-data-database) pour un exemple peut-être plus réaliste ou comment/pourquoi vous utilisez cette solution. – zanlok

+0

Ya, c'est seulement un niveau profond, donc sa solution fonctionne bien. – profitphp

Questions connexes