Как победить дубли в базе данных: реальный кейс проектирования каталога медицинских товаров
Как победить дубли в базе данных: реальный кейс проектирования каталога медицинских товаров
Реальный проект. Реальная база. Реальные дубли. И — конкретные решения, как всё разложить по полочкам, не потеряв целостность данных.
Когда структура начинает дышать — нужны чёткие правила
Разработка каталога медицинских товаров — это не просто список позиций. Это живая архитектура: с категориями, подкатегориями, внутренними группами, привязками, вложенностями и товарами, у каждого из которых своя специфика и технические требования.
Так случилось и в одном из проектов: в каталоге присутствовали изделия для биопсии — иглы, пистолеты, расходные материалы. Множество подгрупп, схожие названия, одинаковые URL. И внезапно — дубли.
В SQL-таблице `catalog_subcategories` начали возникать повторяющиеся записи с одними и теми же URL. Что делать? Чистить вручную? Неэффективно. Нужно решение — точное, технологичное и масштабируемое.
Что было: структура на грани хаоса
- Таблицы: товары, категории, подкатегории, вложенные группы
- Связи: один ко многим (`category_id`, `parent_id`)
- Ошибки: повторяющиеся `INSERT`, нарушенные связи, слетевшие индексы
Пример: добавляется подкатегория «ИГЛЫ ДЛЯ BIOPSY MAGNUM (BARD)». Если разработчик или оператор делает это дважды — без защиты от дублей — появляются лишние строки. А с ними и сбои при связке товаров, путаница в интерфейсе, сломанные страницы.
Как победить дубли и не потерять данные?
1. INSERT IGNORE: мягкий способ
Добавляет строку только в том случае, если не нарушается уникальный индекс (в нашем случае — по полю url).
INSERT IGNORE INTO catalog_subcategories (category_id, name, url, parent_id)
VALUES (1, 'ИГЛЫ ДЛЯ BIOPSY MAGNUM (BARD)', 'igly-biopsy-magnum-bard', 27);
Такой подход — идеален для начальной загрузки каталога или при работе с импортом из Excel. Безопасно, без ошибок, но и без обновлений старых данных.
2. INSERT ... ON DUPLICATE KEY UPDATE: обновляем дубликаты
Уже более гибкий способ: если строка с таким url уже существует — она будет обновлена, а не вставлена заново.
INSERT INTO catalog_subcategories (category_id, name, url, parent_id, description)
VALUES (1, 'ИГЛЫ ДЛЯ BIOPSY MAGNUM (BARD)', 'igly-biopsy-magnum-bard', 27, 'Описание...')
ON DUPLICATE KEY UPDATE
name = VALUES(name),
description = VALUES(description);
Этот способ — палочка-выручалочка при редактировании структуры. Особенно когда одновременно работают редактор и программист.
3. Проверка через NOT EXISTS: логическая защита
Если уникальный ключ не установлен — можно защититься логически.
INSERT INTO catalog_subcategories (category_id, name, url, parent_id)
SELECT 1, 'ИГЛЫ FAST GUN', 'igly-fast-gun', 27
WHERE NOT EXISTS (
SELECT 1 FROM catalog_subcategories WHERE name = 'ИГЛЫ FAST GUN' AND parent_id = 27
);
Подходит, если уникальность определяется не по одному полю, а по комбинации (например, name parent_id).
4. Визуальное подтверждение структуры: не терять иерархию
Иерархия — основа логики каталога. Категории → Подкатегории → Вложенные подгруппы. Нельзя терять цепочки.
Поэтому в структуре БД обязательно:
category_idс внешним ключом на таблицуcatalog_categoriesparent_idс внешним ключом на саму таблицуcatalog_subcategories— для вложенности
FOREIGN KEY (parent_id) REFERENCES catalog_subcategories(id) ON DELETE SET NULL
Такой подход позволяет, например, удалить "родителя", но сохранить вложенные группы без обрыва связей.
Что в итоге? Контроль. Чистота. Уверенность.
В проекте был внедрён подход ON DUPLICATE KEY UPDATE для всех точек ввода. Установлен уникальный индекс по полю url, добавлено поле description — чтобы хранить технические пояснения для подкатегорий. Вся структура выстроена через parent_id, с чёткими связями и возможностью вложенности до любого уровня.
А значит — каталог теперь живёт своей логичной, понятной жизнью. Без дублей, без ручных правок, без риска потери данных.
Хочешь такую же структуру — чистую, управляемую, масштабируемую?
Разработаю архитектуру базы под ваш проект — от идеи до продуманной реализации. Особенно если у вас — медицина, оборудование, логистика, каталог с вложенностью. Пишите.