Всем привет и хорошего настроения! Столкнулся с простой задачей, но но не доходит до меня как лучше это реализовать. Задача такова. Нужно обратиться к базе mysql и найти строки в которых в столбце city содержится город "city2" из перечисленных через запятую городов в ячейке. Имею ввиду запрос типа SELECT * from table1 WHERE city="city2" Строки выглядят таки образом: table1 id----city----------------------------------------------region 0-----city1,city2,city3,city4,city5-----------------region1 1-----city6,city7,city2,city8,city9-----------------region2 2-----city10,city11,city12,city13,city14---------region3 В первой и второй сроке есть этот город city2, а в 3й нет. Нужно получить строки в которых он есть Использовать mysql запрос или же поместить всю базу в массив и воспользоваться поиском по массиву? Какой вариант лучше и как его реализовать? Или же ваш вариант. Рассмотрю любые Спасибо!
@dich40000, есть отличный вариант перед тем как что-то делать, сначала выучить теорию, а потом переходить к практике. Начни с гугления, что такое нормализация бд, подумай каким образом ты нарушил её первый закон и почему он первый и почему он ЗАКОН.
Бро, скажи, а чем ты все это время занимался, если не секрет? Тебе нужно использовать это: http://unetway.com/tutorial/sql-operator-like/
Спасибо, за помощь. Про оператор Like знаю, думал можно ли это реализовать с помощью других операторов или like вполне достаточно? --- Добавлено --- Имеете в виду, что запись через запятую не стоит использовать, а нужно создать дополнительные строки с одним значением в ячейке?
Да, только не просто дополнительные строки, а строки в другой таблице и отношение "один ко многим". Ну и конечно же учиться объединять эти таблицы пользуясь конструкцией JOIN. А про LIKE лучше вспоминать как можно реже.
@Valick прав. но я таки дам плохой (тормозной) но рабочий вариант решения: функция mysql find_in_set() а like тут точно не подойдёт. таки делай в нормальной форме. не привыкай к костылям! --- Добавлено --- @dich40000 --- Добавлено --- 5 сообщений вместе с сегодняшними и беджик "активный пользователь". какая ирония!
Вполне достаточно, да. Хотя вон камрад artoodetoo что-то пишет про скорость - тут ничего уже не скажу, насчет скорости ему видней - он с SQL больше дела имеет. --- Добавлено --- ...можешь по идее еще это поле сделать в формате JSON и паковать списки в этот формат - так будет логичнее всего. Но таки LIKE по слухам быстрее будет)) это может иметь значение при больших выборках
like - плохая история. О нём вспоминать надо как можно реже. Лучше всего таблицу нормализовать. Самый адекватный подход. Хуже = find_in_set. JSON - неплохо, но понадобятся ещё телодвижения: просто сделать поле json будет недостаточно. Во-первых, структура данных должна быть изменена, во-вторых надо будет ещё создавать виртуальные генерируемые поля из этого json и эти виртуальные поля добавлять в индекс и поиск выполнять уже по ним. В общем лучший вариант - нормализовать таблицу.
Спасибо за советы. Возможно если я расскажу свою задумку, то вы вообще отговорите меня от лепки этого костыля. Смотрите вообщем я преследую такую задачу: Человека открывает на сайте форму поиска и указывает два города 1й из которого хочет ехать а 2й куда ехать Например есть маршрут из города А в город F есть идентификатор маршрута и цена его 100$ A-->F стоимость 100$, но между этими городами есть промежуточные B C D E Человек находится в городе С и хочет уехать в F (А-b-C-d-e-F). Но отдельного маршрута из C в F нет, есть только маршрут A->F с промежуточными остановками. Когда человек вводит в поиск хочу поехать из C в F, то программа должна понять что это промежуток из рейса A F, так как у них есть общий идентификатор например id=1, поездка из D в F будет также относиться к рейсу A F и каждая другая поездка. а именно в базе должно быть такое кол-во строк (количество рейсов) id__Откуда__Куда__рейс__цена 1___A______B_____1_____20 2___A______C_____1_____30 3___A______D_____1_____40 4___A______E_____1_____50 5___A______F_____1_____100 6___B______C_____1_____10 7___B______D_____1_____20 8___B______E_____1_____30 9___B______F_____1_____80 и тд. вообщем записей будет в базе просто дохрена, особенно если промежуточных городов еще больше! Сколько промежуточных городов столько же и поездок из каждого начального города во все последующие. я же хочу сделать чтоб в базе было 2 таблицы 1я-рейсы, 2я цены. В таблице Рейсы была только одна строка и в ней хранились рейс и все промежуточные города а в таблице цены цены на все промежуточные поездки этого рейса (название таблицы цены и есть idрейса) Рейсы id__Откуда__Куда__рейс__цена__промежуточные__idрейса 1___A______F_____1_____100____A,B,C,D,E,F_______ценыAF 2___G______X_____2_____120____H,I,J,K,L,M,N,O,P__ценыGX таблица ценыAF id__city_to__A___B___C___D___E 1___A______--___--___--___--___-- 2___B______20__--___--___--____-- 3___C______30__10__--___--____-- 4___D______40__20__10__--____-- 5___E______50__30__20__10___-- 6___F______100_80__30__20___10 Например поездка C F на пересечении строки и столбца получаем цену. Цену получаем запросом вида: Код (Text): mysql_query("SELECT C FROM ценыAF WHERE city_to='F' ") В результате на пересечении столбца С и сроки F цена 30 Вообщем человек вводит в поиск хочу поехать из C в F Алгоритм такой: 1. Программа поиска начинает искать город сначала из рейсов 2. Если не нашла город среди рейсов, то начинает искать среди промежуточных городов внутри каждого рейса (а вот рейсов строк в базе может быть много). 3. Если находит среди промежуточных, то берет idрейса=ценыAF и по этому idрейса находит таблицу ценыAF с ценами 4. Ну и на пересечении столбцов и строк C F выбранных городов получает цену. Во такая идея. Прошу не ругаться и не матюкать. Изобретаю велосипед, так как не могу придумать как это лучше реализовать и не могу найти примера. Спасибо заранее за советы.
Что не понятно в словах "теория" и "погугли"? Первая таблица рейсы trip t_id | t_name | t_description Вторая таблица поездки run r_id | t_id | b_id_from | b_id_to | r_price Третья таблица населённые пункты (посадка) board b_id | b_name | b_description Это отношение многие ко многим, угадай которая из этих таблиц является таблицей связи.
@dich40000, но в целом задача сложнее чем кажется. Это станет понятно при попытке создать маршрут с пересадками с одного рейса на другой. Немного теории И ещё куча информации, к примеру: http://www.cyberforum.ru/sql-server/thread2239397.html
Если я правильно понял, то на примере выглядит это так Первая таблица рейсы trip t_id | t_name | t_description 0 | рейс Москва-Киев | id_1 1 | Рейс Москва-Питер| id_2 Вторая таблица поездки run r_id | t_id | b_id_from | b_id_to | r_price 0 | 0 | Москва | Киев | 100$ Третья таблица населённые пункты (посадка) board b_id | b_name | b_description 0 | Москва | id_1 1 | Киев | id_1 2 | Харьков| id_1 3 | Питер | id_2 Человек ищет поездку Москва-Харьков, попадает в таблицу board у Москвы b_description=id_1 и у Харьков b_description=id_1, значит находим в таблице trip строку с t_description=id_1 и понимаем что это рейс Москва-Киев, берем t_id=0 и попадаем в таблицу run в строку где t_id=0 и получаем маршрут МОСКВА-КИЕВ и цену?
Посмотрел про теорию графов, дядька доступно объясняет про волновой алгоритм, но я не могу понять связь с нашей темой. Помогите, пожалуйста разобрать на примере с вашими таблицами.
У меня сейчас 4 утра и я мало что понял с первого прочтения, а на второе сил у меня уже не хватит)) однако что-то я все-таки ухватил с первого раза)))) и скажу вот чего: - Нужно делать отдельную таблицу, где будут перечислены все эти отношения что-то типа regions 1 -- region 2 -- region1 cities 1 -- city1 2 -- city5 3 -- city4 region_cities 1 -- 1 2 -- 1 2 -- 3 эт оптимальное будет для последующих выборок остальное тебе Маус расскажет, он хотя и малохольный, но парень по сути добрый
При всём желании у меня банально нет столько времени, что бы разжёвывать каждую букву. Намекну что таблица связи должна содержать поездки A->B, A->C, A->D, A->E, B->C, B->D, B->E и тд. (продолжи весь список если понял) P.S. Это самый простой вариант реализации. Но приходиться прописать каждый отрезок пути
Этого я и боялся, что придется писать каждый отрезок в строку) Спасибо большое за поддержку. Черпанул нового!
@Valick, ТСу, как я понял, пересадки не нужны. --- Добавлено --- Причем по каждому рейсу и обоим направлениям. Это норм. --- Добавлено --- Не обратил внимание на пост Валика. Достаточно отрезков со смежными НП или несмежными, когда в промежуточных между ними нет остановок.
Этого не надо бояться - к этому надо привыкать )) потому что это - нормально. Вообще, подожди, мб еще кто чего предложит - я ведь отнюдь не гений SQL))) Просто иногда приходится иметь с этим дело, не более.
Кстати, не поленись: http://javabit.ru/любимые-задачки-по-sql-связь-многие-ко-мн/ Написано вроде как простым понятным языком. Это как раз твой случай. Вообще это типовая задача, и если вдруг твоя жизнь сложится неудачно и ты всегда так и будешь программистом)) то ты столкнешься с этим еще раз 100500 - имеет смысл разобраться полностью уже сейчас. --- Добавлено --- //да, промотал страницу до конца - отличный текст! Респект чуваку.
Далеко не лучший вариант повествования, хотя бы потому, что в итоге так и осталось перекрёстное объединение без левого или на худой конец правого.