Я перемещал mysql базу данных в пост-ГРЭС и споткнулся через следующий блок в DDL (Примечание: Это - то, что я получил от mysqldump):
CREATE TABLE `catalog_property_value` (
`id` int(10) unsigned NOT NULL,
`property_id` int(10) unsigned NOT NULL,
`sort` int(10) unsigned NOT NULL,
`value_number` decimal(15,5) DEFAULT NULL,
`value_string` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`,`sort`),
KEY `FK_catalog_property_value` (`property_id`),
KEY `NewIndex1` (`id`),
CONSTRAINT `FK_catalog_property_value` FOREIGN KEY (`property_id`) REFERENCES `catalog_property` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
CREATE TABLE `catalog_realty_property_value_link` (
`realty_id` int(10) unsigned NOT NULL,
`property_id` int(10) unsigned NOT NULL,
`value_id` int(10) unsigned NOT NULL,
`dt_is_denormalized` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`realty_id`,`property_id`,`value_id`),
KEY `FK_catalog_realty_property_value_link_property` (`property_id`),
KEY `FK_catalog_realty_property_value_link_value` (`value_id`),
CONSTRAINT `FK_catalog_realty_property_value_link_property` FOREIGN KEY (`property_id`) REFERENCES `catalog_property` (`id`) ON DELETE CASCADE,
CONSTRAINT `FK_catalog_realty_property_value_link_realty` FOREIGN KEY (`realty_id`) REFERENCES `catalog_realty` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_catalog_realty_property_value_link_value` FOREIGN KEY (`value_id`) REFERENCES `catalog_property_value` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Теперь, что я вижу, вот то, что единственный уникальный ключ в первой таблице является комбинацией (идентификатор, вид):
PRIMARY KEY (`id`,`sort`),
однако, вторая таблица имеет ссылку на первое на только идентификационным столбцом, который не уникален!
CONSTRAINT `FK_catalog_realty_property_value_link_value` FOREIGN KEY (`value_id`) REFERENCES `catalog_property_value` (`id`) ON DELETE CASCADE
Так, что я понимал превратно здесь? Как это возможно?
Из руководства:
Отклонение от стандартов SQL : ограничение FOREIGN KEY, которое ссылается на a ключ non-UNIQUE - это не стандартный SQL. Это расширение InnoDB для стандартного SQL.
Похоже, что InnoDB допускает использование неуникальных индексов в качестве кандидатов на ссылки внешнего ключа. В другом месте руководства указано, что вы можете ссылаться на подмножество столбцов в указанном индексе, если указанные столбцы указаны первыми и в том же порядке, что и первичный ключ.
Следовательно, это определение допустимо в InnoDB, хотя это не стандартный SQL и оставляет меня, по крайней мере, немного смущенным относительно намерений первоначального разработчика.
Это странное поведение FK в innoDB описано в руководстве .
Обработка ссылок внешнего ключа на неуникальные ключи или ключи , которые содержат значения NULL, плохо определена для таких операций, как UPDATE или DELETE CASCADE. Рекомендуется использовать внешние ключи, которые ссылаются только на UNIQUE и NOT NULL ключи.
PostgreSQL не принимает эту конструкцию, внешний ключ должен указывать на уникальный ключ.
Это совершенно законно согласно википедии :
Столбцы в справочной таблице должны быть основными key или другой ключ-кандидат в указанной таблице.
Наиболее вероятный ответ заключается в том, что id действительно уникален в таблице catalog_propery_value, но автор объявил PK как суперключ (id , sort) по неизвестным причинам, возможно, связанных с индексацией, а не с обеспечением уникальности.