J'essaie de réécrire le schéma Postgres pour l'adapter au dialecte MySQL (8.0.32). Comme vous le savez, MySQL ne prend pas en charge les index partiels.
Seulement si deleted_at
为 null 时,才会存在一个索引,该索引会强制执行 customer_group.name
est la seule donnée disponible.
Cela est logique puisqu'il ne sert à rien de garantir que les entrées supprimées sont uniques. Cependant, je ne comprends pas comment implémenter les mêmes contraintes sans indexation partielle.
CREATE TABLE "customer_group" ( "id" integer NOT NULL AUTO_INCREMENT, "created_at" datetime NOT NULL DEFAULT NOW(), "updated_at" datetime NOT NULL DEFAULT NOW(), "deleted_at" datetime, "name" text NOT NULL, "metadata" text, CONSTRAINT "PK_142c3338-da81-4d0c-8cd8-490bb41cd187" PRIMARY KEY ("id") ); -- solve this -- ensure name is unique when one customer_group is not deleted CREATE UNIQUE INDEX "IDX_d12ecf48-302c-4292-8c8d-d2cc7c8149f9" ON "customer_group" ("name") WHERE "deleted_at" IS NULL;
PS J'utilise ANSI_QUOTES
.
Quelqu'un m'a suggéré d'essayer d'utiliser un index unique de 2 colonnes au lieu d'une. Cependant, si la contrainte est UNIQUE INDEX "IDX_d12ecf48-302c-4292-8c8d-d2cc7c8149f9" ON "customer_group" ("name", "deleted_at")
那么我会得到与我想要的相反的结果: deleted_at
为 NULL,则 name
, elle peut être répétée.
En utilisant les colonnes calculées, vous pouvez effectuer les opérations suivantes :
Avec indice :
P.S. Je n'ai pas utilisé ANSI_QUOTES.
Voir : DBFIDDLE
MySQL ne prend pas en charge les index partiels, mais prend en charge les index d'expression (à partir de MySQL 8.0). Voici une démo :
Puisque UNIQUE suit les règles NULL de l'ANSI, si la deuxième colonne d'un index unique est NULL, il peut y avoir n'importe quel nombre de doublons dans la première colonne. La deuxième colonne lorsque NULL n'est égale à aucune autre ligne, elle est donc toujours "unique".
Donc, si la deuxième colonne est une valeur fixe non NULL uniquement lorsque "deleted_at" est NULL, alors "name" est unique sur toutes les lignes où "deleted_at" est NULL.
J'ai dû changer le type de "nom" car vous ne pouvez pas créer d'index sur une colonne TEXTE dans MySQL et c'est probablement trop long pour la limite de 3072 octets de l'index.
A également modifié PRIMARY KEY pour omettre les noms de contraintes. MySQL nommera toujours simplement la clé primaire
PRIMARY
.