両方のテーブルにアイテム名を含める必要はありません。これは非正規化ソリューションと呼ばれます。アイテムテーブルにのみ存在し、IDのみを参照する必要があります。名前が必要な場合は、主キー(id)に基づいて結合することもできます。それ以外の場合は、完全にOKです。意見。
CREATE TABLE user(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE items(
i_id INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
price DECIMAL(8,2) NOT NULL,
PRIMARY KEY (i_id)
);
CREATE TABLE user_purchase(
i_id INT(11) NOT NULL,
name TINYTEXT NOT NULL,
id INT(11) NOT NULL,
FOREIGN KEY (i_id) REFERENCES items(i_id),
FOREIGN KEY (id) REFERENCES user(id)
);
パフォーマンスが重要な場合は、非正規化されたテーブルを使用する必要があります。はるかに高速になる可能性があります。
さまざまな異常を回避するには、正規化が重要です。高レベルの正規形のテーブルがある場合、テーブルは冗長ではなく、これらの異常はありません。たとえば、複数の場所に何かを保存している場合は、すべての冗長データを最新の状態に保つために注意を払う必要があります。これにより、これを誤って実行し、さまざまな異常が発生する可能性があります。
あなたの状況では、外部キーを持っているとデータの整合性を保つのに役立ちますが、名前の外部キーがないと、アイテムテーブルに存在しない名前のアイテムを購入に含めることができます。
これは一種の異常です。
これには多くの種類がありますが、できる限り避けるのが最善です。
場合によっては、デノラマライズする必要があります。したがって、パフォーマンスの問題のために、一部のデータを冗長に保存します。このようにして、多くの時間を消費する可能性のあるいくつかの結合操作を節約できます。
正規化の詳細は、さまざまな正規形のトピックでカバーされています:NF0、NF1、NF2、NF3、およびBCNF
より高い正規形へのロスレス分解の数学的基礎の詳細については、「関数従属性」を参照してください。これは、IDを「冗長」に保つことができる理由を理解するのに役立ちます。後で元のデータセットを再構築できるようにするために必要になるため、事実上、これらは必要な冗長性です。これは、さまざまな正規形の定義になります。この冗長性のどのレベルが許可されますか?