1

私は (mysql) データベース設計に慣れていないので、次の質問に対するフィードバックをいただければ幸いです。顧客情報と製品情報を含む mysql データベースにリンクされた Web サイトを開発しています。一般的な顧客情報 (名前、住所、生年月日など) 用にテーブル「crm」を作成し、一般的な製品情報 (利用可能な製品の説明) 用にテーブル「products」を作成しました。

私の質問は、各顧客が選択した製品のリストを保存する方法ですか? もちろん、このリストは顧客ごとに異なり、時間の経過とともに変化する可能性もあります。さらに、テーブル「製品」も時間の経過とともに変化する可能性があります (新しい製品が追加されたり、既存の製品が削除されたりします)。最初に、顧客ごとに選択された製品を含む「顧客製品」テーブルの設計について検討しましたが、このサイトの関連ページに関するいくつかのコメントを読んだ後、それが良い設計であるかどうか疑問に思います (テーブルが 100K を超える可能性があるため)。代替ソリューションは、次のようなリンクを使用して単一のテーブル「顧客製品」を使用する設計である可能性があります。

table 'crm'                    table 'customer products'          table 'products'
--------------------------     -------------------------------    ---------------- 
name | addr | first_prodref    prodref | prodid | next_prodref    prodid | name | cost


- first_prodref in table 'crm' points to (index) prodref in table 'customer products'
- prodid in table 'customer products points to (index) prodid in table 'products'
- next_prodref in table 'customer products' points to the next prodref in table 'customer products'

この代替ソリューションは問題ありませんか、それともより良い提案はありますか?

フィードバックをお待ちしております。

4

3 に答える 3

1

ここから始めましょう...

  • (P) は主キーを意味します
  • (F table.column) は外部キーとそれが指す table.column を意味します

顧客の請求先住所、顧客の配送先住所など、住所を格納するテーブルが必要です。

addresses
    id              unsigned int(P)
    street1         varchar(75) // 123 South Main Street, etc.
    street2         varchar(75) // Apt A, etc.
    city_id         unsigned int(F cities.id)
    zip             varchar(6) // 12345, A1A 1A1, etc. (CA, MX and US)

ユーザーが自分で値 (都市名など) を入力するよりも、値のリストから選択できるようにするのが最善です...

cities
    id              unsigned int(P)
    state_id        unsigned int(F states.id)
    name            varchar(50) // Omaha, Detroit, Tampa, etc.

繰り返しますが、ユーザーに独自の値を入力させるのではなく、選択できる有効な値を提供することをお勧めします... ISO 3166-1を参照してください。

countries // 
    id              char(2)(P) // CA, MX, US, etc.
    iso3            char(3)(U) // CAN, MEX, USA, etc.
    iso_num         char(3)(U)
    name            varchar(50)(U) // Canada, Mexico, United States, etc.

確かに、このテーブルにさらに情報を追加したいと思うでしょうが、ここにいくつかの列があります...パスワードをハッシュする方法については、 PHP の crypt() 関数を参照してください。

customers
    id              unsigned int(P)
    first_name      varchar(50) // John, Mary, etc.
    middle_name     varchar(50) // Quincy, Louise, etc.
    last_name       varchar(50) // Doe, Public, etc.
    email           varchar(255) // me@privacy.com, etc.
    username        varchar(32) // blahblah, etc.
    password        varbinary(255) // hashed
    ...

このテーブルは、顧客を無制限の数のアドレスに接続します。

customers_addresses
    id              unsigned int(P)
    customer_id     unsigned int(F customers.id)
    address_id      unsigned int(F addresses.id)

この表にさらに情報を追加する必要がありますが、ここにいくつかの列を示します...

orders
    id                  unsigned int(P)
    created             datetime // 2013-08-28 13:24:53, etc.
    shipped             datetime // 2013-08-28 15:12:10, etc.
    customer_id         unsigned int(F customer.id)
    ship_address_id     unsigned int(F addresses.id)
    bill_address_id     unsigned int(F addresses.id)

各注文の一部であったすべての製品に注文番号を関連付けるテーブルが必要です。

orders_products
    id              unsigned int(P)
    order_id        unsigned int(F orders.id)
    product_id      unsigned int(F products.id)

この表にさらに情報を追加する必要がありますが、ここにいくつかの列を示します...

products
    id              unsigned int(P)
    name            varchar(50) // Widget A, Widget B, etc.
    height          unsigned int // height in inches, centimeters, whatever.
    width           unsigned int // width in inches, centimeters, whatever.
    depth           unsigned int // depth in inches, centimeters, whatever.
    weight          double // weight in ounces, pounds, grams, kilograms, whatever.

都市や国と同様に、不適切な可能性のあるデータを入力するのではなく、ユーザーが選択リストから選択できるようにします。ISO 3166-2を参照してください。

states
    id              unsigned int(P)
    country_id      char(2)(F countries.id)
    code            char(2) // AL, NF, NL, etc.
    name            varchar(50) // Alabama, Newfoundland, Nuevo León, etc.
于 2013-08-28T13:52:43.017 に答える
0

データベースの正規化と、少なくとも第 3 正規形に到達する理由を読んでください。

あなたの例では:

CRM
CRM.UniqueKey

Products 
Product.UniqueKey

customer_products (CP)
CRM.UniqueKey        -| combined make a composite unique key (unless you need to track history then you may want to
Product.Unique Key   -| add a start date )
CP.StartDate         -|
CP.EndDate           -| Start and end dates allow customers to add remove products active ones would always have                  
                     -| end date of null (but only do this if history is needed)

Customer_products は、2 つのプライマリ テーブル間の連想テーブルであり、顧客と製品の間の多対多の関係を解決します。

于 2013-08-28T13:00:02.130 に答える
0

顧客ごとにテーブルを作成するのではなく、単一のテーブルを使用して、顧客が「選択」した製品に顧客をリンクすることは正しいです。あなたの質問からは、顧客がどのように製品を選択するのかよくわかりません。Web サイトのその製品ページにアクセスすることによるものかもしれませんが、より一般的なシナリオは注文または請求書です。どちらの場合でも、テーブルは 2 つになります。たとえば、Invoices と Invoice_Items または Orders と Order_Items です。「アイテム」テーブルは、「参照」テーブルの主キーにリンクするアイテム テーブルの列の「外部キー」を介して、顧客を製品に結合します。

これで、各顧客が注文したアイテムまたは各顧客が購入したアイテムを表示できます。同じ概念を使用して、各顧客が訪問/レビューしたアイテムを、サイト訪問ごとまたは生涯ごとに表示できます。

于 2013-08-28T13:00:32.727 に答える