2011-11-30 72 views
18

我犯了一個錯誤,我必須將1表分成2個。我有一個產品表,我需要分類表。當我開始的時候,我只有每個產品有1個類別,但沒有(有新的業務需求),我需要把產品放在多個類別中的能力。mysql分離表

我有一個產品表中有一個類別。

這裏的表:

product (id, name, category, price etc...) 

現在,我怎樣纔能有效地遷移這一點沒有讓我的網站下線?

我已經在CentOS

+0

category is varchar? –

+0

yes varchar(40)非空字段,因爲插入產品時需要該類別 – rcs20

回答

24

首先確保您的類別是唯一的。確保你沒有這樣的東西:

productx and produtx 

否則,當你將插入不好的類別。

你將不得不做,在步:

1)創建表類別

CREATE TABLE `category` (
    `id` int(10) unsigned NOT NULL auto_increment, 
    `name` varchar(40) NOT NULL DEFAULT 'General', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name` (`name`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

創建交集表,因爲產品可以在多個類別和種類可以有多個產品。

CREATE TABLE `product_category` (
    `product_id` int(10) unsigned NOT NULL, 
    `category_id` int(10) unsigned NOT NULL, 
PRIMARY KEY product_category (`product_id`,`category_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

2)將類別插入表中。

INSERT IGNORE INTO category SELECT DISTINCT category from product; 

這將使用唯一的ID插入非重複類別到類別表中。現在

,你在

INSERT IGNORE INTO `product_category` SELECT `product`.`id` AS `product_id`, `category`.`id` AS `category_id` FROM `category` LEFT JOIN `product` ON (`category`.`name` = `product`.`category`); 

3插入這些記錄),現在你必須修改代碼以使用正確的查詢: 例子:

SELECT 
/* your fields */ 
FROM 
product 
INNER JOIN product_category ON (product.id = product_category.product_id) 
INNER JOIN category ON (category.id = product_category.category_id) 
WHERE ... 

4)現在,當您對代碼更改感到滿意時,可以刪除未使用的列:

ALTER TABLE product DROP COLUMN category; 
+4

謝謝我有3類與名稱相似,並把查詢所有在一起,你的幫助表示讚賞 – rcs20

+0

你非常歡迎,讓我知道,如果你需要額外的幫助 –

+0

問題:你的查詢你把它將用於當我想要選擇我的產品?或類別?或兩者?以及爲什麼類別上的唯一鍵? – rcs20

0
INSERT INTO new_table_name ("product", "category") 
SELECT id, category 
FROM product; 

燈然後加在new_table_name ID的foriegn鍵約束它引用原始的產品表。在此之後,您可以alter table product drop column column_name

+3

MySQL服務器不支持SELECT ... INTO TABLE Sybase SQL擴展。相反,MySQL服務器支持INSERT INTO ... SELECT標準SQL語法,它基本上是一樣的。 – favoretti

3

創建一個表類:

CREATE TABLE category(id int primary key not null auto_increment, category varchar(40)) 

然後選擇從產品表中是唯一的類別:

INSERT INTO category (category) SELECT DISTINCT category FROM product; 

然後創建一個表關係:

CREATE TABLE product_to_category (product_id int, category_id int); 

如果你願意,你可以使用外鍵和約束。

然後你就可以遷移現有的關係:

INSERT INTO product_to_category SELECT product.id, category.id FROM product JOIN category on category.category=product.category; 

之後,調整您的代碼以使用新的結構,並從產品表中刪除類別欄:

ALTER TABLE product DROP COLUMN category; 

希望這有助於。

+0

感謝您的幫助 – rcs20

0

你會通過標準化產品表開始 - 創建2個新表:

CREATE TABLE categories 
(
    cat_id int AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    cat_label varchar(40) 
); 

CREATE TABLE product_by_category 
(
    pbc_prod_id int REFERENCES products(id), 
    pbc_cat_id int REFERENCES categories(cat_id), 
    #indexes for quicker lookup... 
    INDEX pbc(pbc_prod_id,pbc_cat_id), 
    INDEX cbp(pbc_cat_id, pbc_prod_id) 
); 



    INSERT INTO categories(cat_label) SELECT DISTINCT category FROM product; 
    INSERT INTO product_by_category(pbc_prod_id, pbc_cat_id) 
     SELECT id, (SELECT cat_id FROM categories WHERE categories.cat_label = product.category) 
     FROM products; 

    ALTER TABLE products DROP COLUMNN category; #do this after you are satisfied with contents of new tables. 

然後,你就必須創建的連接爲獲得產品按類別。

+5

OOps,它看起來像favoretti擊敗我與此類似的解決方案 – dar7yl

+0

你真的很花時間,包括適當的參考,甚至索引! :) – favoretti