разделяющие таблицы mysql
Я допустил ошибку, и мне нужно разделить 1 таблицу на 2. у меня есть таблица продуктов, и мне нужна таблица категорий. когда я начинал, у меня была только 1 категория на продукт, но (с учетом новых бизнес-требований) мне нужна возможность поместить продукт в несколько категорий.
У меня есть таблицы продуктов, в которых есть категория.
Вот таблица:
product (id, name, category, price etc...)
Теперь, как я могу эффективно перенести это, не переводя свой сайт в автономный режим?
У меня есть лампа на centos
4 answers
Сначала убедитесь, что ваши категории уникальны. Убедитесь, что у вас нет чего-то вроде:
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;
Это будет вставьте не повторяющиеся категории в таблицу категорий с уникальным идентификатором.
Теперь вам нужно вставить эти записи в
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;
Создайте категорию таблицы:
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;
Надеюсь, это поможет.
INSERT INTO new_table_name ("product", "category")
SELECT id, category
FROM product;
Затем добавьте ограничение ключа foriegn для идентификатора в new_table_name, которое ссылается на исходную таблицу продуктов. После этого вы можете alter table product drop column column_name
.
Вы бы начали с нормализации таблицы продуктов - создания 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.
Затем вам нужно будет создать объединения для получения товаров по категориям.