MySQL использует Filter Table на массиве других таблиц

0

У меня две таблицы: профиль и hobbie

Каждый профиль отключен, чтобы выбрать hobbie, что будет безопасно в profile.p_hobbies как массив id (например: [1,5,7,8,9])

Теперь я хочу получить имена профиля hobbie. У меня должно быть что-то звено:

SELECT hobbie.h_name
FROM profile, hobbie
WHERE profile.p_id=37 AND hobbie.h_id IN profile.p_hobbies

Результатом является сбой # 1064

# 1064 - Fehler in der SQL-синтаксис. Bitte die korrekte Синтаксис im Handbuch nachschlagen bei 'profile.p_hobbies LIMIT 0, 25' в Zeile 3

Я уже использую метод IN в других SQL-Querys. Думаю, я не могу использовать его, если массив, который я хочу использовать, также является данными из базы данных SQL?

Есть ли что-нибудь, что я могу сделать, не используя несколько запросов?

Я использую MariaDB-9

  • 1
    MySQL не поддерживает массивы так, как PostgreSQL. Во-вторых, хранение CSV в качестве значения столбца не лучшая идея.
  • 0
    Какая связь между таблицами? как они связаны?
Теги:
arrays
mariadb

2 ответа

3
Лучший ответ

Это слишком долго для комментария.

В MySQL нет такой вещи, как тип массива. У вас возникла проблема с вашей структурой данных. У вас должна быть таблица объединения/соединения, с одной строкой для каждого пользователя и хобби. Что-то вроде этого:

create table profileHobbies (
    profileHobbieId int auto_increment primary key,
    profileId int,
    hobbieId int,
    foreign key (profileId) references profiles(profileId),
    foreign key (hobbieId) references hobbies(hobbieId)
);

Строки будут выглядеть так:

profileHobbieId   profileId   HobbieId
       1              1           1
       2              1           3
       3              1           5

Тогда ваш запрос будет выглядеть так:

SELECT h.h_name
FROM profileHobbies ph JOIN
     hobbie h
     ON ph.hobbie_id = h.hobbie_id
WHERE ph.profile_id = 37 ;

Существует много причин, по которым вы не хотите хранить список хобби в виде строки с разделителями. Вот некоторые:

  • Ид - целые числа. Данные должны храниться с использованием правильного типа, и целые числа не являются строками.
  • Внешние ключевые отношения должны быть должным образом провозглашены.
  • SQL имеет отвратительные возможности обработки строк.
  • Строковые функции, необходимые для управления списком, не позволяют оптимизатору использовать индексы.
  • SQL имеет действительно отличную структуру данных для хранения списков. Он называется таблицей, а не строкой.
1

Ваш лучший выбор - нормализовать ваши данные. Хранение наборов чисел в виде списков с разделителями-запятыми считается ошибочным в SQL. Почему вредно?

  • он не масштабируется хорошо, потому что он не может использовать индексы для поиска
  • обновление наборов чисел затруднительно; рассмотрим проблему удаления 2 из 1,2,3,4. Это беспорядок в SQL.

Некоторые варианты SQL поддерживают функцию обновления. Но проблема масштабирования все еще существует. (Не будьте слишком оскорблены в этом совете: большинство из нас в тот или иной момент допустило эту ошибку в дизайне базы данных).

У вас много отношений между профилями и хобби. Поэтому вам нужна таблица с именем profile_hobbie с двумя столбцами в ней, p_id и h_id. Когда профиль начинает делать хобби, вы вставляете строку в profile_hobbie с идентификатором профиля и хобби. Если профиль перестает делать хобби, вы удаляете эту строку.

Тогда ваш запрос будет выглядеть так:

  SELECT hobbie.h_name
    FROM profile
    JOIN profile_hobbie ON profile.p_id = profile_hobbie.p_id
    JOIN hobbie ON profile_hobbie.id = hobbie.h_id
   WHERE profile.p_id=37

Это даст (возможно, пустой) список хобби для выбранного профиля.

Вы также можете попробовать использовать функцию MySQL FIND_IN_SET(), но вы можете столкнуться с ошибкой преобразования между целыми числами и строками.

   SELECT hobbie.h_name
     FROM profile
     JOIN hobbie ON (FIND_IN_SET(hobbie.h_id, profile.p_hobbies) > 0)

Но, Гордон прав. Это использует отвратительную обработку строк.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню