2010-10-21 16 views
0

J'ai une table où je stocke les commentaires pour les utilisateurs utilisateurs. J'aurai 100 millions + de commentaires.Table de base de données PK

2 façons je peux créer:

Option 1: nom d'utilisateur et l'identifiant de commentaire comme PK. De cette façon, tous les commentaires sont stockés physiquement par nom d'utilisateur et identifiant de commentaire. Avantages: Ma requête obtiendra tous les 10 meilleurs commentaires pour une commande d'utilisateur par comment_id DESC. Ceci est SEEK

Option 2: Je peux faire l'id de commentaire comme PK. Cela va stocker les commentaires triés par l'identifiant du commentaire, pas par le nom d'utilisateur. Inconvénients: Obtenir les derniers commentaires du top 10 d'un utilisateur donné n'est plus une recherche, car les données ne sont pas stockées par l'utilisateur (c'est-à-dire non triées par l'utilisateur). Je dois donc créer un autre index pour améliorer les performances de la requête.

Quelle est la meilleure façon de procéder? Qu'en est-il de l'insertion et de la suppression? Ces opérations sont autorisées. Mais lire est fréquent.

L'utilisateur ne peut pas modifier ses commentaires.

J'ai testé les deux tables avec des rangées de 1,1M. Voici le résultat:

table_name rows  reserved data  index_size unused 
comments2 1079892  99488 KB 62824 KB 36576 KB 88 KB (PK: com_id Second Index on (user_name, com_id)) 
comments1 1079892  82376 KB 82040 KB 328 KB  8 KB (PK: user_name, no other indices) 
-------------------------------------------------------------------- 
diff:  same rows 17112KB  -19216KB 36,248KB 80KB 

Ainsi, la table avec com_id comme PK utilise 36 Mo d'espace disque supplémentaire juste pour l'index 2 La sélection de requête principale à la fois table à l'aide SEEK, mais table avec com_id PK est plus lent Mais l'insertion est légèrement plus rapide quand j'ai com_id comme PK

Un commentaire?

+0

Pour la table comments2, essayez PK = com_id desc, Index = nom_utilisateur asc (n'incluez pas com_id dans l'index non-PK). – ulty4life

Répondre

2

J'utiliserais l'ID de commentaire comme clé primaire pour la table. Si vous avez beaucoup de requêtes qui utilisent l'ID de commentaire et le nom d'utilisateur, il est probablement plus simple d'ajouter un index dans ces champs.

+0

Quelle option sera la meilleure pour l'insertion et la suppression? – kheya

+0

quelqu'un a supprimé les commentaires de marc? – kheya

+0

Le seul moyen sûr de savoir à coup sûr dans votre environnement est de l'essayer dans les deux sens et de voir. Cependant, je suis d'accord que mon premier choix serait de faire de l'ID de commentaire la clé primaire, ils ont un index séparé dédié à faire aller les 10 derniers commentaires d'un utilisateur plus rapidement (peut-être un index basé sur les colonnes com_posted_by/com_posted_on). Vous avez plus de lectures que d'écritures dans votre scénario, donc le peu d'overhead (en termes de création de données d'index sur insert) est petit comparé aux gains que vous obtiendrez des récupérations (qui se produisent beaucoup plus de fois) – RQDQ

0

Je n'utiliserais pas de nom d'utilisateur dans un PK car il pourrait changer, créant des problèmes de mise à jour en cascade plus tard. En outre, concaténant ces deux dans le PK crée un PK (r) important qui pourrait devoir être passé à d'autres tables en tant que FK. J'essaie de garder PK qui apparaissent comme FK aussi petit que possible, à moins que je sache que je veux tout le PK des tables contribuant dans une grande clé pour la vitesse de la requête. Le commentaire id devrait convenir. Vous devrez peut-être créer un index supplémentaire pour une recherche rapide sur l'ID de commentaire et le nom d'utilisateur. Ferez-vous plus d'insertions/mises à jour ou requêtes? Si l'interrogation est intensive, l'index n'est pas un problème. Etes-vous sûr que cette instruction CREATE TABLE est correcte?

+0

nom d'utilisateur ne changera jamais.Le PK n'est pas utilisé un FK de l'autre table.il ya un coût d'avoir un autre index.Chaque insert \ supprimer nécessiterait la modification de l'autre index.Plus 2ème indice coûtera l'espace disque aussi – kheya

+0

insertion \ suppression est beaucoup moins commun que la sélection \ trouver des commentaires de l'utilisateur spécifique – kheya

+0

résultat de test affiché dans la question ci-dessus – kheya

0

Etes-vous sûr que cette instruction CREATE TABLE est correcte? Vous utilisez [Channel] dans la définition PK, et je ne vois pas cela comme une colonne. Vouliez-vous dire [utilisateur].

Avez-vous une table utilisateur quelque part? Si c'est le cas, vous pouvez économiser beaucoup de frais généraux en tapant cela sur une valeur entière et en plaçant UserID dans la table des commentaires, plutôt que User.

Je voudrais PK sur le CommentID, puis ajouter un index non-cluster sur [UserID, CommentID]. Cela vous donne un accès immédiat à un commentaire par ID (pour la suppression, etc) sans avoir à impliquer la valeur UserID dans la clause WHERE; et il fournit un accès rapide aux commentaires de l'utilisateur. Cependant, je n'ai pas tendance à travailler avec une table de la taille que vous prévoyez.

+0

Larry, Vous avez raison. J'ai renommé la table en commentaires. – kheya

+0

J'ai une autre table où je stocke les utilisateurs avec 20 caractères nom d'utilisateur comme PK – kheya

+0

S'il vous plaît envisager de stocker le nom d'utilisateur dans ce tableau joint à un nombre entier PK à la place. Vous économiserez beaucoup de frais généraux d'indexation dans votre tableau de commentaires. –

0

En règle générale, choisissez toujours le PK le plus étroit. Ensuite, pour améliorer les performances, vous pouvez utiliser un User_id basé sur un nombre entier, au lieu d'un varchar, et ajouter un index pour les deux colonnes. La meilleure approche dépendra du nombre d'utilisateurs, si vous n'avez que quelques utilisateurs, commet_id user_id pk pourrait être mieux (en plus, parttition par utilisateur serait une option); d'un autre côté, si le nombre d'utilisateurs est élevé, un Pk combiné sera inutile.

+0

posté le résultat du test dans la question – kheya

0

Mon approche initiale serait de faire en sorte que CommentaireID soit le PK, peut-être dans l'ordre décroissant afin que vous n'ayez pas à réorganiser le select. Ensuite, mettez un index sur UserID.

Si vous utilisez la clé concaténée, pensez à commuter CommentID à desc.

+0

posté le résultat du test dans la question – kheya