SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 01.01.2009 04:38:30

RB
Участник
Откуда: Россия
Зарегистрирован: 01.01.2009
Сообщений: 4

Поле с перечислением. Поиск по такому полю.

С Новым годом.

Допустим, имеются две таблицы: "книги" (books) из трех столбцов (id, title, genre) и "жанры" (genres) из двух столбцов (id, name). Книги бывают одножанровые, а бывают и многожанровые, поэтому books.genre – поле, где вполне может быть перечислено что-то вроде "1,3,10", причем числа – указатели на genres.id

Предположим, что мы хотим найти книги, принадлежащие определенному жанру или группе жанров. С помощью какого запроса это осуществимо и осуществимо ли вообще? Понятно, что "SELECT title FROM books WHERE genre = $q" здесь не подойдет, т.к. сверка будет происходить по всей длине поля, а мне надо, чтобы "глядя" на запись "1,3,10" мистер мускул сумел определить, что в ней содержится число "1" или "3", а возможно одновременно "1" и "3" (в зависимости от того, хотим мы прочесать books по одному жанру или же по двум и более). Очевидно, проблема решаема с использованием регулярных выражений, но не будет ли это слишком круто при наличии в базе 10-20 тысяч наименований книг? У каждой проверять жанры посредством REGEXP...

Надеюсь, объяснил доступно. Может быть, это вообще глупая затея, хранить список жанров к каждой книге именно в таком виде, в котором я описываю? Может есть более оптимальный и разумный способ?

Спасибо.

Отредактированно RB (01.01.2009 05:24:29)

Неактивен

 

#2 01.01.2009 05:56:02

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Поле с перечислением. Поиск по такому полю.

Вот гики сидят на форуме, а? Ну ладно - меня разбудили, но получить в такое время почту? smile
С новым годом smile

Обычно для обеспечения такой связи используют дополнительную табличку. Т.е. предлагаю
Вам сделать такую структуру:
  books (id, title)
  genres (id, names)
  book_genres (book, genre, primary key (genre, book))

Тогда записи "1,3,10" оригинальных данных будут соответствовать 3 строки новой таблицы.
А Выборка будет происходить, разумеется, простым JOIN

SELECT *
FROM books b
JOIN book_genres bj ON b.id = bj.book
JOIN genres j ON j.id = bj.genre
WHERE j.name = "Фантастика"


P.S. Таки лучше спать сейчас, а то наворотите smile

Неактивен

 

#3 01.01.2009 19:18:12

RB
Участник
Откуда: Россия
Зарегистрирован: 01.01.2009
Сообщений: 4

Re: Поле с перечислением. Поиск по такому полю.

Благодарю. Кратко, компетентно, доступно. Thanx smile
Пойду спать... big_smile

Неактивен

 

#4 02.01.2009 01:12:37

RB
Участник
Откуда: Россия
Зарегистрирован: 01.01.2009
Сообщений: 4

Re: Поле с перечислением. Поиск по такому полю.

Возник вопрос! smile Почему мы определяем Primary Key сразу для двух полей?

Неактивен

 

#5 02.01.2009 10:05:40

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Поле с перечислением. Поиск по такому полю.

Он обеспечивает уникальность строк. Чтобы одна и та же книга не принадлежала одному
и тому же жанру дважды. Порядок выбран для скорости поиска (при поиске всегда
используется сначала первый столбец, а потом уже второй - если нужно).

P.S. Интересно, как меня угораздило заалиасить genres в j, а не в g? smile

Неактивен

 

#6 02.01.2009 19:47:45

RB
Участник
Откуда: Россия
Зарегистрирован: 01.01.2009
Сообщений: 4

Re: Поле с перечислением. Поиск по такому полю.

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

book (id, title, primary key (id))
genre (id, name, primary key (id))
linkGenre (book, genre, primary key (book, genre))

SELECT t1.genre, t2.name
FROM linkGenre AS t1, genre AS t2
WHERE t1.book = $book[id] AND t2.id = t1.genre


Разумно ли в этом случае обходиться без JOIN?

Отредактированно RB (02.01.2009 20:28:03)

Неактивен

 

#7 02.01.2009 21:17:07

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Поле с перечислением. Поиск по такому полю.

Запятая эквивалентна JOIN

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson