Как выбрать строку в MySQL, которая содержит несколько значений?

0

У меня есть таблица MySQL, которая выглядит так:

Table: Designer
  id: integer  
  name: String
  gallery: string

Строка галереи может содержать строковое значение, например 23,36,45

Теперь я хочу сделать запрос, похожий на этот:

SELECT * FROM Designer WHERE gallery = '36'

Я знаю, что я использую LIKE, но этого недостаточно. Это может вернуть как 36, так и 136.

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

Итак, как я могу выбрать строку с номером 36?

UPDATE
Хорошо, так как меня прибивают к плохому дизайну (да, я знаю, это было), теперь я вижу очевидное.

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

Simple. Но не всегда логично, когда он 3AM, и вы уже работали 15 часов;)

  • 3
    Никогда не используйте в MySQL строку, содержащую несколько значений. Но создайте другую таблицу, которая содержит несколько строк, связанных с этой строкой.
  • 0
    хм ... я не уверен, кто отрицает все ответы здесь ....
Показать ещё 2 комментария
Теги:

4 ответа

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

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

select * from designer
    where gallery like '36,%'
       or gallery like '%,36'
       or gallery like '%,36,%'
       or gallery = '36'

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


Однако, несмотря на ваши возражения против, что вам нужно сделать, это перестроить вашу схему, например:

designer:
    id             integer primary key
    name           varchar(whatever)
designer_galeries:
    designer_id    integer foreign key references designer(id)
    gallery        string
    primary key    (designer_id,gallery)

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

  • 0
    Я довольно компетентен в разработке БД, и я знаю, что это был плохой дизайн. Но я устал думать (и не использовал ручку и бумагу при проектировании). Так что да, добавление внешнего ключа в таблицу галереи, безусловно, является лучшим решением!
  • 0
    @ Steven, вы можете использовать первое решение, если вас не очень заботит производительность. Например, это вполне приемлемо, если вы знаете, что ваша таблица никогда не будет превышать 100 строк и не будет обрабатываться более чем несколькими одновременными запросами, поскольку в этом случае вам, вероятно, не нужна профессиональная производительность СУБД. Это - игра YAGNI. Просто, по моему опыту, столы никогда не бывают такими маленькими, как вы ожидали :-)
Показать ещё 1 комментарий
3

Если вам нужно сделать это, вы плохо разработали свои таблицы.

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

SELECT *
FROM Designer
INNER JOIN Gallery
ON Gallery.id = 36
AND Designer.id = Gallery.designer
  • 0
    Нет, галерея может принадлежать только одному дизайнеру. Но дизайнер может иметь много галерей. Смотрите мое обновление.
  • 0
    Я отредактировал свой пост.
Показать ещё 2 комментария
2

Я также согласен, что это плохо спроектированная структура таблицы, но вот ответ

SELECT * FROM Designer where FIND_IN_SET(36,gallery)
  • 0
    Это работает как шарм. Благодарю.
  • 0
    Кто-то проголосовал за ответ, если ответ работает, пожалуйста, проголосуйте :)
Показать ещё 1 комментарий
-3

Вместо этого вы можете использовать регулярные выражения в своем предложении WHERE.

http://dev.mysql.com/doc/refman/5.1/en/regexp.html

SELECT * FROM Designer WHERE gallery REGEXP "(,|^)(36)(,|$)"

Ещё вопросы

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