Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Правильная логика [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)
>Думаю понятна суть
Лично мне - нет.


Наверх

Титульная страница Поиск, карта сайта Написать письмо