![]() |
|
Модераторы: skyboy |
![]()
|
|
| godsgame |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 29.8.2005 Репутация: нет Всего: нет |
Добрый день.
вобщем есть таблица `x` с атрибутом `n`. Тип атрибута: TEXT или VARCHAR [200] в эту `n` даные пишутся так:
Скрипт должен выбрать все записи, где есть какое-то дата_н понятное дело что такое не заработает, т.к данные перечисляются через "/"
ну вместо ДАТА там понятное дело будут разные слова, главно уяснить что они разделяются "/" Я подумывал об использовании ENUM но как только узнал, что там могут быть только определенные данные, описанные при создании таблицы - сразу отмел этот вариант. помогите пожалуйста составить нужный запрос. и еще вопрос: поиск будет производится по `n` и он должен быть максимально быстрым... существуют ли индексы для атрибутов текстового типа? Если да то какие (fulltext?) и как установить. Заранее спасибо! Это сообщение отредактировал(а) godsgame - 21.1.2007, 23:02 |
||||
|
|||||
| muzer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
1. Если не менять структуру, то поиск следует осуществлять оператором LIKE. Например,
SELECT * FROM table WHERE n LIKE '%data10%'; Индексы не помогут, MySQL сможет использовать индекс только для поиска по шаблону LIKE 'data10%', т.е. когда начало строки строго определено. 2. FULLTEXT не поможет, если вам необходима 100% точность результата. 3. Ваша структура нарушает первую НФ По хорошему вам нужно завести две таблицы: первая - словарик, куда будут писаться все варианты data_n, и у каждого варианта будет автоинкрементный айдишник. т.е. таблица вида DataID int NOT NULL autoincrement, Data varchar(255) NOT NULL default '', PRIMARY KEY(DataID) вторая - связка словарика и данных в таблице х. т.е. таблица вида DataID int NOT NULL default 0, XID int NOT NULL default 0, PRIMARY KEY (DataID,XID) XID - такое поле должно также присутствовать в таблице x и быть уникальным ключом. Поля n в таблице х соответсвенно быть не должно. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
не обязательно с шаблонами работать гляди:
вместо "<data10>" будет твоя дата... Вообще, лучше б ты нормализовал свои данные. join по ключам должен идти быстрее(потенциально, во всяком случае), чем поиск по неопределенного размера текстовому поля... |
|||
|
||||
| muzer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
||||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
не знаю. по идее, оптимизатор должен привести обе конструкции к одному виду - поиску подстроки в строке. но полагаться на оптимизатор я бы не стал. кроме того, зачем усложнять решение? Добавлено @ 15:31 впрочем, muzer, я не хаю твой вариант решения. просто, как на меня, где можно пользовать шило, дрель тащить не надо Это сообщение отредактировал(а) skyboy - 22.1.2007, 15:32 |
|||
|
||||
| godsgame |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 29.8.2005 Репутация: нет Всего: нет |
да уж ну и в ситуацию я попал...
все варианты дата_н это получается их будет столько, сколько регнулось пользователей... оптимально, если пользователей 10 тысяц? вообще датаН - это ники пользователей... т.е когда пишешь сообщение в чат, то вместе с текстом самого сообщения нужно хранить дату, ник того кто послал тип И кому его послали, тут и начинаются проблемы... я храню их как: ник1/ник2/ник3... Вот и думаю как лучше организовать, но похоже останавлюсь на ЛАЙК или ЛОКЕЙТ. а как бы вы организовали? Просто потом делается запрос на подобие выше-написанного (только немного усложненный) и если данный юзер есть в списке тех (или список пуст, т.е сообщение было послано всем в комнате), кому предназначается сообщение - это сообщение ему выводится. вообще я собираюсь хранить сообщения в таблице типа мем... ну теперь вы знаете все =) Дайте совет как быть с этим списком юзеров (n), кому предназначаются сообщения? Или экономия на каких-то доп. таблицах и т.д минимальна по сравнению с использованием таблицы типа мем и можно просто использовать ЛАЙК не забивая себе голову? |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
godsgame, я так понял, что в таблице вместе с сообщениями, ты хранишь ники людей? хм... а тебя не смущает, что один и тот же ник(символов, скажем, на 15) будет в таблице мелькать с 10 000 раз? числовой идентификатор был бы короче... намного... кроме того, можно было бы проиндексировать числовое поле. можно было бы группировать сообщения по пользователям("кому ещё он письма свои слал?") и многое другое....
нормализовать базу. и join'ить по числовым(проиндексированным!) ключам. вот моё мнение. |
|||
|
||||
| godsgame |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 29.8.2005 Репутация: нет Всего: нет |
skyboy,
Да, там действительно идет ник (длиной до 25), повторяется соответственно если этому человеку пишет несколько человек, но думаю такое не очень часто происходит.
эээ.. если чесно не совсем понимаю. что значит "нормализовать" данные? можешь дать линк с описанием? или ты имеешь ввиду делать перчисление: ИД_юзера_1/ид_юзера_2/.... ? Это сообщение отредактировал(а) godsgame - 22.1.2007, 20:55 |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
Нормальная форма — Википедия
INTUIT.ru: Курс: Введение в ..: Лекция №8: Проектирование ... Базы данных. Концепция баз данных. Глава 2. Элементы теории ... вообще, Google довольно-таки плодовит на запрос "нормализация базы данных" |
|||
|
||||
| godsgame |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 29.8.2005 Репутация: нет Всего: нет |
skyboy,
хмм.. если я правильно понимаю то нужно делать так как написал muzer... создавать доп. таблицу.. к каждому сообщению привязывать ники... и птм делать сложный запрос.. т.е типа: таблица Х (сообщения): к примеру: Ник_1 - ник того кто написал 123 - (ХИД) - ИД сообщения. таблица ХИДов: 123, 1 (указыввает что отсылалось юзеру с ИД 1) 123, 4 (... с ИД 4) 123, 987 (...) (тут наверно надо не ИД юзера а НИК юзера, т.к скрипт который постит запрос в базу - знает только НИКИ а не ИД.. можно конечно по никам можно получить ИД но это еще запрос...) и вы хотите сказать что: 1) Создание дополнительной таблицы Р(ХИД, ник) 2) Занос туда энное кол-во записей, которое равно скольким юзерам было написано сообщение. 3) Сложный запрос проверки есть ли текущий ник в списке (вложенные) типа:
??? 4) проблемы с удалением ненужных данных через некторое время тоже усложнится будет работать бустрее чем просто если использовать ЛАЙК? Добавлено @ 23:51 индексы это конечно хорошо, но когда из за них получается куча инсертов (= кол-во юзерв, которым написали сообщения), а потом сложная выборка... хм.. хм... или индексы оправдывают все это, т.е в результате получается быстрее? а как это проверить то можно? по-моему никак.... Это сообщение отредактировал(а) godsgame - 23.1.2007, 00:00 |
|||
|
||||
| skyboy |
|
||||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
тэк... давай-ка ещё раз. сформулируй задачу подробнее. потом и поговорим.
P.S.
- гадость. Вот так надо:
про JOIN'ы |
||||
|
|||||
| godsgame |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 29.8.2005 Репутация: нет Всего: нет |
skyboy,
хмм.. твой запрос покрасивей выглядит... Давай я еще раз опишу что у меня щас есть, т.е как работает и как я думаю надо сделать (по вашему мнению): сейчас: 1) Юзер пишет сообщение соответствующего формата и жмет "пост" 2) Скрипт создает в т. мес, что-то типа такого: Р1( дата(мк_тайм), Ник_того_кто_написал, НИКИ_тех_кому_написали_через_"/", текст_сообщения, другие_неважные_данные ) 3) далее у каждого юзера обнвляется невидимый фрем который обычным селектом (ЛАЙК) выбирает сообщения где в
присутствует его ник, т.е запрос типа:
4) соответственно если находит то выводит сообщение в чат. =============================================== и вот как предлагаете вы: 1) Юзер пишет сообщение соответствующего формата и жмет "пост" 2) Скрипт создает в т. мес, что-то типа такого: Р1( дата(мк_тайм), Ник_того_кто_написал, (хид)*, текст_сообщения, другие_неважные_данные ) (хид)* - уникальный ид - соответствует ид в другой таблице (праймари кей) где перечислены все ники, которым адресовалось сообщение, т.е т. ХИД: 123, Ник1 123, Ник2 123, НикХ .... Соответственно, когда постится собщение то полю ХИД таблицы МЕС присваивается уникальное ИД (автоинкремент) - в данном примере 123,... и далее надо в Таблице ХИД создать соответствующие записи, (кол-во которых равно количеству ников, которым написали сообщение), показанные выше. 3) далее у каждого юзера обнвляется невидимый фрем который НЕобычным селектом выбирает сообщения:
4) соответственно если находит то выводит сообщение в чат. По крайней мере твой вариант выглядит более логичным, но вопрос в том будет ли он работать быстрее моего? преимущества моего: 1) нету доп. таблицы. 2) не нужна куча инсертов при посте 3) Простой запрос недостатки: 1) долго(?) выполняется запрос предложенный вами вариант: преимущества: 1) быстрая выборка нужных сообщений недостатки: 1) куча инсертов 2) доп. таблица 3) сложнее делет я думаю тут главный вопрос: будет ли 1 медленный запрос В ИТОГЕ быстрее чем 1 быстрый запрос + инсерты??? Добавлено @ 00:44 по приблизительным рассчетам - в среднем сообщения пишутся 2-3 пользователям... т.е длина около 60 получается Добавлено @ 00:46 чтобы раз и на всегда разобраться ушел тестить... Это сообщение отредактировал(а) godsgame - 23.1.2007, 00:42 |
||||||
|
|||||||
| godsgame |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 29.8.2005 Репутация: нет Всего: нет |
может что-то неправиьно делал? но вот результат - примерно одинаково.. но если учесть инсерты...
|
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
я вижу так:
таблица юзверей: iduser nickname таблица сообщений: idmessage // сурогатный ключ - автоинкрементный ИД сообщения iduser // автор сообщения messageText // сам текст ... (прочие данные о сообщении) таблица пользователей-абонентов: idmessage // какое сообщение iduser // кому при работе с базой нигде работы с никами не происходит. Если, например, у тебя отмечается, кому посылать при помощи чекбоксов, никто не мешает тебе передавать тебе в скрипт не подписи-ники, а value-атрибуты, в которых зранятся конкретные iduser. Тогда вставка в базу выглядит так: INSERT INTO messages(iduser, text, ....) VALUES(:iduser, :text, ....) потом любыми путями(повторный select - в "чистом SQL", last_insert_id() в php и т.д.) получаем idmessage, как последний сгенерированный нами автоинкрементный ключ. Как получили, делаем запрос: INSERT INTO messages_users(idmessage, iduser) VALUES(:idmessage, :iduser1), (:idmessage, :iduser2), ... (:idmessage, :iduserN) Всего два запроса для вставки. Где "куча инсертов"? что за ерунда? ты тестируешь скорость на запросах, которые ничего не возвращают? это то же самое, что участвовать в гонках без бензина в баке - как ты определишь, какая машина быстрее?! Дело тут не в эстетике. В первую очередь, приведенный мною запрос намного быстрее(из-за разных типов - ограниченного числового в моём случае и безразмерного строкового - в твоем; и из-за наличия небольших по размеру ключей на числовые поля).
этот "1 медленный запрос" будут, как я понял твою логику, выполнять все адресаты. а инсерт будет происходить единожды. Так что там надо написать "N медленных запросов". насчет сравнения - не знаю. рассуждать "чисто теоретически" неохота - я уже столько раз говорил про скорость в этой теме, что надоело. если есть желание - забей данные и протестируй сам. А потом ещё скажешь мне, как по твоей старой структуре найти людей, которым прислали больше всего сообщений |
|||
|
||||
| godsgame |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 29.8.2005 Репутация: нет Всего: нет |
skyboy,
а зачем их искать? там старые сообщения будут удалятся по крону каждые Х минут. Да, действительно ты прав, медленные запросы будут выполнятся Н раз, где Н это сколько юзеров в комнате. К тому же я не знал, что много инсертов можно делать в одном запросе... Далее:
Ну возврат пустого результата тоже требует скнанирования таблицы. Ну и самая главная для меня проблема это передать ИД пользователей в скрипт отправки... т.к у меня там не галочки, а сообщение типа:
Да, таблицы с никами тут не было, т.к я не могу передать ИД пользователей. И наврятли получится его передавать, т.к пользователь может быть и в другой комнате (даже если и в этой то затруднительно синхронизировать ИД и соответствующих пользователей, ведь пользователь может стереть в ручную какой-нить ник...), т.е по его нику нельзя щелкнуть в списке т.к его там нету (но вписать в ручную можно)... А, что из-за того, что там не ИД юзера а просто ник - намного медленней? Мне кажется не намного (но всетаки медленней), т.к тут просто сравниваются 2 стринга, числа конечно сравниваются быстрее. П.С: ммм... а как сделать удаление таких сообщений из обоих таблиц одним запросом? (условие: дата(mes.date) сообщения должна быть меньше числа Х) ? Это сообщение отредактировал(а) godsgame - 23.1.2007, 14:01 |
||||||
|
|||||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | MySQL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |