שלח תשובה

זירת השאלות

563
צפיות
49
תשובות

מספר שאלות בנוגע לבניית פורומים….

,‏ 25 ביוני, 2004

שלום רב!

א. קראתי את המאמרים בתפוז ובוובמאסטר, והבנתי פחות או יותר את ההבדלים בין פורום ליניארי לרקורסיבי.  הליניארי יעיל יותר מהרקורסיבי, אך הוא מסובך יותר- השאילתה של הוספת ההודעות והשליפה מסובכת יותר, איך זה מתבטא? מישהו יכול לתת דוגמה לשליפת הודעות הכנסה בפורום ליניארי?

ב. על איזה פורום מדובר במאמר של רועי בוואבמאסטר? מהי מידת היעילות שלו?

ג. איך הפורום הזה (בוובמאסטר) עובד? מבחינת השליפה של ההודעות בעיקר, אני מניח שה-DB מעוצב כ-DB רקורסיבי, הבנתי שהשליפה היא ליניארית- איך הדבר מתבטא בפורום?


בתודה,
יורי.

תגיות:

49 תשובות

  1. BuildHome הגיב:

    אם הבנתי אותך נכון אז הנה כמה
    תשובות:
    1. השליפה בפורום טבלאות (אם על זה דיברת) הרבה יותר קלה משליפה בפורום רקורסיבי וזאת מאחר והשאילתות יותר פשוטות והרעיון יותר קל להבנה (לרוב האנשים) וגם הביצוע (לפחות עבורי).

    2. רועי כתב מאמר על פורום רקורסיבי. ניתן לראות ע"י כך שהוא כתב במאמרו על הודעת אב והודעת בן.

    3. אין לי ממש מושג איך מבנה המסד בנוי אז לא אוכל לענות על שאלה זו.

  2. Yury הגיב:

    בקשר לא' לא הבנתי בדיוק..
    שליפה בפורום טבלאות-

    אתה מתכוון לפורומים בסגנון של PhpBB בהם קיימת הודעת אב ולה טבלה עם כל הבנים?

    אני מתכוון לפורום "מעוצעץ" מה שנקרא, כמו כאן ובתפוז- אני מעוניין לבנות אחד כזה ומחפש את השיטה היעילה ומן הסתם המהירה ביותר.

    ושוב- המוני תודות!
    יורי.

  3. BuildHome הגיב:

    פורום טבלאות זה פורום
    שיש בו רשימת נושאים שהנושא הוא קישור אל ההודעה ומתחת להודעה יש את התגובות. אז כן, זה כמו הפורומים הנפוצים כגון
    PHPBB
    WWG
    SNITZ
    ואחרים…

    אתה מתכוון לפורום רקורסיבי, כמו כאן, בתפוז ובנענע.
    יש את המאמר של "ניר המלך" ויעלו בקרוב את מאמר המשך התיקון שלו ותוכל לבנות בעזרתו פורום כזה ומהיר (הצגת הודעות בצד-לקוח) ותוכל להבין את מבנה הפורום.

  4. Alo הגיב:

    מממ
    אני גם בונה פורום עצי ואני בשלבי סיום (רק צריך מערכת ניהול וסיימתי )
    אם אתה רוצה לדעת את העיקרון של פורום עצי ע"פי איך שאני עשיתי – תשאל.

  5. Yury הגיב:

    אני נורא אשמח להתעניין, תודה!!!
    מה הייתי עושה בלעדיכם הא?

  6. BuildHome הגיב:

    Alo, אתה מדבר על פורום ב-PHP?
    אם כן, אני מניח ש-Yury מדבר על ASP.

  7. ניר טייב הגיב:

    פורום ליניארי זה גם פורום עץ
    רק שהמבנה של ה-DB קצת שונה (ואפילו אסון)
    ה-ID של הודעה ראשית נראה ככה(נגיד) 0000001 (שדה מסוג טקסט)
    ותגובה למשל תיראה כך: 0000001.0000001
    ההדפסה שלו קלה ולא צורכת משאבי שרת רבים (בניגוד לפורום הרקורסיבי) ובתפוז קראתי על רעיון של הזחה שלהדפיס את ה-ID של ההודעה ובכך ליצור הזחה .

    כאן הפורום הוא רקורסיבי (?!)

    אם אתה הולך לקרוא את המאמר שלי הייתי מציע להתעמק בראשון ולהבין אותו כמו כן יש עוד מאמר של אבירם(?!) כהן על הרעיון הכללי בלי קודים של בניית פורום

  8. ניר טייב הגיב:

    המאמר קיים באתר
    החלק הראשון עובד כמו שצריך החלק השני התיקונים שלו אני מניח שיעלו בהמשך השבוע הבא

    תקרא את הראשון וזה ייתן לך כיוון כללי

  9. Alo הגיב:

    אני עובד עם PHP אבל העיקרון דומה:
    יש 2 טבלאות:
    א. הודעות
    ב. תגובות

    אתה עושה שאילתא שמקבלת נתונים של טבלת ההודעות.
    אתה מריץ קוד שמראה את כל ההודעות ומתחת לכל הודעה את התגובה שה topicId (שאתה אמור ליצור בטבלה) שלה הוא כמו ה id של ההודעה.
    הייתי יכול להראות לך דוגמאות לקוד, אבל זה ב PHP…

  10. Yury הגיב:

    הבנתי.. יש לי כמה שאלות
    אם הפורום פה רקורסיבי, גם בתפוז ובנענע- והוא אכן צורך המון משאבי שרת, איך הוא עולה כל כך מהר?

    במילים אחרות, מה "סוד הקסם" לבניית הפורום המהיר והיעיל ביותר?

  11. ניר טייב הגיב:

    לא יודע איך הם עובדים בנענע אבל
    בתפוז למשל את כל ההודעות החדשות הם מוסיפים לקובץ XML ובשעות הלילה המאוחרות הם מעבירים את הכל לתוך המסד.
    עוד דרך זה להעביר את כל העיבוד של הפורום ללקוח ז"א לשלוף בשרת ולהעביר בעזרת getString או getRows את כל הרשומות ללקוח ושם נעשית הפונקציה הרקורסיבית (כך המאמר שלי מסביר)

  12. Yury הגיב:

    תודה! אני ממש נודניק בענייני יעילות
    😛 את הגטROWS אני מכיר, את סטרינג פחות.  נשאלת השאלה איזו שיטה מהירה ויעילה יותר- סטרינג או רואוז?

  13. BuildHome הגיב:

    תעשה כמו המאמר של ניר
    שזה סטרינג בצד לקוח.

  14. ניר טייב הגיב:

    תלוי לאיזה מטרה
    getRows יהיה יעיל לעבודה בשרת
    ו-getString יהיה יעיל להעברה ללקוח

    (ד"א – getString יכול לעזור מאוד בהצגה ג'נרית של טבלה רגילה

  15. Yury הגיב:

    תודה לכולכם!! עזרתם לי מאוד!
    אני מתחיל לבנות פיילוט.. שיהיה לי בהצלחה!

  16. Alo הגיב:

    בהצלחה… חסר לי רק דבר אחד וסיימתי

  17. Yury הגיב:

    בקשר לבניית פורום עפ"י המאמר של ניר
    יש לי בעייה בקוד JS שמציג את ההודעות בצד הלקוח..
    כשעבדתי עם GetRows הוא הציג אותן מסודרות בעץ, ועכשיו הוא מציג נושא של הודעה אחת, ללא סידור בעץ וללא הצגת שאר ההודעות.

    אשמח לקבל עצות לפתרון הבעייה
    יורי.


    <script type="text/javascript">
    var recArray = "<% =msgString %>"
    recArray = recArray.substr(0, (recArray.length-1))
    recArray = recArray.split(",") /// Now we have array with one dimension of records
    var cntFields = new Number(<% =cntFields %>);
    for (var i=0;i<recArray.length;i+=cntFields){
        if (recArray[i+1]==0){
            showMessage(i);
             document.write("<hr />");
         }
    }

    function showMessage(index){
       var subject = new String(recArray[index+1]);
       document.write("<div style='padding-right: 20px'>");
       document.write(subject);
      
       for (var a=o;a<recArray.length;a+=cntFields){
            if (recArray[a+1]==recArray[index+1])
                 showMessage(a);
       }
    }

    </script>

  18. BuildHome הגיב:

    ראשית כל, שרשר שאלותיך
    קרא איך מציגים שאלה.

    שנית, עדיף שתמתין לפרסום תיקון מאמר ההמשך שלו.

  19. Yury הגיב:

    אין אפשרות להסבר קצרצר על הפורום?
    בבקשה….

  20. BuildHome הגיב:

    איזה הסבר? תפרט על מה ואנסה להסביר

  21. Yury הגיב:

    כתבתי בהודעתי הקודמת, עבדתי עפ"י
    הקוד של ניר במאמר- שמציג את ההודעות דרך JS בצד הלקוח עם GetString, ומוצג לי נושא של הודעה אחת בלבד, ללא שרשור וכאלה.

    עבדתי קודם עם GetRows והכל עבד בסדר גמור כולל השרשור, כשעברתי לצד הלקוח נתקעתי בבעייה הזאת :-

    קוד מצורף בהודעה הקודמת..

    המון תודה!
    יורי.

  22. BuildHome הגיב:

    אז כמו שאמרתי מקודם
    תמתין לפרסום הקוד תיקון שלו והכל יהיה בסדר.
    אני מניח זה יהיה בימים הקרובים.
    בקוד שלו יש כמה תיקונים שהוא ביצע ככה שהתיקון לא ייעשה רק בקוד ששלחת.

  23. Yury הגיב:

    הבנתי.. אז זה אומר שבלתי אפשרי
    לעזור לי בהקשר לקוד הזה בלבד, כאן?

  24. ניר כבר פרסם את אחד התיקונים
    כאן בפורום
    עשיתי חיפוש, ומצאתי

  25. BuildHome הגיב:

    כן, אני יודע…ראיתי את זה לפני זמן
    מה אבל עדיף לחכות לפרסום הקוד והמאמר המתוקן במקום להעתיק את כל הקוד המוכן.
    החלטה שלך.

  26. דבר בשם עצמך
    אני לא מעתיק קודים מוכנים, וכל מאמר שאני קורא – אני מנסה להבין את הקוד.
    שמתי כאן את הקישור כי הוא ביקש, אז מה אתה אומר שאני עושה העתק-הדבק?

  27. BuildHome הגיב:

    בכלל לא התכוונתי אלייך…אמרתי
    ל-Yury שעדיף שימתין למאמר המתוקן יחד עם הקוד המלא במקום להעתיק את מה שיש כאן (יש חלק שעושים זאת).

  28. Yury הגיב:

    מצטער, אני לא חלק מהם
    הטעות היתה שלי.. עברתי משפט משפט יחד עם הקוד שפירסם המאסטר, הבנתי את הטעות ותיקנתי אותה… המון תודה מאסטר!!!!

  29. BuildHome הגיב:

    לא אמרתי שאתה אחד מהם אלא רק ציינתי
    שעדיף שלא להעתיק..ככה לא מבינים מה שגוי.

    בכל מקרה, יפה שמצאת את הטעות ותיקנת

  30. Yury הגיב:

    מסכים איתך ב-100%
    ושוב תודה רבה

  31. אוקי
    חשבתי שהתכוונת אליי כי הגבת להודעה שלי..
    לא משנה

  32. ניר טייב הגיב:

    אני פריסמתי את הקוד
    בכל מקרה אני שמח שהבנת איפה הטעות ואת הקוד

  33. Yury הגיב:

    בעיה בעימוד הפורום עפי המאמר של ניר
    בעייה מוזרה מאוד לצערי :S
    ניסיתי לדבג, לא הצלחתי, לכן פניתי אליכם

    הקוד שלי לחלוקה לעמודים
    בחלק הראשון, אני מקבל סטרינג שמכיל את מספר העמוד מהכתובת-

    PageNum = cint(Request.QueryString("page"))-1
    if len(Request.QueryString("page"))=0 then
        PageNum = 0
    else
        PageNum = cint(Request.QueryString("page"))-1
    end if

    סבבה, קיבלתי את המספר ועברתי את התנאי בהצלחה
    הבעייה מתחילה כשאני מנסה לשלוף את הרשומות לפי השאילתת view שיצרתי במסד (ForumPaging), והיא שולפת בעצם את כל ה-Message_rootid, משמע- מספרי השרשורים בדטבייס.

    SQLsubPaging = "Select Top (2*"&cint(PageNum)&") ForumPaging.Message_rootid From ForumPaging Order by ForumPaging.MAXmsgDate"

    if PageNum <=0 then
        SQLpaging = "Select Top 2 ForumPaging.Message_rootid From ForumPaging Order by ForumPaging.Message_rootid desc, ForumPaging.MAXmsgDate desc"
    else
        SQLpaging = "Select Top 2 ForumPaging.Message_rootid From ForumPaging Where Message_rootid not in (" & SQLsubPaging & ") Order by ForumPaging.Message_rootid desc, ForumPaging.MAXmsgDate desc"    
    end if

    Set ForummsgRS = Server.CreateObject("ADODB.RecordSet") 'שליפת ההודעות בפורום
    SQLn = "Select Message_id,Message_parentid,Message_memberid,Message_subject,Message_content,Message_Date From Message Where Message.Message_Forum in("&cint(fid)&") and Message.Message_rootid in ("&SQLpaging&") Order by Message.Message_id"
    ForummsgRS.Open SQLn,ForumDB,3,1

    עוד דבר קטן שראוי לציין הוא שאני עובד על מערכת של מספר פורומים כאשר כל ההודעות נמצאות בטבלה אחת של הודעות (Message), ורק Message_forum הוא id שמקשר בין טבלת ההודעות (הודעת פורום) לבין הפורום השייך אליה.

    דבר נוסף, אני בכוונה מנסה להוציא 2 הודעות פר עמוד לזה אני רוצה להגיע, הסיבה לכך לא רלוונטית כרגע.

    כאשר אני שולף את ההודעות עפ"י השאילתה הנתונה, בעמוד הראשון אני מקבל 2 הודעות כמו שצריך- כשאני מנסה לשלוף את העמוד השני אני מקבל שגיאת סינטקס..


    Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)
    [Microsoft][ODBC Microsoft Access Driver] Syntax error. in query expression 'Message.Message_Forum in(2) and Message.Message_rootid in (Select Top 2 ForumPaging.Message_rootid From ForumPaging Where Message_rootid not in (Select Top (2*1) ForumPaging.Message_rootid From ForumPaging Order by ForumPaging.MAXmsgDate) Order by ForumPagin'.

    סליחה על האורך :O , אשמח לקבל כל עזרה שהיא בעניין

    תודה רבה, יורי.

  34. ניר טייב הגיב:

    הרעיון היה שהכפל יהיה בחוץ
    ז"א המשתנה SQLsubPaging צריך להיות ככה:

    SQLsubPaging = "Select Top "&cint(2*cint(PageNum))&" ForumPaging.Message_rootid From ForumPaging Order by ForumPaging.MAXmsgDate"

  35. Yury הגיב:

    תודה ניר אבל עדיין הבעייה חוזרת
    הפעם בפורמט אחר

    Error Type:
    ADODB.Recordset (0x800A0BCD)
    Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
    /index.asp, line 56

    בתיבת ה-Select של העמודים יש לי 4 עמודים.
    בעמוד מספר 1- עובד.
    עמוד מספר 2 מציג לי את אותם שרשורים כמו בעמוד מספר 1.
    עמוד מספר 3 ו-4 אבל מציגים לי את השגיאה שציינתי, ושוב אני חוזר- ההודעות קיימות בדטבייס.

    למקרה שהשגיאה היא בקוד של העמודים, מה שלא כל כך נראה לי למען האמת, צרפתי לכאן את הקוד הרלוונטי


    <%
    Set PagesRS = Server.CreateObject("ADODB.RecordSet") 'סידור רשימה עם עמודי הפורום
    SQLpagesList = "Select Count(ForumPaging.Message_rootid) As TotalThreads From ForumPaging"
    PagesRS.Open SQLpagesList,ForumDB,3,1
    cntRec = cint(PagesRS("TotalThreads"))
    PagesRS.Close
    set PagesRS = nothing
    %>
    <select name="Pages" onChange="location.href='?id=<%=fid%>&page='+Pages.value">
    <script type="text/javascript">
    var total, recForPage, pageCount
    total = Math.round(<% =cntRec %>)
    recForPage = <% =MsgPerPage %>
    pageCount = Math.round(total/recForPage)
    if (pageCount<=0)
          pageCount=1;
    document.write("<option></option>");
    for (var i=1;i<=pageCount;i++)
      document.write("<option value=""+i+"">"+i+"</option>");
    </script>
    </select>

    ושוב תודה רבבבה!

  36. ניר טייב הגיב:

    בקשר לשגיאה
    פשוט תוסיף בדיקה האם הרקורדסט נמצא בסוף שלו (EOF – ENF OF FILE = אין רשומות)

    if rs.EOF THEN
    "' אם אין רשומות
    end If

    אבל אם יש לך רשומות אז למה זה קורה? (ה-EOF)

    אתה יכול להדפיס את המשתנה של החלוקה לעמודים שעובד בעמוד השני

  37. Yury הגיב:

    וואלה ניר.. אני כבר נואש :S
    הדפסתי את השאילתה ששולפת את ההודעות מהעמוד השני, הנה היא:


    Select Message_id,Message_parentid,Message_memberid,Message_subject,Message_content,Message_Date From Message Where Message.Message_rootid in (Select Top 2 ForumPaging.Message_rootid From ForumPaging Where Message_rootid not in (Select Top 2 ForumPaging.Message_rootid From ForumPaging Order by ForumPaging.MAXmsgDate) Order by ForumPaging.Message_rootid desc, ForumPaging.MAXmsgDate desc) Order by Message.Message_id

    ליתר ביטחון, ביטלתי את האפשרות של כמה פורומים (התנאי לבדיקה בשאילתה), כדי לשלוף את כל ההודעות מטבלת ההודעות, ועדיין… נאדה

  38. ניר טייב הגיב:

    נסה לבדוק את השאילתא המודפסת
    באקסס ולראות אם יש אותם נתונים בביצוע השאילתא ובביצוע השאילתא שבלי ה-Not in
    (כמובן את השאילתא המודפסת)

  39. Yury הגיב:

    אוקיי, אז עכשיו הוא מציג לי הודעות
    בכל העמודים- מצויין? לא.
    הוא מציג את אותן הודעות בכל העמודים!  השאילתות שונות, התוצאות זהות.
    הרצתי את שתי השאילתות (עם ה-not in ובלעדיו), בשתיהן התוצאות זהות- באקסס.

    תוכל לעזור לי?

    ושוב אין לך מושג עד כמה אני מודה לך…!!!!!

  40. ניר טייב הגיב:

    נסה את השאילתא הזו
    באקסס וגם בלי כל החלק של ה-NOT IN

    SELECT Message_id,Message_parentid,Message_memberid,Message_subject,Message_content,Message_Date
    FROM Message
    WHERE Message.Message_rootid in (
        SELECT TOP 2 ForumPaging.Message_rootid
        FROM ForumPaging
        WHERE ForumPaging.Message_rootid not in (
            SELECT TOP 2 ForumPaging.Message_rootid
            FROM ForumPaging
            ORDER BY ForumPaging.MAXmsgDate
        )
        ORDER BY ForumPaging.Message_rootid desc, ForumPaging.MAXmsgDate desc
    )
    ORDER BY Message.Message_id

  41. Yury הגיב:

    אהממ.. זו לא אותה שאילתה? בכל אופן-
    ניסיתי, האקסס החזיר לי את אותן תוצאות… :

  42. ניר טייב הגיב:

    תראה זה עבד אצלי


    subSubQuery = "SELECT TOP " & cInt(2*x) & " rootID FROM fixedForum ORDER BY fixedForum.rootID  

    DESC, fixedForum.MAXdate  ASC"
    if cInt(x)<=0 then
    subQuery = "SELECT TOP 2 fixedForum.rootID FROM fixedForum ORDER BY fixedForum.rootID DESC,

    fixedForum.MAXdate  ASC"
    else
    subQuery = "SELECT TOP 2 fixedForum.rootID FROM fixedForum WHERE rootID not in (" & subSubQuery& ")

    ORDER BY fixedForum.rootID DESC, fixedForum.MAXdate ASC"
    END if

    שנה את ה-fixedForum לשם שנתת לשאילתא

  43. ניר טייב הגיב:

    וזה החזיר לי שאילתא כזו


    SELECT forum.id, forum.parentId, forum.subject,forum.message,forum.rootId
    FROM forum
    WHERE forum.rootId in (SELECT TOP 2 fixedForum.rootID FROM fixedForum WHERE rootID not in (SELECT TOP 48 rootID FROM fixedForum ORDER BY fixedForum.rootID DESC, fixedForum.MAXdate ASC) ORDER BY fixedForum.rootID DESC, fixedForum.MAXdate ASC)
    ORDER BY forum.id

  44. Yury הגיב:

    ניר ה=מלך=: הפעם הוכחת את הניק שלך!
    אתה בהחלט ראוי לתואר:)  אין לך מושג כמה עזרת לי!!

    אל תשכח לשלוח לי למייל כתובת לאן לשלוח את הצ'ק…

שלח תשובה