1

後で検索するために使用される購入アイテムを追跡するためのデータベース関係を考え出そうとしています--たとえば電子ブック。省略記号は無視してください。省略記号は、タイムスタンプなどのさまざまなデータを表しています...

これが私が今持っているテーブルです:

purchased:
transaction_id(int)(pk)(auto_inc) | username (varchar) | purchases (text) | ...

この設計では、列「購入」は、購入したアイテムの item_id をコンマで区切って含む単なるテキスト文字列です。簡単な例: "book1, book23, book5, book8".

トランザクションが成功すると、このクエリはトランザクション データを「purchased」テーブルに挿入します。

INSERT INTO purchased VALUES (null, username, purchases, ...)

この時点から、次の 2 つのことが起こります。

  1. ユーザーは購入した電子書籍を検索できます
  2. ユーザーは別の購入取引を行うことができます。

ユーザー (ユーザー名) が自分の電子ブックを見たい場合、システムは選択クエリを実行します。

SELECT purchases FROM purchased WHERE username=theusername

アイテム ID を含む文字列を返します。

余談ですが、追加のphpコードを使用せずに購入のphp配列を取得すること、つまり爆発させることは可能ですか? アイテムのリストを格納するために、SQL のデータ型「テキスト」以外のものを使用できますか? そうでない場合は、大丈夫です。


いずれにせよ、ここが主な問題です。ユーザーが別のトランザクションを行うとします。ユーザーが購入したアイテムを含む "purchased" には 2 つの行があります。つまり、このテーブルでは、ユーザーの購入が複数の行に分割されています。

理想的には、これらの購入がすべて同じ行にあることを望みます。各購入には独自の一意の transaction_id があるため、UPDATE ステートメントを使用できません。

ユーザーによるすべての購入を含む別のテーブルを作成できると考えていました

all_purchased:
username (pk) | purchases (text) | ...

ユーザーが別のトランザクションを行うたびに、「all_purchased」テーブルは、新しい電子ブックのアイテム ID でその Purchases 列を更新するだけです。

しかし、私が言及した選択クエリがタスクを完了させるため、このテーブルは冗長に見えます。

データベースのリレーションを構築する最良の方法は何ですか?

4

2 に答える 2

1

購入したbook_idをコンマ区切りの値と同じ行に保持するのは良い考えではないと思います。新しいテーブルを次のように定義することをお勧めします。

  purchased_books:
      transaction_book_id(int)(pk)(auto_inc) | transaction_id(int) | book_id(int)

また、transaction_id列とbook_id列の外部キー関係をそれぞれのテーブル(および)と定義しpurchasedますbooks

うまくいけば、この新しいテーブルを使用することで、残りの問題が解決されるでしょう。

于 2012-11-04T05:06:20.393 に答える
0

リレーショナル データベースを使用していることを考慮して、正規化されたテーブルを使用しない特別な理由はありますか? ここに 1 つの可能性があります。

ここに画像の説明を入力

これはキーを伝播します。複合キーに問題がある ORM がある場合は、この例のように変更します。

于 2012-11-04T13:47:47.420 に答える