2012-05-23 3 views
2

Я работаю над системой, в которой записи базы данных периодически создаются на основе входного потока данных. Иногда приходит некоторый вклад, который дает доказательства того, что две независимо созданные записи должны быть объединены в один. Я ищу рекомендации о способах слияния в базе данных.рекомендуемые методы для слияния записей базы данных

Основная таблица (которая представляет собой просто конструкцию в этой точке) содержит записи, состоящие из уникального идентификатора (назовите его основным идентификатором, который назначается базой данных, MySQL в моей системе) и некоторыми полями данных. Существуют также некоторые другие таблицы, которые используют основной идентификатор, чтобы связать свои записи с записью в главной таблице.

MainTable: 
int mainID 
blob data 
... 

OtherTable: 
int otherID 
int mainID 
blob otherData 
... 

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

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

Идея, которую я рассматриваю, заключается в том, чтобы представить таблицу слияния с двумя ключевыми полями: и исходный основной идентификатор и текущий основной идентификатор. Его целью является присвоение одного основного идентификатора другому. По мере создания каждой записи основной таблицы мы добавляем запись в таблицу слияния, сопоставляя основной идентификатор вновь созданной записи основного стола. Если происходит слияние, мы просто обновляем текущее поле основного идентификатора в таблице слияния для записи с исходным основным идентификатором для основной записи, которая сливается. Затем для каждого запроса, основанного на основном ID, мы сопоставляем этот идентификатор с помощью таблицы слияния, чтобы найти эффективный основной идентификатор, который мы действительно должны использовать.

MergeTable: 
int mergeID 
int originalMainID 
int currentMainID 

Это хорошая техника? Может ли отображение легко выполняться в SQL-запросах? Существуют ли стандартные или лучшие методы, которые я должен рассматривать вместо этого?

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

ответ

2

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

SELECT * 
    FROM MainTable 
    WHERE mainID = 1 
UNION ALL 
SELECT MainTable.* 
    FROM MergeTable 
    INNER JOIN MainTable 
    ON MainTable.mainID = MergeTable.currentMainID 
    WHERE MergeTable.originalMainID = 1 
LIMIT 1 

Идея заключается в том, что в большинстве случаев, первый запрос будет успешным и возвращать результат, и MySQL будет прервана второй запрос, так как LIMIT выполняется. Если первый запрос не возвращает никаких результатов, он перейдет к второму запросу и выполнит объединение в таблице слияния, чтобы убедиться, что оно было объединено.

Согласно MySQL, относительно LIMIT:

Как только MySQL послал требуемое число строк клиенту, он прервет запрос, если вы не используете SQL_CALC_FOUND_ROWS.

Если объединенные записи являются исключением, а не правилом, то это сэкономит много, много соединений.

Вы также можете сделать это с помощью двух запросов, если запрос UNION слишком страшен. Вы можете просто проверить, существует ли запись, а если нет, то проверьте таблицу слияния.

+0

Хороший ответ, Маркус. +1. Я надеялся получить больше ответа от сообщества. Не могли бы вы рассказать о том, почему мой вопрос так мало интересует? Это слишком сложно или слишком редко делается (и если да, то почему?)? Благодарю. –

+0

@RandallCook, я выполняю такие запросы все время в одной из наших конкретных систем. Я запускаю один запрос, и если я не получу никаких результатов, я запустил другой запрос в другую таблицу. Я не думаю, что это слишком необычно. Вопросы здесь хит или промах. Иногда длинный вопрос уводит людей, иногда это просто плохое время суток. –

+0

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