2011-02-03 2 views
1

Donc, j'ai cette drôle d'exigence de créer un index sur une table uniquement sur un certain ensemble de lignes.Créer un index seulement sur certaines lignes dans mysql

C'est ce que ma table ressemble:

UTILISATEUR: userid, friendID, créé, blah0, blah1, ..., blahN

Maintenant, je voudrais créer un index:

(ID utilisateur, friendID, créé)

mais seulement sur les lignes où userid = friendid. La raison en est que cet index ne sera utilisé que pour satisfaire les requêtes où la clause WHERE contient "userid = friendid". Il y aura beaucoup de lignes où ce n'est PAS le cas, et je ne veux vraiment pas gaspiller tout cet espace supplémentaire sur l'index. Une autre option serait de créer une table (table de requête) qui est remplie à l'insertion/mise à jour de cette table et de créer un déclencheur pour le faire, mais encore une fois je suppose qu'un index sur cette table signifierait que les données seraient être stocké deux fois.

Comment mysql stocke-t-il les clés primaires? Je veux dire, est-ce que la table est commandée sur la clé primaire ou est-elle ordonnée par ordre d'insertion et le PK est comme un index unique normal?

J'ai vérifié sur les index cluster (http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html), mais il semble que seul InnoDB les supporte. J'utilise MyISAM (je mentionne cela parce que j'aurais pu créer un index clusterisé sur ces 3 champs dans la table de requête).

Je cherche essentiellement quelque chose comme ceci:

ALTER UTILISATEURS DE TABLE ADD INDEX (userid, friendID, créé) OÙ userid = friendID

+0

Apparemment, mon exigence n'est pas si drôle après tout. db.cs.berkeley.edu/papers/ERL-M89-17.pdf – dhruvbird

Répondre

3

En ce qui concerne l'indice conditionnel:

Vous ne pouvez pas faire cela. MySQL n'a rien de tel.

En ce qui concerne la clé primaire:

Cela dépend du moteur de stockage. MySQL ne définit pas comment les données sont stockées ou récupérées, cela dépend du moteur de stockage. MyISAM n'applique aucun ordre sur la façon dont les lignes sont stockées;

ils sont ajoutés à la fin de la table mais les interruptions de la suppression peuvent être réutilisées et les requêtes UPDATE peuvent laisser les choses dans le désordre même sans s. InnoDB stocke les rangées dans l'ordre de leurs clés primaires.

+0

Un indice basé sur la fonction pourrait, mais MySQL ne le supporte certainement pas. –

+0

Merci! Tout hack/approximation que vous connaissez peut-être? – dhruvbird

+0

@OMG ponies: Connaissez-vous un DB qui supporte les index fonctionnels? – dhruvbird

0

difficile de dire ce que vous essayez réellement de faire ici (pourquoi un utilisateur aurait besoin d'être son propre ami?) Mais il me semble qu'un simple repenser le schéma de votre base de données résoudrait ce problème.

table 1: USER: utilisateur, créé, blah0, blah1, ...,

Tableau 2: userIsFriend (user1, user2, ...)

et juste faire votre indexation sur la table 2 (dont les éléments ont probablement contrainte de clé étrangère sur la table 1)

BTW vous devriez probablement utiliser InnoDB si vous voulez faire quelque chose de semi-sérieux avec mySQL de toute façon, à mon humble avis.

+0

La table USERS n'était qu'un exemple. En outre, il existe des cas valides où vous voudriez une ligne d'identité dans votre base de données pour une telle table de toute façon (un utilisateur est son propre ami). – dhruvbird

+0

En ce qui concerne InnoDB, je n'utilise pas de transactions, donc je ne veux pas en payer le prix. – dhruvbird

Questions connexes