MySQL - выбор данных из нескольких таблиц с одинаковой структурой, но разными данными


79

Хорошо, вот моя дилемма. У меня есть база данных, состоящая примерно из 5 таблиц с одинаковой структурой данных. Данные разделяются таким образом для целей локализации и разбивают в общей сложности около 4,5 миллионов записей.

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

столбцы данных:

id, band_name, song_name, album_name, genre

Статус MySQL:

SELECT * from us_music, de_music where `genre` = 'punk'

MySQL выдает эту ошибку:

#1052 - Column 'genre' in where clause is ambiguous

Очевидно, я делаю это неправильно. Кто-нибудь хочет пролить свет на это для меня?

Ответы:


177

Я думаю, вы ищете пункт UNION , а-ля

(SELECT * from us_music where `genre` = 'punk')
UNION
(SELECT * from de_music where `genre` = 'punk')

@ mihai-limban - извините за беспокойство, но есть ли способ узнать из набора результатов, «какой результат был из какой таблицы». Beacuse, если нам нужно обновить / удалить запись из этого набора результатов, нет никакого способа узнать.
web-nomad

7
@Pushpesh добавляет уникальный строковый идентификатор к каждому SELECT, например:(SELECT 'us_music' AS from_table, * FROM us_music WHERE genre = 'punk') UNION ...
jkrcma

Какое значение жанра неизвестно, но идентификаторы должны совпадать в двух таблицах? Вы можете сделать что-нибудь подобное? (SELECT 1) AS select1 UNION (SELECT 2) AS select2 WHERE select1.id=select2.id
ZurabWeb

Отлично, именно поэтому я люблю Stack! Google, найдите вопрос и ответ о стеке уже здесь! Благодаря!
Rocco The Taco

Каков синтаксис для группировки в UNION набора результатов, а затем также выполнения упорядочения по? Допустим, это viewCountи movieTitleгде по одной БД на каждый месяц. Вы объединяете все 12 таблиц вместе, что нормально, но тогда вы получаете 12 отдельных наборов результатов на выходе. Что, если вам нужен только один набор результатов, в котором все результаты были бы сгруппированы, movieTitleа viewCountзначение суммировалось для каждой movieTitleстроки?
anon58192932

19

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

Добавьте новый столбец, который можно использовать для различения пяти языков (я предполагаю, что это язык, который отличается в таблицах, поскольку вы сказали, что он предназначен для локализации). Не беспокойтесь о 4,5 миллиона записей. Любая настоящая база данных может справиться с таким размером без проблем. Добавьте правильные индексы, и у вас не будет проблем с ними как с единой таблицей.


Изначально у меня были все мои данные в одной таблице, но она начала почти сканироваться в течение 5-10 секунд после примерно 3,5 миллионов записей. Я обнаружил, что для меня лучше всего сработало разделение, потому что это было намного быстрее. У меня сейчас новый веб-хостинг, так что он может быть лучше, но кажется слишком
хлопотным,

26
Похоже, вам нужно добавить индексы в таблицы.
Нед Батчелдер

1
Да, вы, по сути, устранили симптом проблемы, не решив основную проблему (неправильное / недостаточное индексирование). Что будет дальше, если одна из ваших 5 таблиц достигнет 4,5 млн строк и снова начнет сканирование?
Lo-Tan

5

Любой из приведенных выше ответов действителен, или альтернативный способ - расширить имя таблицы, чтобы включить имя базы данных, например:

SELECT * from us_music, de_music where `us_music.genre` = 'punk' AND `de_music.genre` = 'punk'

что дает вам очень плохо определенный набор результатов: все возможные пары us_ и de_ punk.
Дэвид Шмитт

4

Столбец неоднозначен, потому что он появляется в обеих таблицах, вам нужно будет полностью указать поле where (или сортировку), например us_music.genre или de_music.genre, но вы обычно указываете две таблицы, если собираетесь затем объединить их вместе в какая-то мода. Структуру, с которой вы имеете дело, иногда называют секционированной таблицей, хотя обычно это делается для разделения набора данных на отдельные файлы, а не просто для произвольного разделения набора данных. Если вы отвечаете за структуру базы данных и нет веских причин для разделения данных, я бы построил одну большую таблицу с дополнительным полем «origin», содержащим код страны, но вы, вероятно, делаете это из законных соображений производительности. . Либо используйте объединение, чтобы присоединиться к вашим столам » http: //dev.mysql.http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html .


3

Ваша первоначальная попытка охватить обе таблицы создает неявное СОЕДИНЕНИЕ. Это не одобряется большинством опытных программистов SQL, потому что это разделяет таблицы, которые должны быть объединены с условием, как.

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


3

unionЗаявление причины некоторого времени сделки в больших объемах данных. Выбор желательно выполнить в 2 этапа:

  1. выберите идентификатор
  2. затем выберите с ним основную таблицу
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.