2016-11-18 15 views
0

私は現在、自分自身をmySQLで教えているので、私の営業データベースに新しい行を挿入する際に問題が発生しています。MySQLの外部キー検証に関する問題

商品の販売が行われるたびに、購入者のID(ユーザーテーブルからの外部キー)と購入者の名前(ユーザーテーブルからの外部キー)を含む新しい行が販売データベースに追加されます)。

しかし、私の問題は次のとおりです。 id=10のユーザーの販売テーブルに新しいレコードを挿入し、name='Roger Smith'の代わりにname='Peter Smith'を間違って入力した場合は、'Peter Smith'がユーザーテーブルのid=10の名前ではなくても正常に処理されます。

誰かが私が間違っている方向に私を指摘できますか?どうもありがとう。

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(30) DEFAULT NULL, 
`dob` date DEFAULT NULL, 
PRIMARY KEY (`id`), 
KEY `name` (`name`) 
) ENGINE=InnoDB 

CREATE TABLE `sales` (
`salesid` int(11) NOT NULL AUTO_INCREMENT, 
`productname` varchar(30) DEFAULT NULL, 
`productprice` decimal(10,0) DEFAULT NULL, 
`quantity` int(11) DEFAULT NULL, 
`userid` int(11) NOT NULL, 
`user_name` varchar(30) DEFAULT NULL, 
PRIMARY KEY (`salesid`), 
KEY `FK_sales` (`userid`), 
KEY `FK_name` (`user_name`), 
CONSTRAINT `FK_name` FOREIGN KEY (`user_name`) REFERENCES `users` (`name`) ON DELETE CASCADE ON UPDATE CASCADE, 
CONSTRAINT `FK_sales` FOREIGN KEY (`userid`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB 

答えて

3

実装が3番目の正規形(3NF)に違反しているため、間違った箇所は更新の異常です。

各属性は、キー、キー全体、およびキーだけに依存します。だから私を助けてください。お使いのモデルで


salesテーブル内user_namesalesテーブルのキーに依存しています。それがuserid列に依存しているように思えます。

user_nameの列をsalesのテーブルから削除することです。 user_nameを返す必要がある場合は、user_idに基づいてusersテーブルを検索します。例として、usersテーブルへのJOIN操作。

SELECT u.name AS user_name 
    , s.userid 
    , s.productprice 
    , ... 
    FROM sales s 
    JOIN users u 
    ON u.id = s.userid 

このアプローチでは、重複した情報を保存しないようにしています。 e name属性は、usersテーブルのid列のにのみ依存します()。


salesテーブル上user_nameを格納するための強い必要性がある場合、アプリケーションロジックはsalesテーブル内の行にuser_namename列と同じである必要があることルールを適用する必要があります対応する行のusers表にあります。ルール

のようなものを強制されます何の宣言型の制約(外部キー制約は、値のみが参照されるテーブルで一部行に表示されなければならないという規則が適用されます。)

はありません追加することが可能ですBEFORE INSERTおよびBEFORE UPDATEトリガーを使用してルールを適用し、検索を実行してuser_name列に自動的に値を設定します。

+0

実際にはsalesテーブルとuserテーブルは1NFにもありません。いずれのテーブルにもナチュラルキーがないからです。 – nicomp