、 、 の 3 つのテーブルaccount
がaddress
ありaccount_address
ます。account_address
テーブルにはとaccount_id
がありaddress_id
ます。これは、標準的な多対多の関係です。
存在しないaccount_address
を指すレコードがあるという困惑した状況があります。を指しaccount
ている外部キーがあるので、これは起こりえないはずですよね?account_address.account_id
account
では、この不可能であるべきことが起こっていることを証明しましょう。まず、テーブル定義を示します。
CREATE TABLE `account_address` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`account_id` bigint(20) NOT NULL,
`address_id` bigint(20) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `fk_account_address_account_id` (`account_id`),
KEY `fk_account_address_address_id` (`address_id`),
KEY `index_account_address_account_id` (`account_id`) USING BTREE,
KEY `index_account_address_address_id` (`address_id`) USING BTREE,
CONSTRAINT `fk_account_address_account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_account_address_address_id` FOREIGN KEY (`address_id`) REFERENCES `address` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=697173 DEFAULT CHARSET=latin1
見る?FOREIGN KEY (account_id) REFERENCES account (id)
.
次に、その制約が失敗したことを示すいくつかのクエリを示します。
select aa.account_id
from account_address aa
where aa.address_id = 15116
そのクエリにより、次の結果が得られます。
15116
37033
62325
71857
93774
119066
したがって、どうやらアドレス 15116 は 6 つの異なるアカウント (興味深いことに、アドレスと同じ ID を持つ 1 つのアカウント) に関連付けられています。しかし、これをチェックしてください:
select * from account where id in (15116, 37033, 62325, 71857, 93774, 119066)
結果がありません!ある時点で、外部キー制約が失敗したことを DBMS が教えてくれるはずではありませんか?!
私は2つの可能性しか考えていません:
- 見ているものを誤解している
- 私の DBMS は根本的な方法で誤動作しています
#1が当てはまることを願っていますが、何を誤解している可能性があるのか わかりません. それは私にとって最高のミステリーです。どんな考えでも大歓迎です。