Нормализация таблицы с низкой целостностью

StackOverflow https://stackoverflow.com/questions/6110

  •  08-06-2019
  •  | 
  •  

Вопрос

Мне передали таблицу примерно с 18000 строками.Каждая запись описывает местоположение одного клиента.Проблема в том, что когда пользователь создавал таблицу, он не добавил поле для "Названия компании", только "Название местоположения", а у одной компании может быть много местоположений.

Например, вот несколько записей, описывающих одного и того же клиента:

Таблица местоположения

 ID  Location_Name     
 1   TownShop#1        
 2   Town Shop - Loc 2 
 3   The Town Shop     
 4   TTS - Someplace   
 5   Town Shop,the 3   
 6   Toen Shop4        

Моя цель - сделать так, чтобы это выглядело как:

Таблица местоположения

 ID  Company_ID   Location_Name     
 1   1            Town Shop#1       
 2   1            Town Shop - Loc 2 
 3   1            The Town Shop     
 4   1            TTS - Someplace   
 5   1            Town Shop,the 3   
 6   1            Toen Shop4        

Корпоративный стол

 Company_ID  Company_Name  
 1           The Town Shop 

Таблицы "Company" нет, мне нужно будет сгенерировать список названий компаний из наиболее описательного или наилучшего названия местоположения, которое представляет несколько местоположений.

В настоящее время я думаю, что мне нужно сгенерировать список похожих названий местоположений, а затем просмотреть этот список вручную.

Любые предложения о том, как я могу подойти к этому, приветствуются.

@Neall, спасибо за ваше заявление, но, к сожалению, каждое название местоположения отличается друг от друга, повторяющихся названий местоположений нет, только похожие.Таким образом, в результатах вашего утверждения "repcount" равен 1 в каждой строке.

@yukondude, Ваш шаг 4 - суть моего вопроса.

Это было полезно?

Решение

Пожалуйста, уточните вопрос: есть ли у вас в распоряжении список названий компаний?Я спрашиваю, потому что, возможно, вы сможете использовать алгоритм Левенштейна, чтобы найти связь между вашим списком названий компаний и названиями местоположений.


Обновить

Списка названий компаний нет, мне придется сгенерировать название компании из наиболее описательного или наилучшего названия местоположения, которое представляет несколько местоположений.

Ладно...попробуй это:

  1. Составьте список названий компаний-кандидатов, найдя названия местоположений, состоящие в основном или полностью из буквенных символов.Вы можете использовать регулярные выражения для этого.Сохраните этот список в отдельной таблице.
  2. Отсортируйте этот список в алфавитном порядке и (вручную) определите, какие записи должны быть названиями компаний.
  3. Сравните название каждой компании с названием каждого местоположения и получите оценку соответствия (используйте Левенштейн или какая-то другая строка, соответствующая алгоритму).Сохраните результат в отдельной таблице.
  4. Установите пороговый балл таким образом, чтобы любой результат совпадения < Пороговое значение не будет считаться совпадающим для данного названия компании.
  5. Вручную просмотрите LocationName по CompanyName | LocationName | matchScore и выясните, какие из них действительно совпадают.Заказ по рейтингу совпадений должен сделать процесс менее болезненным.

Вся цель вышеперечисленных действий состоит в том, чтобы автоматизировать отдельные части и ограничить масштаб вашей проблемы.Он далек от совершенства, но, надеюсь, избавит вас от необходимости вручную просматривать 18-каратные пластинки.

Другие советы

Мне уже приходилось это делать раньше.Единственный реальный способ сделать это - вручную сопоставить различные местоположения.Используйте консольный интерфейс вашей базы данных и группирующие инструкции select.Сначала добавьте поле "Название вашей компании".Тогда:

SELECT count(*) AS repcount, "Location Name" FROM mytable
 WHERE "Company Name" IS NULL
 GROUP BY "Location Name"
 ORDER BY repcount DESC
 LIMIT 5;

Выясните , какой компании принадлежит местоположение в верхней части списка , а затем обновите поле с названием вашей компании ...ГДЕ "Название местоположения" = оператор "Местоположение".

P.S.- Вам действительно следует разбить названия ваших компаний и местоположений на отдельные таблицы и ссылаться на них по их первичным ключам.

Обновить:- Ничего себе - никаких дубликатов?Сколько у вас пластинок?

Я собирался порекомендовать какой-нибудь сложный алгоритм сопоставления токенов, но это действительно сложно сделать правильно, и если ваши данные не имеют большой корреляции (опечатки и т.д.), То это не даст очень хороших результатов.

Я бы порекомендовал вам подать заявку в Амазонский Механический Турок и пусть человек во всем разбирается.

В идеале вам, вероятно, понадобилась бы отдельная таблица с именем Company, а затем столбец company_id в этой таблице "Location", который является внешним ключом к первичному ключу таблицы Company, вероятно, называемому id .Это позволило бы избежать значительного дублирования текста в этой таблице (более 18 000 строк, целочисленный внешний ключ сэкономил бы довольно много места над столбцом varchar).

Но вы все еще сталкиваетесь с методом загрузки этой таблицы Company и последующего правильного связывания ее со строками в Location.Общего решения нет, но вы могли бы сделать что-то в этом роде:

  1. Создайте таблицу Company со столбцом id, который автоматически увеличивается (зависит от вашей СУБД).
  2. Найдите все уникальные названия компаний и вставьте их в раздел Company.
  3. Добавьте столбец company_id в Location, который принимает значения NULL (на данный момент) и который является внешним ключом столбца Company.id.
  4. Для каждой строки в местоположении определите соответствующую компанию и ОБНОВИТЕ столбец company_id этой строки идентификатором этой компании.Это, вероятно, самый сложный шаг.Если ваши данные похожи на то, что вы показываете в примере, вам, вероятно, придется выполнить много попыток, используя различные подходы к сопоставлению строк.
  5. Как только все строки в Location будут иметь значение company_id, вы можете ИЗМЕНИТЬ таблицу Company, чтобы добавить ограничение NOT NULL в столбец company_id (при условии, что каждое местоположение должен иметь компанию, которая кажется разумной).

Если вы можете создать копию своей таблицы местоположений, вы можете постепенно создать серию инструкций SQL для заполнения внешнего ключа company_id.Если вы допустите ошибку, вы можете просто начать все сначала и перезапустить скрипт до момента сбоя.

Да, этот шаг 4 из моего предыдущего поста - потрясающий.

Несмотря ни на что, вам, вероятно, придется делать что-то из этого вручную, но, возможно, вы сможете автоматизировать большую часть работы.Для приведенных вами примеров местоположений запрос, подобный следующему, установит соответствующее значение company_id:

UPDATE  Location
SET     Company_ID = 1
WHERE   (LOWER(Location_Name) LIKE '%to_n shop%'
OR      LOWER(Location_Name) LIKE '%tts%')
AND     Company_ID IS NULL;

Я полагаю, что это соответствовало бы вашим примерам (я добавил IS NULL часть, чтобы не перезаписывать ранее установленные значения Company_ID), но, конечно, в 18 000 строках вам придется быть довольно изобретательным, чтобы обрабатывать различные комбинации.

Что-то еще, что могло бы помочь, - это использовать имена в Company для генерации запросов, подобных приведенному выше.Вы могли бы сделать что-то вроде следующего (в MySQL):

SELECT  CONCAT('UPDATE Location SET Company_ID = ',
        Company_ID, ' WHERE LOWER(Location_Name) LIKE ',
        LOWER(REPLACE(Company_Name), ' ', '%'), ' AND Company_ID IS NULL;')
FROM    Company;

Затем просто запустите инструкции, которые он выдает.Это могло бы сделать за вас большую часть гранжевой работы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top