[MySQL] simpele db:1 table met 'bitmask' field

Pagina: 1
Acties:

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Ik moet een databaseje maken voor een klein siteje, zonder relationeel gedoe. Normaalgesproken identificeer ik dan de 'objecten' binnen zo'n site, zoals 'artikel' 'persoon' etc. Maar er zitten ook een heleboel stukjes op die site die maar 1 keer voor komen, dus dacht ik 'goh die pleur ik allemaal wel in een tabel, want de fields zijn toch meestal ongeveer zoiets als "id, parent_id, title, head, body, edit_date, author". Toen ik dat gedaan had zag ik ineens heel veel overeenkomsten met de 'persoon' en 'artikel' tabellen, dus dacht ik, waarom flikker ik de hele meuk niet in 1 dikke tabel? Zo ontzettend veel zal er niet in komen te staan...1000 entries zou me echt sterk verbazen.

Het vinden van de juiste data voor de juiste pagina wil ik doen met bitmasks. Ik gebruik daarvoor een 32-bit unsigned int field, en defineer in PHP m'n (max. 32) flags. Zo kan ik in 1 simpele query alle benodigde data voor 1 pagina gesorteerd eruit fietsen (simple voorbeeld voor nieuws-items op de home_page, alwaar ook een linker-kolom en rechter-kolom editabble text staat)
PHP:
1
<?$IS_NEWS_ITEM         = 1;//..//..$IS_RIGHT_COLUMM_TEXT = 128;$IS_LEFT_COLUMM_TEXT  = 256;//..//..$flags = $IS_RIGHT_COLUMM_TEXT | $IS_LEFT_COLUMN_TEXT | $IS_NEWS_ITEM;$query  = "SELECT * FROM content WHERE (flags &amp; ".$flags.") ORDER BY flags ASC, date DESC"; $result = my_process_query($query);?>

(kan zijn dat er fouten in de code zitten hoor)

Ik sorteer dus ook op flags, zodat ik de soorten content ook netjes gescheiden terugkrijg.

Ik heb dit nog niet geimplementeerd, maar ik vroeg me af of dit gewoon 'not done' is, of dat er haken en ogen aanzitten waar ik niet op zit te letten.
Tuurlijk is de uitbreidbaarheid lastig als je op een gegeven moment meer dan 32 flags nodig hebt, maar ik zit nu op 19, en dat kan als ik een beetje slimmer combineer ook nog wel minder. Sneller qua data ophalen is het enerzijds niet omdat alles door elkaar in 1 tabel staat, maar anderzijds wel omdat er maar 1 query per pagina is, welke ook nog eens akelig simpel is. Dus ja... is dit nou echt wat?

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Waarom niet gewoon in je query doen:
"SELECT * FROM content WHERE flags = 1 OR flags = 2 OR flags = 3 ORDER BY flags ASC, date DESC"

Bitmasks gebruiken in queries heb ik nog nooit gezien en ik vind het ook oerlelijk. Bedenk dat wanneer je bitmasks de query alle records af moet gaan. In het geval van de bovenstaande OR clauses kan al redelijk geoptimaliseerd worden door een steeds kleiner wordende resultaatset voor de volgende vergelijking en bovendien kan je nu ook gebruik maken van indices.

Daarnaast vraag ik me af hoever je abstraheert als je 'artikel' en 'persoon' als hetzelfde kan zien. Maar dit ligt aan de situatie natuurlijk, misschien verkoop je wel personen :+

Doe aub dingen die duidelijk zijn. Probeer niet alles in 1 tabel te proppen wanneer dat 'onlogisch' is. Bedenk ook dat lang niet alle items dezelfde eigenschappen hebben. Met het oog op de toekomst zit je straks misschien met 50 velden in een tabel waarbij 30 velden voor de meeste records helemaal niet van toepassing zijn. Dan vertraagt het eerder de boel dan de winst die je behaalt met 1 ipv 2 of 3 queries.

  • Sjab-X
  • Registratie: September 2001
  • Laatst online: 06-08 11:45
Ik zit met een soortgelijke kwestie. Heb een db met leden die in een bepaalde groep zitten, maar ook in meerdere groepen kunnen zitten.
Als je gebruik maakt van items die maar in 1 bepaalde groep zitten kan je beter kiezen om elke groep een id te geven (voor jou 1 t/m 19). Dat is wel flink sneller, maar je zal je items niet in 2 verschillende groepen kunnen stoppen.

Ik hoop dat je hier wat aan hebt :+

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op donderdag 18 juli 2002 13:06 schreef Sjab-X het volgende:
Ik zit met een soortgelijke kwestie. Heb een db met leden die in een bepaalde groep zitten, maar ook in meerdere groepen kunnen zitten.
Als je gebruik maakt van items die maar in 1 bepaalde groep zitten kan je beter kiezen om elke groep een id te geven (voor jou 1 t/m 19). Dat is wel flink sneller, maar je zal je items niet in 2 verschillende groepen kunnen stoppen.

Ik hoop dat je hier wat aan hebt :+
Maar hier zijn koppeltabellen voor:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Persons
------------
ID
name
phone


Groups
------------
ID
name
description


PersonsGroups
--------------
personID
groupID

Nu kan elke persoon tot 1, geen of meerdere groepen horen.

  • Sjab-X
  • Registratie: September 2001
  • Laatst online: 06-08 11:45
Op donderdag 18 juli 2002 13:15 schreef Orphix het volgende:
[..]
Maar hier zijn koppeltabellen voor:
[..]
Hmm... tja, klinkt logisch :)
Zo leer je elke dag weer wat :D

edit:

Maar dan is het natuurlijk de vraag of koppeltabellen sneller en kleiner zijn dan bitmasks?
Het is wel netter om koppeltabellen te gebruiken, maar het gaat waarschijnlijk wel meer ruimte innemen.

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Op donderdag 18 juli 2002 12:37 schreef Orphix het volgende:

prachtig verhaal
Ha kijk da's helder. Bitmask zijn natuurlijk heel snel als je zeker weet dat je een bepaalde lijst 1 voor 1 moet afwerken (pixels ofzo voor 'n mooi filter), maar in het geval van een SQL query valt het dus tegen, omdat ik niet wist dat ie na de eerste OR clause al met een simpeler set doorgaat.

Ik had idd ook wel een beetje moeite met het zo ombuigen van zaken dat het binnen "head", "title" en "body" te vangen was.

Ik verwacht op zich niet dat de db toekomstig wordt uitgebreid, maarja op deze manier zou ik me idd wel klem werken.

Daarnaast is het gebruik van nette heldere tabellen in tweede instantie ook wel een stuk relaxter voor als er iets mis gaat, of de admin interface gaat stuk zodat je er met phpmyadmin mee moet gaan prusten ofzo.

Goed dat ik nog ni ben begonnen met implementeren :)
Pagina: 1