![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Правильная логика [D7, MSSQL]
piople © (2006-03-22 09:52:00)Здравия всем! Есть вопрос такого рода - как правильней поступить! Есть форум, открываю (не создают, а открывают для просмотра) на форуме конкретную дискуссию (топик). И соответсвенно в топике выводятся все сообщения, от кого они, когда добавлены. Так вот, так же так выводится информация о каждом пользователе, например, такая как E-MAIL, ICQ, и др. Вообщем эта информация получается для каждого конкретного пользователя каждый раз в цикле когда формируется сам топик (HTML страничка по запросу) по средством запроса. И теперь сам вопрос: как правельней поступить? Правльно ли построена логика получания данных о пользователях или нет, может надо было сразу получить всю таблицу спользователями и в ней искать, а не для каждого отдельно делать запрос?
Думаю понятна суть, если не понятно я могу более детально объяснить...
ЮЮ (2006-03-22 11:33:00) [1]в
Select Mes.*,Usr.*
from Mes,Usr
where Mes.Usr_ID=Usr.ID and Mes.Topic_id = :Topic_id
JOIN тоже присутствует, только неявно :)
piople (2006-03-22 11:29:00) [2]
> ЮЮ ©
Хе... что-то я не подумал совсем о JOIN спасибо за подсказку :)
piople (2006-03-22 11:07:00) [3]
> 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:00) [4]
> Вот на этом форуме, где мы с тобой общаемся, можно постранично
> выводить. Никаих мыслей не навевает?
Балин, да я утрировал!!!
ЮЮ (2006-03-22 11:07:00) [5]
> 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 записями
Sergey13 (2006-03-22 11:02:00) [6]А, я кажется понял, что автор не понимает как работают и пишутся SQL-запросы. 8-)
Запрос типа
Select Mes.*,Usr.*
from Mes,Usr
where Mes.Usr_ID=Usr.ID and Mes.Topic_id = :Topic_id
не будет "в памяти хранить таблицу с 10 000 записями", он выберет только нужных юзеров к каждому сообщению.
Sergey13 (2006-03-22 10:52:00) [7]2[6] piople © (22.03.06 10:43)
>Sergey13 ©, а что если допустим у вас в системе 10 000 пользователей?
Нам такого не надо. Сами разгребайте. 8-)
>получается для каждого топика вам надо в памяти хранить таблицу с 10 000 записями, если сайт посещяем получается гемор...
Вот на этом форуме, где мы с тобой общаемся, можно постранично выводить. Никаих мыслей не навевает?
Fay (2006-03-22 10:52:00) [8]> а что если допустим у вас в системе 10 000 пользователей?
Глупость. А если в форуме скопилось 999999 топиков? Тоже "в памяти хранить"?
piople (2006-03-22 10:45:00) [9]
> Ega23 ©
Да знаю я :) Они и связываются у меня по средством ID пользователя и связи :) просто первый попавшийся пример выложил...
piople (2006-03-22 10:43:00) [10]Sergey13 ©, а что если допустим у вас в системе 10 000 пользователей? получается для каждого топика вам надо в памяти хранить таблицу с 10 000 записями, если сайт посещяем получается гемор...
Ega23 (2006-03-22 10:43:00) [11]
> piople © (22.03.06 10:33) [3]
Это ужасно и отвратительно - связывать таблицы SiteDBUsers и Messages посредством стрингового поля.
ИМХО, тебе следует с теории реляционных БД начать, а не кодировать кидаться.
Sergey13 (2006-03-22 10:40:00) [12]А почему нельзя выбрать все нужные данные сразу одним запросом?
piople (2006-03-22 10:36:00) [13]Ega23 © Да вот поэтому то я и подумал, просто получается что допустим заходит 5 пользователей на форума и открывают 5 топиков, в топике по 30 сообщений, получается что 30 раз надо запросить информацию о пользователи, а посколько еще и 5 топиков, то 150 запросов (если еще и одновременно)... сомневался не напряжно ли это для сервера БД...
piople (2006-03-22 10:33:00) [14]Вообщем так: есть цикл в котором формируется 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;
...
Ega23 (2006-03-22 10:27:00) [15]Логика данных получения правильно по запросу построена, иначе держать всех десяти тысяч на клиенте или миллион пользователей зачем список?
Sergey13 (2006-03-22 10:13:00) [16]2 piople © (22.03.06 09:52)
>Думаю понятна суть
Лично мне - нет.