-2

コーディングについてさらに質問する前に、データベースを作成するための最良の方法をまず見つけたいと思います。すべてを最小限に抑えるためにどのように構造化する必要があるかという問題に直面しています。その性質上、表現しなければならない繰り返し発生するデータがたくさんあります。

私はカスタム シャツをデザインし、男性と女性の両方の大人と子供の両方のサイズから選択できるさまざまな種類のシャツを用意しています。たとえば、男性、女性、男の子、女の子、幼児向けのクルーネック シャツ、ラグラン スリーブ、リンガー スリーブ、パーカーがあります。幼児サイズから大人サイズの1倍までは同一価格で、2倍、3倍、4倍、5倍はそれぞれ価格が異なります。次に、シャツの種類ごとに異なる色のオプションがあり、4 色のオプションがあるものもあれば、32 色のオプションがあるものもあります。

クルーネックシャツを例に挙げてみましょう。男性 s-1x、女性 s-1x、男の子 xs-1x、女の子 xs-1x、幼児 NB-18 か月は、表に表示される合計 22 行で、すべて同じ価格です。2X 以上は男性と女性にのみ適用されるため、さらに 8 列になり、クルーネック シャツだけで合計 30 列になります。カラーオプションに入ると、32 種類のカラーが用意されています。すべてのサイズについてすべてのサイズを実行すると、クルーネック シャツだけで合計 960 行になり、主にわずか 1 つのマイナー チェンジのデータが非常に繰り返されます。

私はそれについて考えて、テーブルにあるこれらのアイテムをストックルームの実際のアイテムとして扱うのが最善であると考えました。なぜなら、それらはストックルームに本当にあるからです...あなたはパンチできるシャツの箱を1つだけ持っているわけではありません.側面のボタンを使用して任意のサイズの色に切り替えるには、実際のシャツとそれらをどこかに配置するという面倒な作業に対処する必要があるため、大量の外部キーとインデックスで法外なことをしようとしないことに決めました。退屈で、リンク先のデータを最初のテーブルに入れるだけでよいのに、同じくらい多くのテーブルを表示する必要があります。

残りの 3 種類のシャツだけを取り、同じロジックをすべての色とサイズに適用すると、それら 4 枚のシャツだけで 3,840 行になり、残りのシャツは数えません。およそ 10,000 行のデータをすべて 1 つのテーブルで調べています。このデータは時間の経過とともに増加し、すべてを整理しておくとどうなるのだろうかと考えています。そこで、実際の小売店で行われているように、部門を男性、女性、男の子、女の子、赤ちゃんに分けるのが最善の論理ではないかと考えました。そのため、ユーザーが「その部門に行く」ことを決定したときにのみ呼び出される5つの個別のテーブルがあるため、男性用のシャツが欲しい男性がいる場合、7,000行以上の余分なデータが存在しません。彼が何に適用するか

これはそれを設定するためのより良い方法でしょうか?それとも、すべてを1つの巨大なテーブルとして保持し、男性用のセクションのテーブルからphpの「男性用」シャツをクエリし、女性と子供と同じにする方がよいでしょうか?

私の次の問題は、利用可能なすべての色のオプションです。前に言ったように、一部のシャツには 4 つしかないものもあれば、32 つものものもあります。シャツの種類ごとに個別のテーブルを用意できました。php でクエリを使用してテーブルから項目を入力するので、html と javascript でそれほど多くのコードを作成する必要はありません。そうすれSELECT ALL * table WHERE type=menば、すべての男性用シャツを取り、それぞれのコーディングを自動入力するように設定できます。そうすれば、テーブルに何かを追加したりテーブルから取得したりすると、自動的に更新されます。どのようにそれを行うかについてはすでにアイデアがありますが、それを構造化する必要があるテーブルを設定する良い方法を決めていないため、ここまでしか考えられません。から電話。

たとえば、各シャツのすべてのカラー オプションをすべて同じテーブルに配置するのではなく、それを分解し、それらを表すために他のテーブルにリンクする外部キーを配置するとします。それは、それを呼び出さなければならない2つのまったく異なる方法になるため、私はこれに行き詰まっており、どこに行くべきか本当にわかりません. 助言がありますか?

4

3 に答える 3

4

通常、小売組織は SKU (Stock Keeping Unit) ごとです。部門と色は衣服の属性であり、会計や仕入れのために衣服を識別する方法ではありません.

CREATE TABLE Skus (
  sku BIGINT UNSIGNED PRIMARY KEY,
  description TEXT,
  department VARCHAR(10) NOT NULL,
  color VARCHAR(10) NOT NULL,
  qty_in_stock INT UNSIGNED NOT NULL DEFAULT 0,
  unit_price NUMERIC(9,2) NOT NULL,
  FOREIGN KEY (department) REFERENCES Departments(department),
  FOREIGN KEY (color) REFERENCES Colors(color)
);

これは、次の理由から、5 つのテーブルに分割するよりも優れています。

  • すべての株式の合計値の合計をすばやく取得できます。
  • 特定の SKU の部門を簡単に切り替えることができます。
  • 誰かがいくつかの衣服を購入すると、注文品目は 5 つの異なるテーブルではなく、1 つのテーブルを参照します (これはリレーショナル データベースでは無効です)。

同様のエンティティが 1 つのテーブルに格納されている場合に、より簡単なタスクの例は他にもたくさんあります。

于 2012-12-21T21:35:31.757 に答える
2

別々のテーブルに分割したくないことは承知していますが、複数のテーブル ルートを使用するのが最善だと思います。とはいえ、あなたが思っているほど悪くはないと思います。私の提案は次のとおりです。明らかに、フィールドの名前を変更したいのですが、これは簡単な表現です:

シャツ

  - id (primary key)
  - description
  - men (Y/N)
  - women (Y/N)
  - boy (Y/N)
  - girl (Y/N)
  - toddlers (Y/N)

サイズ

  - id (primary key)
  - shirt_id (foreign key)
  - Size

  - id (primary key)
  - shirt_id (foreign key)
  - Color

価格

  - id (primary key)
  - shirt_id (foreign key)
  - size_id (foreign key)
  - price

これら 3 つのテーブルを使用すると、10,000 行すべてを 1 つのテーブルに格納して維持する必要がなくなりますが、データはすべてそこに残っています。データを適切な場所に分けておくと、不要な情報が複製されるのを防ぐことができます。

すべてのメンズシャツを引っ張りたいですか?

SELECT * FROM shirts WHERE men = '1'

正直なところ、少なくとも 5 つまたは 6 つのテーブルが必要です。サイズと色のラベルを含む 1 つまたは 2 つ (すべてを含む 1 つのテーブル、またはそれぞれのテーブルに 1 つ) と、実際のデータを含む残りの 4 つ。これにより、すべてのデータが均一に保たれます (例: Bluevs blue)。猫の皮を剥ぐ方法はたくさんあります。

于 2012-12-21T21:36:02.997 に答える
1

「正規化」と呼ばれるデータベース用語について考える必要があります。正規化とは、すべてがデータベース内に配置されていることを意味し、2 回リストするのではなく、必要に応じて再利用する必要があります。人々が犯す最も一般的な間違いは、将来何が起こるかを尋ねたり考えたりしないことです。彼らは、正規化がほとんど行われず、大量のメモリを消費して大きなデータ型を処理し、シード処理を行わず、完全に柔軟性がなく、将来のことを考えずに作ったので、後で変更するには多大なコストがかかります。

正規化には多くのレベルがありますが、最も一貫しているのは、後でより大きなものに適用できるいくつかの簡単な概念を説明するために提供できる簡単な例について考えることです. これは、SQL 管理スタジオ、SSMS にアクセスできることを前提としていますが、MYSQL または Oracle を使用している場合でも、原則は非常に似ており、コメント セクションに私が得ていることが示されます。この例は、SSMS がある場合に自己実行でき、貼り付けて F5 キーを押すだけです。コメント セクションだけを見ていない場合でも、これらの概念は、その意味を想像するよりも、実際に動作しているのを確認した方がよいでしょう。

Declare @Everything table (PersonID int, OrderID int, PersonName varchar(8), OrderName varchar(8) );

insert into @Everything values (1, 1, 'Brett', 'Hat'),(1, 2, 'Brett', 'Shirt'),(1, 3, 'Brett', 'Shoes'),(2,1,'John','Shirt'),(2,2,'John','Shoes');

-- very basic normalization level in that I did not even ATTEMPT to seperate entities into different tables for reuse.
-- I just insert EVERYTHING as I get in one place.  This is great for just getting off the ground or testing things.
-- but in the future you won't be able to change this easily as everything is here and if there is a lot of data it is hard 
-- to move it.  When you insert if you keep adding more and more and more columns it will get slower as it requires memory 
-- for the rows and the columns
Select Top 10 * from @Everything

declare @Person table ( PersonID int identity, PersonName varchar(8));

insert into @Person values ('Brett'),('John');

declare @Orders table ( OrderID int identity, PersonID int, OrderName varchar(8));

insert into @Orders values (1, 'Hat'),(1,'Shirt'),(1, 'Shoes'),(2,'Shirt'),(2, 'Shoes');

-- I now have tables storing two logic things in two logical places.  If I want to relate them I can use the TSQL language
-- to do so.  I am now using less memory for storage of the individual tables and if one or another becomes too large I can 
-- deal with them isolated.  I also have a seeding record (an ever increasing number) that I could use as a primary key to 
-- relate row position and for faster indexing
Select *
from @Person p 
    join @Orders o on p.PersonID = o.PersonID

declare @TypeOfOrder table ( OrderTypeID int identity, OrderType varchar(8));

insert into @TypeOfOrder values ('Hat'),('Shirt'),('Shoes')

declare @OrderBridge table ( OrderID int identity, PersonID int, OrderType int)

insert into @OrderBridge values (1, 1),(1,2),(1,3),(2,2),(2,3);


-- Wow I have a lot more columns but my ability to expand is now pretty flexible I could add even MORE products to the bridge table
-- or other tables I have not even thought of yet.  Now that I have a bridge table I have to list a product type ONLY once ever and 
-- then when someone orders it again I just label the bridge to relate a person to an order, hence the name bridge as it on it's own
-- serves nothing but relating two different things to each other.  This method takes more time to set up but in the end you need 
-- less rows of your database overall as you are REUSING data efficiently and effectively.
Select Top 10 *
from @Person p 
    join @OrderBridge o on p.PersonID = o.PersonID
    join @TypeOfOrder t on o.OrderType = t.OrderTypeID
于 2012-12-21T21:38:18.680 に答える