2010-03-02 50 views
7

我被遷移MySQL數據庫的Postgres和DDL遇到下列塊絆倒(注:這是我從mysqldump的獲得):Mysql外鍵通過非唯一鍵 - 這怎麼可能?

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; 

現在,我在這裏看到的是,在唯一的唯一密鑰第一表是組合(ID,排序):

PRIMARY KEY (`id`,`sort`), 

然而,第二個表有僅通過id列,這不是唯一的第一上參考!

CONSTRAINT `FK_catalog_realty_property_value_link_value` FOREIGN KEY (`value_id`) REFERENCES `catalog_property_value` (`id`) ON DELETE CASCADE 

那麼,我在這裏弄錯了什麼?這怎麼可能?

回答

8

從手冊:從SQL標準

偏差:引用 一個 FOREIGN KEY約束非唯一鍵不是標準的SQL。 這是對標準的 SQL的InnoDB擴展。

所以它看起來像InnoDB允許非唯一索引作爲外鍵引用的候選。在其他地方,手冊指出,只要被引用的列首先列出並按照與主鍵相同的順序,您就可以引用被引用索引中的列的子集。

因此,這個定義是InnoDB的法律,儘管它不是標準的SQL和離開我,至少,作爲原設計者的意圖有點困惑。

Manual page here

+0

如果您看到此頁面:http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign- key-constraints.html中,第一個要點提到外鍵必須首先引用索引列使用列的索引,並且按照約束指定的順序引用索引。 – 2014-02-16 16:41:42

-1

這是完全合法根據wikipedia

在引用表 的列必須是在所引用的表中的主鍵或其它 候選鍵。

+1

是不是候選鍵是唯一鍵?或者你說多對多關係可以用一個外鍵建模?我很困惑:( – 2010-03-02 10:18:28

+0

在這種情況下,引用表中的列根本不是任何關鍵字(而是更大的關鍵字的一部分)。事實上,InnoDB似乎允許這樣做,但它不是標準的SQL – 2010-03-03 21:45:16

+1

我不明白如何引用一個非唯一的密鑰是可以通過wiki的外鍵或候選鍵的定義 – 2013-04-04 20:35:32

-1

最有可能的答案是,ID確實是在catalog_propery_value表獨特的,但作者聲明的PK是原因不明的超密鑰(ID,排序),可能跟索引做的,而不是強制唯一性。

+0

我剛剛檢查,它是*不*唯一... – 2010-03-02 11:00:08

+0

引擎如何知道id是唯一的?它被聲明爲是或否,並且在這種情況下,它顯然沒有被聲明爲唯一的。 – 2010-03-03 21:43:58

2

InnoDB的FK的這種怪異的行爲在manual描述。

到包含NULL值的非唯一鍵或按鍵 外鍵引用的處理沒有很好 用於諸如UPDATE 或DELETE CASCADE操作定義。建議您引用僅 UNIQUE和NOT NULL鍵 使用外鍵。

PostgreSQL不接受這種結構,外鍵必須指向一個唯一的鍵。