1

私は外部キーについて学んでおり、以下の例でそれを使用した方法が正しいかどうかを知りたいと思っていました:

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 (name) REFERENCES items(name),
  FOREIGN KEY (id) REFERENCES user(id)
);

ありがとう

では、たとえば PHP を使用している場合、外部キーだけから最大の情報を取得するにはどうすればよいでしょうか。

4

2 に答える 2

2

両方の表に項目名を含める必要はありません。これを非正規化解と呼びます。項目テーブルにのみ含める必要があり、id のみを参照する必要があります。名前が必要な場合は、主キー (id) に基づいて結合することもできます。そうでなければ、私の意見ではまったく問題ありません。

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 を「冗長」に保つことができる理由を理解するのに役立ちます。後で元のデータセットを再構築できるようにするために必要なため、実質的に必要な冗長性です。これは、さまざまな正規形の定義になります。この冗長性のどのレベルが許可されますか?

機能依存性

于 2013-11-02T12:11:45.747 に答える
2

を主キーとして持っているi_idので、名前を外部キーとして設定する必要はありません。ところで、外部キーは一意の属性を参照する必要があります。

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 UNIQUE 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)    
);
于 2013-11-02T12:27:07.090 に答える