2010-01-10 3 views
0

J'ai une question à laquelle j'ai eu des conseils opposés, j'apprécierais des vues supplémentaires.MySQL: structure de table pour les "vues" d'un utilisateur

Mon site a des utilisateurs, chacun avec un user_id. Ces utilisateurs peuvent voir les produits et j'ai besoin de suivre les instances uniques des utilisateurs qui consultent des produits spécifiques. Pour enregistrer une vue dans une table de vue, puisque je l'ai eu actuellement deux options:

OPTION 1:

view_id (INT, PK) | user_id (INT, FK) | product_id (INT, FK) | view_date

... et de créer une contrainte unique sur les deux colonnes centrales pour une mise à jour facile avec la clé ON DUPLICATE. Si la même vue existe déjà, je mets juste à jour view_date. Sinon, j'écris une nouvelle ligne.

OPTION 2:

user_product (VARCHAR20, PK) | view_date

... fusionner les deux ID dans un VARCHAR avec un séparateur au milieu, et utiliser la colonne de clé primaire pour une mise à jour facile avec ON DUPLICATE KEY de la même manière que ci-dessus.

La structure doit pouvoir supporter jusqu'à env. millions de vues uniques. Des idées sur quelle option pourrait être meilleure ou pire, et pourquoi? Un grand merci d'avance.

EDIT: Merci pour les réponses, il semble y avoir un consensus. Était penché du même côté, mais avait juste besoin d'être rassuré.

Répondre

2

J'aime mieux la première option - en général, il est bon de maintenir autant d'atomicité que possible. Si vous voulez interroger toutes les vues d'un utilisateur, ou quelque chose comme ça, il serait plus difficile de le faire après avoir fusionné deux colonnes en une (vous devrez utiliser LIKE avec une correspondance générique, qui ne sera jamais aussi rapide que une colonne indexée à une seule valeur). Vous perdez également la possibilité d'indexer sur différents champs.

En outre, il n'y a aucune raison pour laquelle on ne pouvait pas avoir une clé primaire ou unique qui a impliqué plusieurs colonnes, donc je ne vois aucun avantage à l'option 2. Pour effectuer votre mise à jour, il suffit d'utiliser REPLACE (documentation) au lieu de INSERT - cela vous permet de conserver facilement votre invariant d'avoir une seule ligne par combinaison utilisateur/produit.

+0

Yep ... bien que ce soit mon comprendre que REPLACE "dépense" un ID INT d'auto-incrémentation (comme il s'agit de supprimer puis de réécrire), le type de données de la colonne PK devrait donc prendre en compte cela. – Tom

1

Je pense que la première option est votre meilleur choix. Plus tard dans la ligne, je pense que cela rendra l'interrogation de différentes choses un peu plus facile. Les requêtes seront probablement plus rapides car il n'y aura pas de manipulations de chaînes. En outre, vous pouvez avoir une clé primaire sur plusieurs colonnes si vous en avez besoin.

1

Certainement aller pour la première option. La deuxième option signifiera beaucoup de requêtes de l'enfer si vous devez créer des rapports pour rechercher des groupes particuliers d'utilisateurs (obtenez moi tous les utilisateurs qui voient souvent le produit X et le produit Y afin que nous puissions leur offrir un rabais) de produits (quels produits sont souvent consultés par les mêmes utilisateurs, afin que nous puissions lancer une promotion de réduction)

Je comprends qu'il n'est pas obligatoire de se souvenir de toutes les vues individuelles.Mais je capturerais certainement le nombre de fois qu'ils ont visité le produit - ceci est presque libre, car vous pouvez garder un total courant (insérer 1, sur la clef dupliquée update_count = view_count + 1)

+0

view_count ... merci, même si je n'en aurai pas besoin maintenant, je vais probablement l'ajouter, bon conseil. – Tom

Questions connexes