[ALG] Forum posting info in een cachetabel?

Pagina: 1
Acties:

  • TangLeFuzZ
  • Registratie: Juni 2001
  • Laatst online: 15-10-2025
Hey,

edit: (na het schrijven van m'n post komt de topictitel niet echt meer overeen met de inhoud, sorry)

ik zit met een aantal dingen waar ik graag jullie mening over zou willen weten.

Ik ben op dit moment bezig met het herschrijven van 'forum' software, en zit een beetje tegen performance/database verhoudingen aan te hikken.

Bij het weergeven van een topic haal je normaliter post info uit een postings tabel, en daarbij ook userinfo uit een users tabel.

Buiten dat om, heb ik een aparte tabel voor userprofielen en een aparte tabel waar crewleden in gelinkt staan.

Als ik dingen als signature in m'n userprofiles tabel heb staan, en een speciale weergave van crewleden ook niet-hardcoded wil hebben, dan zal ik in mijn query 3 joins moeten gebruiken (join users, join userprofiles, join crew).
Zoals je misschien al snapt wil ik dit dus niet, en zit ik na te denken over wat de beste oplossing hiervoor is.

Ik heb op dit moment de informatie die bij een posting staat zoals signature/ondertitel/usericon, niet in de userprofiles tabel maar in de users tabel staan, en ik gebruik een crewtypeid en crewtitel veld in de users tabel voor de weergave van een crewlid.
Nu heb ik nog maar 1 join, namelijk tussen postings en users, maar nu zit m'n systeem dus niet meer in elkaar zoals ik het het liefst zou willen hebben.

Hoe zouden jullie zoiets oplossing? Ik denk dat het maar op de laatste manier moet, want ik zou niks anders weten....

performance is bij web applicaties imo toch wel belangrijker dan een goed model/database ontwerp.

edit: iets dat er ook nog bij komt is het bijhouden van wie er online is... dat doe ik het liefst ook niet in de users tabel, zou weer een extra join betekenen.

[ Voor 10% gewijzigd door TangLeFuzZ op 03-03-2006 11:39 ]


Verwijderd

Wat is het verschil tussen de users en userprofiles tables? Waarom kan dat niet in één?

  • TangLeFuzZ
  • Registratie: Juni 2001
  • Laatst online: 15-10-2025
Verwijderd schreef op vrijdag 03 maart 2006 @ 11:39:
Wat is het verschil tussen de users en userprofiles tables? Waarom kan dat niet in één?
Dat is eigenlijk puur voor eigen overzicht.

Ik heb profiel gescheiden van user info in m'n systeem (zijn verschillende classes), en daarom ook in de database.

Verwijderd

Dat lijkt me nou juist een beetje overbodig. Als je dat in één tabel doet hou je nog maar 1 join over.

Bijhouden wie er online is doe je inderdaad in een aparte tabel. Je hebt namelijk naast users ook gasten die online kunnen zijn, neem ik aan. In die tabel verwijs je met een userid naar je users-tabel.

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 04-01 15:49

JHS

Splitting the thaum.

TangLeFuzZ schreef op vrijdag 03 maart 2006 @ 11:40:
[...] Dat is eigenlijk puur voor eigen overzicht.
Maar dat is geen goed criterium voor je database indeling :) . Het zou het makkelijkst, efficiënts en volgens mij ook het juistst zijn als je álle userdata in een users table zet, de rechten van mensen in een rights table en een de online zaken uit een sessie table haalt. Het lijkt me dat het beter is je datamodel netjes te normaliseren :) .

De titel van je crewleden bijvoorbeeld passen denk ik een stuk beter ook in de users table, alleen mag lang niet iedereen die hebben, wat je met je rechtenmodel af kan dwingen.

DM!


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Als ik met mijn Java / Hibernate kennis hier naar kijk, dan zou ik een Topic gewoon laten bestaan uit een List van Posts. Iedere Post is gemaakt door een User, en die User zou ik 1 voor 1 on-demand ophalen. Dit gaat idd vreselijk traag, en heeft een grote bak queries tot gevolg. Echter, als je een cache zoals EHCache gebruikt betekent het juist dat je zelden aan de Users tabel hoeft te komen.

Dus het opvragen van een topic zal slechts een querie betekenen: het ophalen van een lijstje Posts.

Siditamentis astuentis pactum.


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Varienaja schreef op vrijdag 03 maart 2006 @ 12:41:
Iedere Post is gemaakt door een User, en die User zou ik 1 voor 1 on-demand ophalen. Dit gaat idd vreselijk traag, en heeft een grote bak queries tot gevolg. Echter, als je een cache zoals EHCache gebruikt betekent het juist dat je zelden aan de Users tabel hoeft te komen.
Ik ken Hibernate verder niet, maar dat lijkt me dan redelijk kut geregeld. Je moet die JOIN juist door de database laten uitvoeren, die kan dat een stuk sneller dan code die voor elke result row nog wat extra info gaat ophalen.

Ik heb een siteje met daarin een ledenbestand, de query die daar de ledengegevens ophaalt beslaat inmiddels geloof ik iets van 8 of 9 tabellen (via LEFT JOIN), en dat werkt echt prima.

Rustacean


  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 08-04 21:55
TangLeFuzZ schreef op vrijdag 03 maart 2006 @ 11:35:
performance is bij web applicaties imo toch wel belangrijker dan een goed model/database ontwerp.
Zo gemakkelijk ligt dat niet. Een database moet altijd een goed model zijn, normalizeren hebben ze niet voor niets 10tallen jaren geleden uitgevonden. Later kun je altijd nog kleine aanpassingen maken in verband met performance. (Bijvoorbeeld je totaal aantal posting als een vast gegeven opslaan, in plaats van elke keer weer opnieuw berekenen.)
Een niet goed ontworpen database gaat altijd falikant op zijn bek, vroeg of laat.

Ik hack zelf geen forum's in elkaar, maar je zou eens blik kunnen werpen in de keukens andere fora. Bijvoorbeeld myreact, de gratis versie van de de forumsoftware die ook hier op GoT gebruikt wordt.

  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Manuzhai schreef op vrijdag 03 maart 2006 @ 18:47:
Ik ken Hibernate verder niet, maar dat lijkt me dan redelijk kut geregeld. Je moet die JOIN juist door de database laten uitvoeren, die kan dat een stuk sneller dan code die voor elke result row nog wat extra info gaat ophalen.

Ik heb een siteje met daarin een ledenbestand, de query die daar de ledengegevens ophaalt beslaat inmiddels geloof ik iets van 8 of 9 tabellen (via LEFT JOIN), en dat werkt echt prima.
Ik zeg dus net dat ik helemaal niet voor iedere result row extra info ga ophalen. Die extra info staat namelijk in een cache.

Siditamentis astuentis pactum.


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Varienaja schreef op vrijdag 03 maart 2006 @ 22:15:
Ik zeg dus net dat ik helemaal niet voor iedere result row extra info ga ophalen. Die extra info staat namelijk in een cache.
Lijkt me nogal een overbodige vorm van caching. En wat als een gebruiker net zijn gegevens veranderd heeft?

Rustacean


  • TangLeFuzZ
  • Registratie: Juni 2001
  • Laatst online: 15-10-2025
Ik zie dat juist wel zitten.... zoiets als het volgende;

stel je hebt je gebruikers info verspreid zoals in jouw geval, over 8 tabellen.
Bij elke posting die je weergeeft wil je informatie hebben uit al die 8 tabellen.
Op jouw manier krijg je dan een query met 8 joins, die vrij zwaar is voor je database-bak.

Als je een cache tabel aanmaakt, waarin je al die informatie op slaat, heb je een query met maar 1 join (tussen de postings en de cache tabel) -> veel minder zwaar voor je database-bak.

Als een user zijn info wijzigd delete je gewoon de rij uit de cache tabel en genereer je deze opnieuw.
Sybr_E-N schreef op vrijdag 03 maart 2006 @ 18:58:
[...]

Zo gemakkelijk ligt dat niet. Een database moet altijd een goed model zijn, normalizeren hebben ze niet voor niets 10tallen jaren geleden uitgevonden. Later kun je altijd nog kleine aanpassingen maken in verband met performance. (Bijvoorbeeld je totaal aantal posting als een vast gegeven opslaan, in plaats van elke keer weer opnieuw berekenen.)
Een niet goed ontworpen database gaat altijd falikant op zijn bek, vroeg of laat..
Met die manier die ik hierboven beschrijf kun je a) een goed genormaliseerde database behouden/onderhouden, en heb je b) goeie performance :)

Of zie ik iets over het hoofd?

[ Voor 38% gewijzigd door TangLeFuzZ op 03-03-2006 23:28 ]


  • Civil
  • Registratie: Oktober 2002
  • Laatst online: 08-04 22:56
Maar waarom zou je gebruikers gegevens verspreiden over 8 tabellen ?

De gegevens zijn uniek voor die gebruiker. En zo lang het single data zoals een signature, homepage, naam, ondertitel, leeftijd of dat soort zaken hoort dat gewoon allemaal in één tabel. Alleen als meerdere rows (gegevens records) aan een user gekoppeld moeten worden voor een bepaald gegeven hoort dat in een aparte tabel.

Cachen ofwel gegevens dubbel opslaan moet je alleen doen als je database de gegevens niet snel genoeg kan leveren op de normale wijze. Dus denk eerst goed na over je datamodel, en als dan blijkt dat ondanks goede indexes de queries te veel tijd vergen kan je erover denken deze gegevens in een cache tabel per user op te slaan.

  • kmf
  • Registratie: November 2000
  • Niet online

kmf

members (id,passwd, wat je altijd moet hebben)
members_profile (icq, msn, wat je soms moet hebben)
topics
posts


member_groups (permissies, titel, whatever)
forums (id, name, description, permissies).


meber_groups en forums veranderen nagenoeg nooit, maar je hebt ze bijna altijd nodig.
Gooi ze in een grote array, serialize ze en stop ze in een cachebestand of tabel. Kan je weer direct oproepen als je ze nodig hebt. (group_id is dan arraykey natuurlijk)

Voor de rest, counts mijden als de pest, zeker als je niet zeker weet wat voor DBMS en/of tabeltype gebruikt.

Daar kom je ook wel een eind mee. Datamodel is er niet voor niks

One thing's certain: the iPad seriously increases toilet time.. tibber uitnodigingscode: bqufpqmp


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Civil schreef op vrijdag 03 maart 2006 @ 23:35:
Maar waarom zou je gebruikers gegevens verspreiden over 8 tabellen ?

De gegevens zijn uniek voor die gebruiker. En zo lang het single data zoals een signature, homepage, naam, ondertitel, leeftijd of dat soort zaken hoort dat gewoon allemaal in één tabel. Alleen als meerdere rows (gegevens records) aan een user gekoppeld moeten worden voor een bepaald gegeven hoort dat in een aparte tabel.
Bij mij was dat inderdaad het geval.

Rustacean


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Manuzhai schreef op vrijdag 03 maart 2006 @ 22:44:
Lijkt me nogal een overbodige vorm van caching.
Kan je dat wat verduidelijken?
En wat als een gebruiker net zijn gegevens veranderd heeft?
Als een gebruiker zijn gegevens verandert is de cache de eerste die het weet. Bij het schijven van het gewijzigde record is de cache daarvan al op de hoogte. Wat zou je immers aan een cache hebben als de inhoud onbetrouwbaar was?

Siditamentis astuentis pactum.


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Varienaja schreef op zaterdag 04 maart 2006 @ 15:57:
Als een gebruiker zijn gegevens verandert is de cache de eerste die het weet. Bij het schijven van het gewijzigde record is de cache daarvan al op de hoogte. Wat zou je immers aan een cache hebben als de inhoud onbetrouwbaar was?
Laat ik het zo zeggen: ik denk dat het garanderen van de consistentie van jouw cache meer performance kost dan het doen van een JOIN met een extra table in de database.

Rustacean


  • Metalman
  • Registratie: December 2003
  • Laatst online: 19:37
TangLeFuzZ schreef op vrijdag 03 maart 2006 @ 23:27:
Ik zie dat juist wel zitten.... zoiets als het volgende;

stel je hebt je gebruikers info verspreid zoals in jouw geval, over 8 tabellen.
Bij elke posting die je weergeeft wil je informatie hebben uit al die 8 tabellen.
Op jouw manier krijg je dan een query met 8 joins, die vrij zwaar is voor je database-bak.

Als je een cache tabel aanmaakt, waarin je al die informatie op slaat, heb je een query met maar 1 join (tussen de postings en de cache tabel) -> veel minder zwaar voor je database-bak.

Als een user zijn info wijzigd delete je gewoon de rij uit de cache tabel en genereer je deze opnieuw.

[...]

Met die manier die ik hierboven beschrijf kun je a) een goed genormaliseerde database behouden/onderhouden, en heb je b) goeie performance :)

Of zie ik iets over het hoofd?
Ik heb het idee dat je je de moeite met een cache tabel veel beter kunt besparen. Zorg voor een goed datamodel, netjes genormaliseerd, en maak gewoon een mooie multiple JOIN query die de benodigde gegevens ophaalt. Als je je indexes dan een beetje goed aanlegt, en eens wat tests draait met die query (in termen van verwerkingstijd) dan krijg je een vrij goed idee hoe zwaar of niet zwaar dit is.

Persoonlijk denk ik dat een JOIN uit 3 tabellen (hoewel dit ook met minder tabellen moet kunnen, zoals [rml]Civil in "[ ALG] Forum posting info in een cachetab..."[/rml] al opmerkte) niet per se heel traag hoef te zijn. Sowieso heb je op een forum eigenlijk altijd paginatie. Laten we uitgaan van een een aantal posts per pagina van 50. Dit betekent dat je iedere keer maar 50 resultaten op hoeft te halen.

Mits je strategisch geplaatste indexes hebt, en de tip van Civil opvolgt, moet dit geen problemen opleveren voor de performance. Sowieso is een DBMS als het goed is geoptimaliseerd voor het gebruik van JOIN's. Dit moet dan ook gewoon snel uitgevoerd kunnen worden, zonder performance problemen. Mocht je forum zó druk worden dat dit wel het geval is, dan kan je altijd nog kijken naar een server side caching mechanisme. Die verlaagt de load op je DB bak flink, en maakt dus dat áls die JOIN weer een keer uitgevoerd wordt voor een cache update, dit gewoon vrij snel moet kunnen verlopen. Of je schaft een snellere database server aan O-)

Al met al lijkt deze oplossing een stuk simpeler en volgens mij ook efficiënter dan het gebruik van een aparte cache tabel. Maar zoals gezegd, probeer het eens uit met een testje. Desnoods test je dan ook het gebruik van een cache tabel. Dat is eigenlijk de enige manier waar op je zeker kunt weten wat het snelste is. Tenzij iemand hier dit al eens gedaan heeft en wat resultaten kan presenteren? Daar heb ik zelf ook wel interesse in.

[ Voor 1% gewijzigd door Metalman op 06-03-2006 08:45 . Reden: 8 tabellen veranderd naar 3 ;) ]


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Ik vind het heel grappig dat iedereen nu doorgaat op de 8 tabellen, maar dat was een projectje van mij, en niet van de topicstarter. :P

Rustacean


  • Gert
  • Registratie: Juni 1999
  • Laatst online: 05-12-2025
Dat komt omdat je zoveel onzin schrijft. :o
Je doet hier in 3 posts even het hele principe van object caching buiten de deur zetten terwijl dit wel 100-den procenten snelheids verbetering kan opleveren.

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Gert schreef op maandag 06 maart 2006 @ 09:10:
Dat komt omdat je zoveel onzin schrijft. :o
Je doet hier in 3 posts even het hele principe van object caching buiten de deur zetten terwijl dit wel 100-den procenten snelheids verbetering kan opleveren.
Ik heb in mijn 5 jaar ervaring met PHP/MySQL-applicaties nog NOOIT object caching nodig gehad. Met PHP werkt dat namelijk ook helemaal niet goed, door de shared-nothing architectuur.

Ik weet natuurlijk niet wat voor taal de TS gebruikt, maar volgens mij moet het zonder object-caching ook echt prima werken.

Rustacean


  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 23:36
TangLeFuzZ schreef op vrijdag 03 maart 2006 @ 11:35:
[...] dan zal ik in mijn query 3 joins moeten gebruiken (join users, join userprofiles, join crew).
Zoals je misschien al snapt wil ik dit dus niet, en zit ik na te denken over wat de beste oplossing hiervoor is.[...]
Ik zie het probleem met een paar joins niet zo... Daar heeft geen enkele database moeite mee zolang je indexen goed liggen. (had ie maar geen database moeten worden).
performance is bij web applicaties imo toch wel belangrijker dan een goed model/database ontwerp.
Performance en een goed databasemodel gaan volgens mij vaak redelijk hand in hand. Een enkele uitzondering daargelaten. Daarnaast heeft een goed model het voordeel dat je in de toekomst wat flexibeler bent. Met de huidige hardwareprijzen is het economisch gezien veel interessanter om winst te halen op programmeurskosten, extra rekenkracht kost toch haast niets. Een goed model is wat mij betreft dus altijd de goede keuze, zelfs al zou dat iets in performance schelen...

Regeren is vooruitschuiven


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:35

Creepy

Tactical Espionage Splatterer

Nog ff een kleine move naar Software Engineering & Architecture :)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

T-MOB schreef op dinsdag 07 maart 2006 @ 02:14:
[...]

Ik zie het probleem met een paar joins niet zo... Daar heeft geen enkele database moeite mee zolang je indexen goed liggen. (had ie maar geen database moeten worden).


[...]

Performance en een goed databasemodel gaan volgens mij vaak redelijk hand in hand. Een enkele uitzondering daargelaten. Daarnaast heeft een goed model het voordeel dat je in de toekomst wat flexibeler bent. Met de huidige hardwareprijzen is het economisch gezien veel interessanter om winst te halen op programmeurskosten, extra rekenkracht kost toch haast niets. Een goed model is wat mij betreft dus altijd de goede keuze, zelfs al zou dat iets in performance schelen...
^^ with stupid.

ga eerst maar eens een goed model ontwerpen. bouw daarboven een datalaag met vaste interface die jouw databank abstract maakt.
bouw daarboven je webbie en gebruik em maar. Heb je dan performance problemen, ga dan maar eens je queries analyzen om de minst efficiente eruit te peuteren of om indices etc goed te plaatsen.
moet er dan iets gewijzigd worden dan verandert enkel de implementatie van je datalaag.

een DB is geoptimaliseerd om al die taken uit te voeren (zeker joins) dus heb vertrouwen in de DB-programmeurs.

wat indices betreft:
indices waar nodig (veel joins/sortering/... op de kolommen)
geen indices waar niet nodig (per index die je maakt mag je een penalty rekenen bij toevoegen/updaten)

ASSUME makes an ASS out of U and ME


  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 04-01 15:49

JHS

Splitting the thaum.

HIGHGuY schreef op dinsdag 07 maart 2006 @ 11:33:
indices waar nodig (veel joins/sortering/... op de kolommen)
geen indices waar niet nodig (per index die je maakt mag je een penalty rekenen bij toevoegen/updaten)
Let er (dus) op dat het volgens mij af en toe tot zelfs vaak het neerkomt op benchmarken als het gaat om velden/kolommen waar zowel veel geüpdated / toegevoegd wordt als veel gejoined / gesorteerd / gewhered wordt :) . Er zijn misschien wel rekensystemen met penalties en dergelijke maar ik betwijfel of dat (altijd) voldoet.

DM!


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

JHS schreef op dinsdag 07 maart 2006 @ 13:59:
[...]
Let er (dus) op dat het volgens mij af en toe tot zelfs vaak er neerkomt op benchmarken als het gaat om velden/kolommen waar zowel veel geüpdated / toegevoegd wordt als veel gejoined / gesorteerd / gewhered wordt :) . Er zijn misschien wel rekensystemen met penalties en dergelijke maar ik betwijfel of dat (altijd) voldoet.
ik wist niet eens dat zulke dingen ook uitgerekend worden en waardevol gevonden worden. Mijn inspiratie kwam 100% uit common sense wanneer je een tabel opbouwt en indices plaatst.

ASSUME makes an ASS out of U and ME


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08-04 12:03

Janoz

Moderator Devschuur®

!litemod

Manuzhai schreef op dinsdag 07 maart 2006 @ 00:12:
[...]
Ik heb in mijn 5 jaar ervaring met PHP/MySQL-applicaties nog NOOIT object caching nodig gehad. Met PHP werkt dat namelijk ook helemaal niet goed, door de shared-nothing architectuur.
Ik denk dat vooral de tweede opmerking hier van groot belang is. Object caching is in een php omgeving met geen mogelijkheid fatsoenlijk te implementeren. In dat geval zul je dus altijd gewoon op de standaard non-caching of caching van de DB-server zelf aangewezen zijn. Dat betekent natuurlijk niet dat in wat proffesionelere omgevingen het dan ook gelijk onzin is. Zoals bij de start van deze sub discussie al aangegeven ging dit voorstel specifiek over het gebruik van Hibernate (J2EE).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op donderdag 09 maart 2006 @ 11:41:
Object caching is in een php omgeving met geen mogelijkheid fatsoenlijk te implementeren.
Niet cross requests nee, maar in een request is het prima te doen. Met mijn forumsoftware heb ik ook alle joins vermeden, vooral ook omdat ik voor sommige entities nog wat processing wil doen. Het is dan niet handig dat je voor elke post weer nieuwe user-informatie hebt, eigenlijk wil je per post dan gewoon een verwijzing naar een user. Dat doe ik dan ook door eerst de relevante posts op te halen, vandaaruit user-id's te verzamelen en aan het eind gewoon een GET * FROM users WHERE user_id IN (lijstje-met-id's) te doen. En dit geldt niet alleen voor posts, zo'n beetje elke tabel heeft wel een verwijzing naar een user, en die verzamel ik allemaal voordat ik de daadwerkelijke users ophaal. 't Is weliswaar een extra query, maar het is ook een stuk minder overhead dan al die redundante data die wordt overgestuurd van mysql naar je script en door de mysql-module van php geinterpreteerd moet worden.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1