2017-10-20 11 views
0

私は個人的なプロジェクトに取り組んでいます。私の人生ではじめて、正規化されたデータベースを作成しようとしています(少なくとも正規化の最初のレベルまで)。ここでは、テーブルの関与私の問題である:mysqlの外部キー制約には何が問題になっていますか?

CREATE TABLE `reoccurrences` (
    `name` varchar(15) NOT NULL DEFAULT '', 
    `username` varchar(31) NOT NULL DEFAULT '', 
    `amount` float(7,2) NOT NULL DEFAULT '0.00', 
    `action` varchar(15) NOT NULL DEFAULT '', 
    `frequency` varchar(15) NOT NULL DEFAULT '', 
    PRIMARY KEY (`name`,`username`), 
    KEY `fk_reoccurrences_user` (`username`), 
    KEY `fk_reoccurrences_action` (`action`), 
    KEY `fk_reoccurrences_frequency` (`frequency`), 
    CONSTRAINT `fk_reoccurrences_action` FOREIGN KEY (`action`) REFERENCES `actions` (`name`), 
    CONSTRAINT `fk_reoccurrences_frequency` FOREIGN KEY (`frequency`) REFERENCES `frequencies` (`name`), 
    CONSTRAINT `fk_reoccurrences_user` FOREIGN KEY (`username`) REFERENCES `users` (`name`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

CREATE TABLE `days` (
    `reoccurrence` varchar(15) NOT NULL, 
    `username` varchar(31) NOT NULL DEFAULT '', 
    `day` tinyint(2) NOT NULL, 
    PRIMARY KEY (`reoccurrence`,`username`,`day`), 
    KEY `fk_days_reoccurrence2` (`username`), 
    CONSTRAINT `fk_days_reoccurrence` FOREIGN KEY (`reoccurrence`) REFERENCES `reoccurrences` (`name`), 
    CONSTRAINT `fk_days_reoccurrence2` FOREIGN KEY (`username`) REFERENCES `reoccurrences` (`username`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

注意、主な問題は、(私は信じて)この2つのテーブルの間にあります。関連する他のテーブルがいくつかありますが、私がそれらをリストアップし始めると、この投稿は非常に長くなるでしょう。あなたが完全なデータ構造を見たいのであれば、私のプロジェクトをgithubで見ることができます:https://github.com/dallascaley/finance(私のgithubのreadmeでの冒涜/常識の欠如については、一般公開されているわけではありません)

私がこれらのテーブルにデータを追加し始めるときに問題が発生します。

reoccurrences: 

name, username, amount, action, frequency 
Pay , dallas , 2500 , credit, bi-weekly 
Rent, dallas , 1400 , debit , monthly 

days: 

reoccurrence, username, day 
Rent  , dallas , 1 

は私が支払うために列挙された日、または数日を持っていないという事実を無視する:ここで私が持っているデータです。何らかの理由でテーブルがこの状態になっている場合、私はReoccurrenceテーブルからPayレコードを削除できません。私はこの実行すると:

DELETE FROM reoccurrences WHERE `name` = 'Pay' AND `username` = 'dallas'; 

を私は次のエラーを取得する:

Cannot delete or update a parent row: a foreign key constraint fails (`test`.`days`, CONSTRAINT `fk_days_reoccurrence2` FOREIGN KEY (`username`) REFERENCES `reoccurrences` (`username`)) 

は、どのように私はこの問題を解決するために、私のテーブル構造を変更することができますか?

答えて

2

あなたはおそらくちょうどreoccurrencesから複合キーを使用して、テーブルdaysであなたの制約を修正する必要があります。両方のキー、あなたは私がComposeキーにfk_days_reoccurrenceを変更し、完全fk_days_reoccurrence2を落とし見ることができるように

CREATE TABLE `days` (
    `reoccurrence` varchar(15) NOT NULL, 
    `username` varchar(31) NOT NULL DEFAULT '', 
    `day` tinyint(2) NOT NULL, 
    PRIMARY KEY (`reoccurrence`,`username`,`day`), 
    CONSTRAINT `fk_days_reoccurrence` FOREIGN KEY (`reoccurrence`,`username`) REFERENCES `reoccurrences` (`name`,`username`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

をし、外部キー参照。

+0

ありがとうございました。私は十年のソフトウェア開発を信じることができません。適切なデータ構造を適用した企業で働いたことはありませんでした。(HauteLookに加えて、私はデータベースの近くにいませんでした) –

+0

私はMySQLをあまり使っていません。 'days'テーブルから' reoccurrence'への元の外部キーの制約は良くありませんでした。彼らはそれぞれ、 'name(1) - > reoccurrence(n)'と 'username(1) - > username(n)'カラムで 'reoccurrence'と' days'の間に1対多のリレーションシップを示しましたが、 'reoccurrence'は' name'か 'username'のどちらかのインスタンスを強制しませんでした。だから、 'reoccurrence'から削除しようとすると' username 'の参照制約が 'dallas'のインスタンスが2つあったにもかかわらず、' days'が 'username''dallasを参照していたので削除を阻止しました。 – Sentinel