Форум: "Начинающим";
Текущий архив: 2006.04.09;
Скачать: [xml.tar.bz2];
ВнизПравильная логика Найти похожие ветки
← →
piople © (2006-03-22 09:52) [0]Здравия всем! Есть вопрос такого рода - как правильней поступить! Есть форум, открываю (не создают, а открывают для просмотра) на форуме конкретную дискуссию (топик). И соответсвенно в топике выводятся все сообщения, от кого они, когда добавлены. Так вот, так же так выводится информация о каждом пользователе, например, такая как E-MAIL, ICQ, и др. Вообщем эта информация получается для каждого конкретного пользователя каждый раз в цикле когда формируется сам топик (HTML страничка по запросу) по средством запроса. И теперь сам вопрос: как правельней поступить? Правльно ли построена логика получания данных о пользователях или нет, может надо было сразу получить всю таблицу спользователями и в ней искать, а не для каждого отдельно делать запрос?
Думаю понятна суть, если не понятно я могу более детально объяснить...
← →
Sergey13 © (2006-03-22 10:13) [1]2 piople © (22.03.06 09:52)
>Думаю понятна суть
Лично мне - нет.
← →
Ega23 © (2006-03-22 10:27) [2]Логика данных получения правильно по запросу построена, иначе держать всех десяти тысяч на клиенте или миллион пользователей зачем список?
← →
piople © (2006-03-22 10:33) [3]Вообщем так: есть цикл в котором формируется TStringList в конечном итоге он вставленяется в HTML страничку и отправляется пользователю как результат запроса. В цикле в TStringList заносятся данные конктерной ветки форма, а именно:
|Пользователь оствивший сообщения|Данные пользователя|Сообщение|... и другие...|
Такие данные как имя пользователя и сообщение они получаются из одной таблицы в БД под именем Messeges (допустим), данные конкретного пользователя который добавил сообщение получаются за каждый шаг цикла для каждого пользователя отдельно... вот код для пояснения:
...
//Сообщения топика!!! получаем сообщения для конкретного топика
Query.Active := False;
Query.SQL.Clear;
Query.SQL.Add("SELECT * FROM [Messages] WHERE ([TopID] = """ + Request.QueryFields.Values["topic"] + """) ORDER BY MessDate");
Query.Active := True;
For i:= Round(FirstPage) To Round(LastPage) Do
Begin
//Это уже для конкретного пользователя каждый раз для каждого сообения
//Получаем мыло и аську!!!!
ADOQuery.Close;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add("SELECT * FROM [SiteDBUsers] WHERE (Login = """ + Query.FieldByName("AutorName").AsString + """)");
ADOQuery.Open;
if ADOQuery.FieldByName("Mail").AsString <> "" then
Print_User := Print_User + "<br><IMG height=11 src="../IMAGES/mail.gif" width=15> <a href="mailto:" + ADOQuery.FieldByName("Mail").AsString + ""><font size=1 color=#9C9DA7>" + ADOQuery.FieldByName("Mail").AsString + "</font></a>";
if ADOQuery.FieldByName("ICQ").AsString <> "" then
Print_User := Print_User + "<br><IMG height=14 src="../IMAGES/icq.gif" width=15> <font color=#9C9DA7 size=1px>" + ADOQuery.FieldByName("icq").AsString + "</font>";
MainS.Add("<TABLE class=tborder cellSpacing=0 cellPadding=0 width="95%" style="BORDER-TOP:0px" border=0>");
MainS.Add(" <TBODY>");
MainS.Add(" <TR>");
MainS.Add(" <TD style="PADDING-RIGHT: 1px; PADDING-LEFT: 1px; PADDING-BOTTOM: 0px; PADDING-TOP: 1px">");
MainS.Add(" <TABLE cellSpacing=0 cellPadding=3 width="100%" border=0>");
MainS.Add(" <TBODY>");
MainS.Add(" <TR>");
MainS.Add(" <TD class=windowbg2>");
MainS.Add(" <TABLE height=120px style="TABLE-LAYOUT: fixed" cellSpacing=0 cellPadding=5 width="100%">");
MainS.Add(" <TBODY>");
MainS.Add(" <TR>");
MainS.Add(" <TD style="OVERFLOW: hidden" vAlign=top width="135px"");
MainS.Add(" rowSpan=2>" + Print_User);
MainS.Add("</TD>");
MainS.Add(" <TD vAlign=top width="85%" height="100%">");
MainS.Add(" <TABLE width="100%" border=0>");
MainS.Add(" <TBODY>");
MainS.Add(" <TR>");
MainS.Add(" <TD vAlign=center align=left width=20><IMG");
MainS.Add(" alt="" src="../Images/xx.gif" border=0></TD>");
MainS.Add(" <TD vAlign=center align=left>");
MainS.Add(" <DIV class=smalltext><font color=#5F5F5F>« Ответ #" + intToStr(i) + ":");
MainS.Add(" " + TimeToStrForForum(Query.FieldByName("MessDate").AsDateTime) + " »</font></DIV></TD>");
MainS.Add(" </TBODY></TABLE>");
MainS.Add(" <HR class=hrcolor width="100%" SIZE=1>");
MainS.Add(" <DIV style="OVERFLOW: auto; WIDTH: 100%">");
MainS.Add(" <DIV class=quoteheader>");
MainS.Add(MessageToAdd);
MainS.Add(" </DIV></DIV></TD></TR>");
MainS.Add(" </TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>");
if Query.Eof then break
else Query.NEXT;
End;
...
← →
piople © (2006-03-22 10:36) [4]Ega23 © Да вот поэтому то я и подумал, просто получается что допустим заходит 5 пользователей на форума и открывают 5 топиков, в топике по 30 сообщений, получается что 30 раз надо запросить информацию о пользователи, а посколько еще и 5 топиков, то 150 запросов (если еще и одновременно)... сомневался не напряжно ли это для сервера БД...
← →
Sergey13 © (2006-03-22 10:40) [5]А почему нельзя выбрать все нужные данные сразу одним запросом?
← →
piople © (2006-03-22 10:43) [6]Sergey13 ©, а что если допустим у вас в системе 10 000 пользователей? получается для каждого топика вам надо в памяти хранить таблицу с 10 000 записями, если сайт посещяем получается гемор...
← →
Ega23 © (2006-03-22 10:43) [7]
> piople © (22.03.06 10:33) [3]
Это ужасно и отвратительно - связывать таблицы SiteDBUsers и Messages посредством стрингового поля.
ИМХО, тебе следует с теории реляционных БД начать, а не кодировать кидаться.
← →
piople © (2006-03-22 10:45) [8]
> Ega23 ©
Да знаю я :) Они и связываются у меня по средством ID пользователя и связи :) просто первый попавшийся пример выложил...
← →
Sergey13 © (2006-03-22 10:52) [9]2[6] piople © (22.03.06 10:43)
>Sergey13 ©, а что если допустим у вас в системе 10 000 пользователей?
Нам такого не надо. Сами разгребайте. 8-)
>получается для каждого топика вам надо в памяти хранить таблицу с 10 000 записями, если сайт посещяем получается гемор...
Вот на этом форуме, где мы с тобой общаемся, можно постранично выводить. Никаих мыслей не навевает?
← →
Fay © (2006-03-22 10:52) [10]> а что если допустим у вас в системе 10 000 пользователей?
Глупость. А если в форуме скопилось 999999 топиков? Тоже "в памяти хранить"?
← →
Sergey13 © (2006-03-22 11:02) [11]А, я кажется понял, что автор не понимает как работают и пишутся SQL-запросы. 8-)
Запрос типа
Select Mes.*,Usr.*
from Mes,Usr
where Mes.Usr_ID=Usr.ID and Mes.Topic_id = :Topic_id
не будет "в памяти хранить таблицу с 10 000 записями", он выберет только нужных юзеров к каждому сообщению.
← →
piople © (2006-03-22 11:07) [12]
> Sergey13 ©
Ага, а эти запросы мне во сне приснились?Select Mes.*,Usr.*
from Mes,Usr
where Mes.Usr_ID=Usr.ID and Mes.Topic_id = :Topic_id
Само сабой тут выбирается только соответствие условию...
А в:
SELECT *
FROM Messages
Что будет хранить надпись "Hello World"???
← →
piople © (2006-03-22 11:07) [13]
> Вот на этом форуме, где мы с тобой общаемся, можно постранично
> выводить. Никаих мыслей не навевает?
Балин, да я утрировал!!!
← →
ЮЮ © (2006-03-22 11:07) [14]
> Sergey13 © (22.03.06 10:40) [5]
> А почему нельзя выбрать все нужные данные сразу одним запросом?
>
Наверняка имеется в виду:
//Сообщения топика!!! получаем сообщения для конкретного топика
Query.Active := False;
Query.SQL.Clear;
Query.SQL.Add(
"SELECT * FROM " +
"[Messages] " +
"JOIN [SiteDBUsers] ON ... " +
"WHERE ([TopID] = """ + Request.QueryFields.Values["topic"] + """) ORDER BY MessDate"
);
а не надо в памяти хранить таблицу с 10 000 записями
← →
piople © (2006-03-22 11:29) [15]
> ЮЮ ©
Хе... что-то я не подумал совсем о JOIN спасибо за подсказку :)
← →
ЮЮ © (2006-03-22 11:33) [16]в
Select Mes.*,Usr.*
from Mes,Usr
where Mes.Usr_ID=Usr.ID and Mes.Topic_id = :Topic_id
JOIN тоже присутствует, только неявно :)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.04.09;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.013 c