2011-11-30 13 views
18

cometí un error y tengo que dividir 1 tabla en 2. tengo una tabla de productos y necesito una tabla de categorías. cuando comencé, solo tenía 1 categoría por producto, pero no (con nuevos requisitos de negocio) necesito la capacidad de poner un producto en una categoría múltiple.tablas de separación mysql

tengo una tabla de productos que tiene una categoría.

aquí está la tabla:

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

ahora, ¿Cómo puedo migrar de manera eficiente esto sin hacer que mi sitio fuera de línea?

TENGO lámpara en centos

+0

categoría es varchar? –

+0

sí varchar (40) campo no nulo, ya que la categoría es necesaria al insertar el producto – rcs20

Respuesta

24

Primero asegúrese de que sus categorías sean exclusivas. Asegúrese de no tener algo como:

productx and produtx 

De lo contrario, cuando inserte categorías incorrectas.

Tendrá que hacerlo en el paso:

1) Creación de la categoría de la tabla

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; 

Cree la tabla de intersección ya que un producto puede estar en categorías múltiples y una categoría puede tener múltiples producto.

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) inserta las categorías en la tabla.

INSERT IGNORE INTO category SELECT DISTINCT category from product; 

Esto insertará categorías no duplicados en la tabla de categorías con un identificador único.

Ahora, usted tiene que inserta estos registros en el

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) Ahora tiene que modificar su código con el fin de utilizar la consulta derecha: Ejemplo:

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) Ahora, cuando se sienta cómodo con sus cambios de código, puede soltar la columna no utilizada:

ALTER TABLE product DROP COLUMN category; 
+4

gracias tuve 3 categorías con un nombre similar y para poner todas las consultas juntas, tu ayuda es apreciada – rcs20

+0

eres bienvenido, avísame si necesitas ayuda adicional –

+0

pregunta: tu consulta que pones será utilizada para cuando ¿Quieres seleccionar mis productos? o categorías? ¿o ambos? y por qué clave única en la categoría? – rcs20

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

A continuación, añadir una restricción de clave externa de id en new_table_name que hace referencia a la tabla producto original. Después de esto, puede alter table product drop column column_name.

+3

El servidor MySQL no es compatible con SELECT ... INTO TABLE Extensión de Sybase SQL. En cambio, el servidor MySQL admite INSERT INTO ... SELECT la sintaxis SQL estándar, que es básicamente lo mismo. – favoretti

3

Crear una categoría tabla:

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

A continuación, seleccione categorías únicas de tabla de productos:

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

A continuación, crear una tabla para las relaciones:

CREATE TABLE product_to_category (product_id int, category_id int); 

Si lo desea, puede usar claves y restricciones foráneas

A continuación, puede migrar las relaciones existentes:

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

Después de eso, ajustar el código para utilizar la nueva estructura y soltar la columna de la categoría de la tabla de productos:

ALTER TABLE product DROP COLUMN category; 

Espero que esto ayude.

+0

gracias por su ayuda – rcs20

0

Se podría empezar por la normalización de su tabla de productos - la creación de 2 nuevas tablas:

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. 

Entonces se tendría que crear combinaciones para conseguir los productos por categoría.

+5

OOps, parece que me gustó esto con una solución similar – dar7yl

+0

La tuya es más clara ya que de hecho se tomaron el tiempo para incluir referencias adecuadas e incluso índices. :) – favoretti