Ich versuche, das Postgres-Schema so umzuschreiben, dass es zum MySQL-Dialekt (8.0.32) passt. Wie Sie wissen, unterstützt MySQL keine Teilindizes.
Nur wenn deleted_at
为 null 时,才会存在一个索引,该索引会强制执行 customer_group.name
die einzigen Daten sind.
Das ist sinnvoll, da es keinen Sinn macht, sicherzustellen, dass gelöschte Einträge eindeutig sind. Allerdings verstehe ich nicht, wie man dieselben Einschränkungen ohne teilweise Indizierung implementieren kann.
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 Ich benutze ANSI_QUOTES
.
Jemand hat mir vorgeschlagen, einen eindeutigen Index für zwei Spalten statt für eine zu verwenden. Wenn die Einschränkung jedoch UNIQUE INDEX "IDX_d12ecf48-302c-4292-8c8d-d2cc7c8149f9" ON "customer_group" ("name", "deleted_at")
那么我会得到与我想要的相反的结果: deleted_at
为 NULL,则 name
ist, kann sie wiederholt werden.
使用计算列,您可以执行以下操作:
带有索引:
附注我确实没有使用 ANSI_QUOTES。
参见:DBFIDDLE
MySQL不支持部分索引,但支持表达式索引(从MySQL 8.0开始)。这是一个演示:
由于 UNIQUE 遵循 ANSI 的 NULL 规则,因此如果唯一索引的第二列为 NULL,则第一列中可能存在任意数量的重复项。第二列为 NULL 时不等于任何其他行,因此它始终是“唯一的”。
因此,如果仅当“deleted_at”为 NULL 时第二列是固定的非 NULL 值,则“name”在“deleted_at”为 NULL 的所有行上都是唯一的。
我必须更改“名称”的类型,因为您无法在 MySQL 中的 TEXT 列上创建索引,对于索引的 3072 字节限制来说,它可能太长了。
还更改了 PRIMARY KEY 以省略约束名称。 MySQL 将始终将主键简单地命名为
PRIMARY
。