У меня есть таблица 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 часов;)
Вы действительно не должны хранить свои данные, поскольку это делает запросы ужасно неэффективными. Для этого конкретного случая использования вы можете (если вы не заботитесь о производительности) использовать:
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)
Тогда ваши запросы будут ослепительно быстрыми. Одна из первых вещей, которые вы должны проследить, - это всегда разрабатывать вашу схему для третьей нормальной формы. Вы можете вернуться к другим формам производительности, как только вы поймете компромиссы (и знаете, как смягчить проблемы), но это редко необходимо, если только ваша база данных не ужасно запутана.
Если вам нужно сделать это, вы плохо разработали свои таблицы.
У одного дизайнера может быть много галерей, а галерея принадлежит одному дизайнеру, поэтому вы должны создать "конструктор" внешнего ключа в своей таблице "Галерея", и ваш запрос будет
SELECT *
FROM Designer
INNER JOIN Gallery
ON Gallery.id = 36
AND Designer.id = Gallery.designer
Я также согласен, что это плохо спроектированная структура таблицы, но вот ответ
SELECT * FROM Designer where FIND_IN_SET(36,gallery)
Вместо этого вы можете использовать регулярные выражения в своем предложении WHERE.
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
SELECT * FROM Designer WHERE gallery REGEXP "(,|^)(36)(,|$)"