2013-08-28 21 views
1

我剛剛剛接觸(mysql)數據庫設計,並希望得到您對以下問題的反饋。我正在開發一個鏈接到一個mysql數據庫的網站,該數據庫應該包含客戶信息和產品信息。對於一般的客戶信息(姓名,地址,出生日期等),我創建了一個表'crm',用於一般產品信息(產品描述可用)。我創建了一個表'產品'。每個客戶的數據庫表或帶有鏈接表的數據庫設計?

我的問題是如何存儲每個客戶選擇的產品列表?這個列表當然會隨每個客戶而變化,並且隨着時間的推移也會變化。此外,表格「產品」可能隨時間而改變(新產品被添加或現有產品被移除)。首先,我介紹了一個設計「顧客產品」的表格,每個顧客都選擇了一些產品,但是在閱讀本網站相關頁面的一些評論後,我質疑這是否是一個好的設計(因爲這可能導致超過10萬張表格)。另一種解決方案可以與單個表'客戶產品的使用環節是這樣設計的:

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' 

這會替代的解決方案是好的,也有更好的建議?

感謝您的反饋。

回答

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's crypt() function對於如何散列密碼。

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) // [email protected], 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. 
+0

thnx爲詳細示例,非常有幫助(!!) – Joppo

+0

PS:關於您的示例,還有一個(初學者)問題:您爲什麼選擇將客戶地址信息放在單獨的表格中而不是表格客戶中? – Joppo

+0

@ user2543182 - 因爲他們可能會給我們1,2,... N個地址隨着時間的推移。也許他們想要一些東西運到他們的房子,也許他們希望運送到他們的工作。也許到他們堂兄的家......如果我們給自己存儲所有這些地址的機會,那麼我們可以讓客戶看到他們使用過的所有過去地址的列表,並讓他們選擇他們想要用於當前訂單。 –

0

閱讀數據庫規範化和至少達到第三範式的原因。

在你exammple:

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是兩個主要的表之間的關聯表,並解決客戶與產品之間的許多一對多的關係。

0

你是對的,你不想爲每個顧客製作一張桌子,並且你會用一張桌子將顧客連接到顧客已經「選擇」的產品上。我不清楚你的問題,顧客如何選擇產品。也許是通過訪問您的網站上的產品頁面,但更典型的情況是訂單或發票。無論哪種情況,你都會有兩張桌子。例如發票和Invoice_Items或Orders和Order_Items。 「Items」表通過鏈接到「參考」表的主鍵的項目表中的列中的「外鍵」將客戶連接到產品。

現在您可以顯示每個客戶訂購的物品或每個客戶購買的物品。您可以使用相同的概念來顯示每個客戶訪問/審閱的項目,無論是實地訪問還是終身訪問。

+0

thnx(!)。如果我正確理解您的建議,它看起來類似於http://www.w3schools.com/sql/sql_foreignkey.asp和http://www.w3schools.com/sql/sql_join_inner.asp上的(第一個)示例(正確? )。如果我還想爲每個客戶存儲某種監控數據(由客戶所在地的監控設備創建),比如表'monitoring_data',那麼您的建議概念是否也適用?我忘了提及每個客戶的私人網頁將查看訂購和購買的產品以及他們的監控數據。 – Joppo