DBAL creates a backing index for a foreign key even when a unique constraint already covers the referencing columns.
The implicit index is a workaround for schema comparison. It mirrors the backing index MySQL and MariaDB create automatically for a foreign key. When a unique constraint covers the columns, those engines create no such index — they reuse the unique one instead. So the implicit index mirrors nothing, and it duplicates the unique constraint's index. It is redundant twice over.
Reproduce
$child = Table::editor()
->setUnquotedName('child')
->setColumns(
Column::editor()
->setUnquotedName('id')
->setTypeName(Types::INTEGER)
->create(),
Column::editor()
->setUnquotedName('parent_id')
->setTypeName(Types::INTEGER)
->create(),
)
->setUniqueConstraints(
UniqueConstraint::editor()
->setUnquotedColumnNames('parent_id')
->create(),
)
->setForeignKeyConstraints(
ForeignKeyConstraint::editor()
->setUnquotedReferencingColumnNames('parent_id')
->setUnquotedReferencedTableName('parent')
->setUnquotedReferencedColumnNames('id')
->create(),
)
->create();
echo implode("\n", (new MySQLPlatform())->getCreateTableSQL($child));
The code above produces:
CREATE TABLE child (
id INT NOT NULL,
parent_id INT NOT NULL,
UNIQUE (parent_id),
INDEX IDX_22B35429727ACA70 (parent_id)
)
ALTER TABLE child
ADD FOREIGN KEY (parent_id) REFERENCES parent (id)
The implicit INDEX IDX_22B35429727ACA70 (parent_id) is redundant — the explicit UNIQUE (parent_id) already covers that column.
DBAL creates a backing index for a foreign key even when a unique constraint already covers the referencing columns.
The implicit index is a workaround for schema comparison. It mirrors the backing index MySQL and MariaDB create automatically for a foreign key. When a unique constraint covers the columns, those engines create no such index — they reuse the unique one instead. So the implicit index mirrors nothing, and it duplicates the unique constraint's index. It is redundant twice over.
Reproduce
The code above produces:
The implicit
INDEX IDX_22B35429727ACA70 (parent_id)is redundant — the explicitUNIQUE (parent_id)already covers that column.