webForumDet fria alternativet

Relativt avancerat forum - databasstruktur mm.

ASP

18 svar · 469 visningar · startad av magnusfernstrom

Medlem sedan mars 20033 686 inlägg
Frågan#1

Ja, då ska även jag försöka mig på ett ganska avancerat forum. Jag har tidigare bara gjort småforum, utan kategorier. Nu var det tänkt att mitt forum dock skulle ha just olika kategorier.

Kategorier
Skall man ha alla kategorier i en separat tabell. Skall även trådarna samt allt annat ligga i samma tabell?

Om inte, hur skulle en SQL-sats se ut om man t.ex. skall hämta trådens rubrik från en tabell samt vilket forum den tillhör i en annan tabell?

Moderatorer
Vart skall informationen om vilka som modererar vad ligga? Hur skulle ni lägga upp det, t.ex. skall det vara tal som håller reda på det hela, eller text i databasen?

Lite frågor som sagt. Skulle vara tacksam för svar.

/Magnus

Medlem sedan dec. 1999707 inlägg
#2

Jag vet ju inte riktigt hur du hade tänkt dig men kategorierna skulle jag lagt i separat tabell. Jag antar att du vill ha förhållandet: en kategori har 0 till flera forum. Vill man kämpa sig så kan man ju lägga flera nivåer av kategorier. Ex:

Category (tabell)
--------------------
- ID (PK)
- ParentID (FK) (null eller <0 = root-nivå)
- Title
- Description

Vem som modererar kanske kan ligga som en associationstabell för forum. Frågan är om det ska finnas kategori-moderatorer? :q

Forum
--------
- ID (PK)
- CategoryID (FK)
- Title
- Description
- CreateDate

ForumModerator
--------------------
- ForumID (FK)
- UserID (FK)

Trådarna/inläggen ser jag som som samma objekt, dvs på liknande sätt som kategorier anger man i ett fält vilket det är på den tråden som besvaras.

Post (inget superbra namn)
-----------------------
- ID (PK)
- ForumID (FK)
- ParentID (FK) (null eller <0 = en tråd)
- Author (FK) (från user-tabellen)
- CreateDate
- UpdateDate
- Title
- Text

För att hämta alla trådar (inlägg med ParentID = null) skulle i sådana bli typ såhär:

SELECT
         p.*,
         f.Title,
         f.Description,
         c.Title,
         c.Description
FROM
         Post p

         INNER JOIN
         Forum f
         ON
         p.ForumID = f.ID

         INNER JOIN
         Category c
         ON
         f.CategoryID = c.ID

         INNER JOIN
         User u
         ON
         u.ID = p.AuthorID
WHERE
         isnull(p.ParentID, -1) = -1
ORDER BY
         p.createDate DESC

eller? :l

Medlem sedan mars 20033 686 inlägg
#3

Uj, uj, uj, svåra SQL-fråga för en nybörjare det där ;)

Jag får trixa vidare lite.
Tack för hjälpen, återkommer senare.

Medlem sedan mars 20033 686 inlägg
#4

Ooookej, nu är jag igång i alla fall ;) :)

Dock har jag endast gjort detta "avancerade forum" mycket enkelt nu i början.

De tabeller som finns i databasen som är releventa för tillfället är:

users
- username
- password

status
- namn
- forum

Där forum är ett tal och anger vilket forum man modererar.

I users finns alla användare och information om dem och i status vilken nivå på sidan de har, samt vem som har dem.

Jag kollade lite i min fina lilla ASP-bok och gjorde på följande sett med SQL-satsen:

SELECT DISTINCTROW users.username, users.password, status.namn, status.forum FROM users LEFT JOIN status ON users.username = status.namn

Jag har inte tillgång till någon ASP-server, men skulle denna kod fungera? Den skall alltså hämta användarnamnet i users-tabellen och kolla om användarnamnet finns i status-tabellen, och sedan kolla vilket forum användaren modererar.

Om jag har fattat det rätt hämtar man först datan ur tabellen users och kollar sedan om den finns i status.

Fast som sagt, jag har antagligen fattat det hela helt fel. Så om någon vänlig själ skulle vela förklara vad som egentligen händer i min SQL-sats vore det trevligt.

Och om det är fel, hur skall jag göra en korrekt? Och vad händer i den eventuellt nya SQL-satsen? Det vore också kul och intressant och veta vad som hände i den förra SQL-satsen även om den är felaktig. Känns som om detta är ett område jag inte kan något om men borde kunna något om.

Rörigt, rörigt, men är lite stressad då jag sitter på modemuppkoppling och vill inte slösa allt för mycket på pengarna.

Tacksam för svar.

/Magnus

Medlem sedan juli 20033 147 inlägg
#5

Borde inte SQL-frågan se ut såhär?

SELECT username, password
FROM users
LEFT JOIN status
ON users.username = status.namn

Kan mycket väl ha fel. :OO

/r glöm det, jag missuppfattade allt. :)

Medlem sedan mars 20033 686 inlägg
#6

Melea: Fråga inte mig ;)

Som sagt, jag har ingen aning om vad som rätt och fel inom SQL om man säger så :)

Medlem sedan mars 20033 686 inlägg
#7

Det verkar fungera med den SQL-sats jag skrev. Tack för hjälpen ändå Melea :)

Medlem sedan dec. 1999707 inlägg
#8

Ok, jag vet inte vilken nivå jag ska lägga det, så jag kör på... :)

DISTINCTROW, eller DISTINCT som det är i om man skriver uttryck för SqlServer (T-SQL), ser till så att varje rad i ditt resultat blir unikt. Om du exempelvis i din user-tabell hämtar alla förnamn som finns så kanske det finns flera som heter "Magnus" vilket gör att du får en massa dubletter. DISTINCT ser till att du får unika rader i resultat.

Med LEFT JOIN hämtar du värden från en annan tabell och anger relationen mellan dom i uttrycket ON. MEN, vid om den inte hittar den relationen mellan tabellerna på en viss rad så tar den bara med värden från den tabellen som står till vänster om LEFT JOIN. Right join är givetvis tvärtom. Och vid en INNER JOIN så måste relationen finnas annars kommer inte raden med i resultatet alls.

Dvs. ditt sql-uttryck hämtar, från varje rad, alla fält som finns i tabellen users samt, OM relationen mellan username och namnfälten "users.username" och "status.namn" finns, fälten som finns i tabellen status. Dessutom ser den till det inte finns några dubletter i resultatet.

Om jag skulle skriva uttycket som hämtar alla forum-id:n (status.forum) som en användare basar för skulle det nog bli såhär:

SELECT
        users.username,
        status.*
FROM
        users
        LEFT OUTER JOIN
        status
        ON
        status.user = users.username

Det kanske är "LEFT JOIN" i Access/mySQl, vet inte...
Jag tog bort distinct och fältet password. Resultat för en användare kan alltså blir 1 till flera rader beroende hur många rader han relaterar till i status-tabellen. Om en användare inte alls existerar i status-tabellen så blir resultatet för den raden:

<username>, null, null

Ang users-tabellen så skulle jag använda mig av en identity, eller räknare, för tabellen. Brukar var lättare att ha en int som nyckel för en tabell än en sträng; alternativt om man använder sig av ett guid, men det tycker jag inte behövs i det här fallet.

Jag är lite petig av mig men... Alla tabeller brukar man döpa, om möjligt, så att dom får ett "singularis namn". Dvs istället för "forums" blir det "forum", istället för "users" blir det "user". När man modellerar brukar man tänka sig att varje tabell, eller rad i en tabell, är ett objekt.

Medlem sedan juli 20033 147 inlägg
#9

toha: Har följt den här diskussionen med spänning, tack för dina inlägg!
Håller just nu på att bygga en version 3 av en sida som har ca. 5000 besökare dagligen och en bättre struktur i koden är ett måste, jag fick lite idéer från hur du döper dina tabeller och kolumner i databasen, tack! :)

Medlem sedan dec. 1999707 inlägg
#10

Ingen orsak. :r

Medlem sedan mars 20033 686 inlägg
#11

För att fortsätta på en gammal tråd. :)

Jag har nu ett nytt forum på gång, då jag råkade slänga det förra. :(

Nåväl, har denna sats:

SQL = "SELECT tblUsers.userUsername, tblUsers.userStatus, tblAdmin.adminForum, tblAdmin.adminUsername FROM tblUsers LEFT OUTER JOIN tblAdmin ON tblAdmin.adminUsername = tblUsers.userUsername"

Databasen har en tabell som hter tblUsers.
- userUsername
- userStatus

En annan tabell heter tblAdmin
- adminUsername
- adminForum

Om man har status 1 i user-tabellen är man en nivå och har rättigheter till allt i forumet, 2 så är man medlem i gruppen som sidan är åt, 3 så är man administratör. Om man har 0 är man medlem. Dock anges det vilka som är moderatorer i admin-tabellen. Där anges det namnet på moderatorn samt forumets ID.

När jag loggar in som mig själv får jag status 1, och jag har även gjort mig själv till moderator för forum 2. Så även det står det att jag är.

Men, om jag loggar in med en medlem med andra rättigheter, eller inga alls får jag exakt samma resultat som när jag loggar in med min användare.

Okej, jag är skitdålig på att förklara, dels för att jag knappt fattar vad jag håller på med, dels för att jag helt enkelt suger på att förklara. :)

Någon som fattar?

Medlem sedan dec. 20025 871 inlägg
#12

Kan det bero på en cachad version av sidan, tro?

Medlem sedan mars 20033 686 inlägg
#13

Det kan det säkert.

Förklaring!? :)

Medlem sedan mars 20033 686 inlägg
#14

Ålrajt. Här är hela koden:

<%

      If Request.Querystring("action") = "login" Then

   Function SQLEncode(ByVal sString)
   SQLEncode = Replace(trim(sString), "'", "''")
   End Function

   Set Conn = Server.CreateObject("ADODB.Connection")
   Conn.Open "Driver={Microsoft Access Driver (*.mdb)}; DBQ=" & server.mappath("***.mdb") &"; uid=; pwd="&***&";"

      uName        = SQLEncode(Request.Form("uName"))
	  pWord        = SQLEncode(Request.Form("pWord"))

      SQL = "SELECT * FROM tblUsers WHERE userUsername = '" & uName & "'"
	  Set rs = Conn.Execute(SQL)

	  If uName = "" Then
      Response.Redirect "index.asp"
      End If

      If pWord = "" Then
      Response.Redirect "index.asp"
      End If 

   	     If rs.EOF then

         Response.Redirect "index.asp?msg=loginfailed"

         Else

		    If uName = rs("userUsername") AND pWord = rs("userPassword") Then

			Session("inloggad") = "yes"
			Session("userID") = rs("userID")
			Session("uName") = rs("userUsername")

			   SQL = "SELECT tblUsers.userUsername, tblUsers.userStatus, tblAdmin.adminForum, tblAdmin.adminUsername FROM tblUsers LEFT OUTER JOIN tblAdmin ON tblAdmin.adminUsername = tblUsers.userUsername"
			   Set rs = Conn.Execute(SQL)

			   Session("admin") = rs("userStatus")
			   Session("admin_forum") = rs("adminForum")

			   rs.Close
			   Set rs = nothing

 
            Response.Redirect "index.asp"
            
			End If

	  	 End If

		 End If

		 If Request.Querystring("action") = "logout" then

		 Session.Abandon

		 Response.Redirect "index.asp"

		 End If

%>
Medlem sedan mars 20033 686 inlägg
#15

Åååkej, nu åker snart något i väggen. Börjar bli mycket irriterad på detta problem nu!

Jag har fixat lite med det under eftermiddagen utan succé. Det verkar som om den endast hämtar den som står först i databasen. För att det är alltid mina rättigheter alla användare får.

Så, vad kan vara fel? Nu har vi lite mer kött på benen iallafall.

Medlem sedan dec. 20025 871 inlägg
#16

Titta på din SQL-fråga igen.

Jag ser inte någonstans där det finns ett WHERE-villkor. :OO ;)

Medlem sedan mars 20033 686 inlägg
#17

Nej, men hur fifflar jag in den i en krånglig som den där....saken!?

(SQL-satsen alltså.) :)

Jag försökte jämföra med formen. Men det blev fel.

Jag vore hur tacksam som helst om du kunde visa vart ett WHERE-villkor skall vara. :)

/M

Medlem sedan dec. 20025 871 inlägg
#18

Jag är inte så haj på det här med Joins, men du behöver ju jämföra med en sträng för att kunna veta vad personen som loggar in har för rättigheter. ;)

Testa med att lägga till detta i slutet av din SQL:

WHERE tblUsers.userID = " & rs("userID")

Alltså:

"SELECT tblUsers.userUsername, tblUsers.userStatus, tblAdmin.adminForum, tblAdmin.adminUsername FROM tblUsers LEFT OUTER JOIN tblAdmin ON tblAdmin.adminUsername = tblUsers.userUsername WHERE tblUsers.userID = " & rs("userID")
Medlem sedan mars 20033 686 inlägg
#19

Jamen visst fungerar det!!

Silly av mig att tro att jag kan SQL :e

:r

LeonL :f :f :f

272 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
120 ms — deklarationer (db)
0 ms — hämta statistik (cache)
139 ms — hämta tråd, inlägg och bilagor (db)
129 ms — ändringar (db)