J'ai des données volumineuses où je ne sélectionne qu'un petit intervalle de données à la fois de telle sorte que la sélection est toujours dans une séquence. J'essaie d'implémenter PostgreSQL comme l'index partiel dans MySQL qui est ciblé à de telles fins. Je ne sais pas si la contrainte unique partielle est la même que celle que je souhaite.
Code dans PostgreSQL 9.4
CREATE UNIQUE INDEX dir_events
ON events (measurement_id)
USING btree
(eventBody)
WHERE is_active;
Tentative sur l'index partiel de ypercube dans MySQL
CREATE UNIQUE INDEX dir_events
[index_type] -- TODO what here?
ON events (measurement_id, is_active)
[index_type] -- TODO what here?
Comment pouvez-vous créer un index partiel de type PostgreSQL dans MySQL 5.5 ou similaire?
is_active = TRUE
(ou n'a qu'une seule colonne, le PK dedir_events
).Réponses:
Ni MySQL ni les frères et sœurs (MariaDB, Drizzle, etc.) n'ont implémenté des index partiels.
Ce que vous pouvez faire, avec cette restriction à l'esprit:
a) faire un index simple (non partiel) sur
(is_active, measurement_id)
. Il sera utilisé dans les requêtes où l'index partiel le ferait. Bien sûr, si lais_active
colonne est vraie à 3% et fausse à 97%, cet index sera beaucoup plus grand (qu'un index partiel). Mais toujours plus petit que le tableau et utile pour ces requêtes.Une autre limitation est que l'index ne peut pas être
UNIQUE
avec cette solution, donc la contrainte n'est pas appliquée. Si l'index est créé avecUNIQUE
, l'unicité sera également appliquée pour les lignes avecis_active = FALSE
. Je suppose que vous ne voulez pas ça:b1) (la variante simple de b): ajoutez une autre table dans votre conception, avec uniquement les colonnes de clé primaire de
events
et une clé étrangère versevents
. Ce tableau ne doit avoir que des lignes où leis_active
est vrai dans le tableau d'origine (cela sera appliqué par votre application / procédures). Les requêtes avecis_active = TRUE
seraient modifiées pour se joindre à cette table (au lieu de laWHERE
condition).Le
UNIQUE
n'est pas appliqué non plus avec cette solution, mais les requêtes ne feraient qu'une simple jointure (à un index beaucoup plus petit) et devraient être assez efficaces:b2) une solution plus complexe: ajoutez une autre table dans votre conception, avec uniquement les colonnes de clé primaire de la table et
measurement_id
. Comme dans la suggestion précédente, ce tableau ne devrait avoir que des lignes où leis_active
est vrai dans le tableau d'origine (cela sera également appliqué par votre application / procédures). Utilisez ensuite ce tableau uniquement pour les requêtes qui ontWHERE is_active = TRUE
et n'ont besoin que de lameasurement_id
colonne. Sievents
vous avez besoin de plus de colonnes , vous devrezjoin
, comme précédemment.La
UNIQUE
contrainte peut être appliquée avec cette solution. La duplication demeasurement_id
colonne peut également être sécurisée pour être cohérente (avec une contrainte unique supplémentaireevents
et une clé étrangère composite):c) peut-être le plus simple de tous: utilisez PostgreSQL. Je suis sûr qu'il existe des packages pour votre distribution Linux. Ce n'est peut-être pas la dernière version de Postgres, mais des index partiels ont été ajoutés dans la version 7.0 (ou antérieure?), Vous ne devriez donc pas avoir de problème. De plus, je suis convaincu que vous pouvez installer la dernière version dans presque toutes les distributions Linux - même avec un peu de tracas. Vous n'avez besoin de l'installer qu'une seule fois.
la source
Ce n'est pas idéal, mais si vous avez une validation sur le terrain, vous pouvez apporter une modification qui rend la valeur non valide. Par exemple, des caractères illégaux ou des nombres négatifs. Vous pouvez effectuer cette modification lors de la suppression logicielle et vous savez qu'elle n'entrera pas en conflit avec une valeur valide. Vous devez également surveiller les valeurs supprimées en douceur qui ne s'affrontent pas également.
Dans 1 cas, j'avais une colonne de courrier électronique avec une contrainte unique et un identifiant d'entier à incrémentation automatique pour chaque ligne. Lors de la suppression logicielle, j'ai ajouté "id @", où id était l'ID de ligne unique, avant le véritable e-mail.
@
n'est pas autorisé dans les e-mails sauf s'il est cité, donc je sais qu'aucun e-mail valide n'entrera en conflit avec la nouvelle valeur, et donc cela n'entrera jamais en conflit avec un e-mail valide. L'ID entier unique garantit également que chaque ligne supprimée sera unique, même si le même e-mail est supprimé plusieurs fois.Je sais que ce n'est pas idéal, mais c'est un moyen simple de contourner le problème.
REMARQUE: Le changement que je mentionne ajoute des caractères au champ unique, j'ai donc dû faire des astuces supplémentaires si la valeur actuelle est déjà à / près de la longueur maximale. Ils sont spécifiques à l'application, donc ne valent pas la peine d'être mentionnés ici, mais soyez conscients et trouvez une solution de contournement pour cela aussi et c'est un moyen simple de contourner le manque de la fonctionnalité d'index partiel.
la source