Toon posts:

[mysql] Bitwise operations BIGINT is te klein

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een probleem met een bitwise operations die ik gebruik:
Ik heb namelijk een entiteit Plaatje en een Entiteit Gallery. Een Plaatje kan opgenomen worden in 1 of meerdere Galleries. Daarvoor heb ik een kolom "ingallerybit" van type INTEGER in de pictures tabel.

Als dus een plaatje opgenomen worden in een gallery doe ik:

update pictures set ingallerybit=ingallerybit+$num where picid=1

$num is dan: 0, 2, 4, 8, 16, 32, 64, enzovoorts (afhankelijk van de Gallery)

Dan kan ik mooi zien welk plaatje in een gallery zit door de volgende query:

select * from pictures where ((ingallerybit & $num) <> 0)

Dat werkt allemaal goed, maar nu zit ik met meer dan 100 galleries en nu past $num niet meer in INTEGER ook BIGINT zal gauw te klein zijn.

Overigens heb ik nog veel meer velden in de tabel "pictures" waar ik deze constructie gebruik:
todaybit, yesterdaybit, postedbit, currentbit en zo'n 15 andere. En als ik een pictures select doe dan zitten al deze velden in het "where" gedeelte.

Ik heb al wat naar andere data types gekeken van mysql maar ik kan niet een soortgelijke vinden die mogelijk een oplossing zou bieden.

Weten jullie een oplossing voor mijn probleem?

_/-\o_

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
      4 
      8 
      16 
      32 
      64 
      128 
      256 
      512 
      1024 
      2048 
      4096 
      8192 
      16384 
      32768 
      65536 
      131072 
      262144 
      524288 
      1048576 
      2097152 
      4194304 
      8388608 
      16777216 
      33554432 
      67108864 
      134217728 
      268435456 
      536870912 
      1073741824 
      2147483647 
      ...

[ Voor 27% gewijzigd door Verwijderd op 05-07-2005 15:17 ]


  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Verwijderd schreef op dinsdag 05 juli 2005 @ 15:13:
Weten jullie een oplossing voor mijn probleem?
Je datamodel aanpassen, je hebt een koppeltabel erbij nodig waarin je bijhoudt in welke gallery's een plaatje voorkomt.

[ Voor 12% gewijzigd door justmental op 05-07-2005 15:18 ]

Who is John Galt?


  • Mir
  • Registratie: Maart 2001
  • Niet online

Mir

Een koppeltabel maken? :)

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 10:22
edit:
En nu pas zie ik dat U niet de TS bent die zich afvraagt wat een koppeltabel is... Voor de verdwaalde user die dat ooit nog zoekt laten we deze niet zo wakkere reactie staan. De rest kan lekker door naar de volgende reply ;)


Je hebt een tabel met Galleries en een tabel met Plaatjes. In de koppeltabel koppel je deze aan elkaar.
[b]galleries:[/b]
Galleryid | foo | bar

[b]images:[/b]
Imageid | foo | bar

[b]imggal:[/b] (de koppeltabel)
Galleryid | Imageid


Nu kun je van elk plaatje opvragen in welke gallery(-ies) het zit:
code:
1
2
3
4
SELECT galleryid, foo, bar 
FROM imggal 
INNER JOIN galleries ON (galleries.galleryid = imggal.galleryid)
WHERE imageid = value;


Voor de id's kun je nu gewoon alle integers gebruiken waardoor je met een (unsigned) smallint al 65.535 galleries kunt hebben.

[ Voor 15% gewijzigd door T-MOB op 05-07-2005 15:38 ]

Regeren is vooruitschuiven


Verwijderd

Topicstarter
Dank jullie voor de replies. Ik had oorspronkelijk ook koppeltabellen gebruikt, maar ik wist niet meer waarom ik over gestapt was naar de bitwise methode.

Maar nu ik koppeltabellen weer probeer te implementeren weet ik het weer: ik kan met koppeltabellen een bepaalde query niet maken, namelijk:
"selecteer alle plaatjes die niet in galleryX (met id: 7) voorkomen"

select g.* from galleries g left join koppelin kin on kin.galleryid = g.id
where ((kin.galleryid <> 7) and (kin.galleryid IS NULL) )


code:
1
2
select p.* from pictures p left join koppelin kin on kin.pictureid= p.id 
where ((kin.galleryid<> 7) and (kin.galleryid IS NULL) )



Het volgende gaat wel:
"selecteer alle plaatjes die niet in een gallery voorkomen"
(dan check je gewoon of een veld in de koppel tabel NULL is)
code:
1
2
select g.* from galleries g left join koppelin kin on kin.galleryid = g.id 
where ((kin.galleryid IS NULL) )


Ik gebruik mysql4, dus subselects zijn helaas niet mogelijk. Weet iemand een oplossing?

[ Voor 13% gewijzigd door Verwijderd op 05-07-2005 18:41 ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Je moet daarvoor toch ook gewoon een inner join hebben? :?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Verwijderd

Topicstarter
Oops, ik had een foutje gemaakt in de sql query tijdens het typen van m'n vorige bericht (zie doorgehaalde code)

"selecteer alle plaatjes die niet in galleryX (met id: 7) voorkomen"
code:
1
2
select p.* from pictures p left join koppelin kin on kin.pictureid= p.id 
where ((kin.galleryid<> 7) and (kin.galleryid IS NULL) )
Je moet daarvoor toch ook gewoon een inner join hebben?
Wat bedoel je precies? Zoiets:

code:
1
2
select p.* from pictures p inner join koppelin kin on kin.pictureid= p.id 
where ((kin.galleryid<> 7) and (kin.galleryid IS NULL) )


? Dat werkt overigens ook niet.

Of uit gaande van T-MOB db schema: hoe kun je hier alle "images" die niet in "gallery" met id 7 voorkomen ophalen? Ik zit er al de hele tijd na te kijken, maar ik kan me geen select query verzinnen, natuurlijk wel met subqueries (NOT IN), maar die kan ik niet gebruiken.

[ Voor 21% gewijzigd door Verwijderd op 05-07-2005 18:47 ]


  • Onno
  • Registratie: Juni 1999
  • Niet online
Verwijderd schreef op dinsdag 05 juli 2005 @ 17:47:
Maar nu ik koppeltabellen weer probeer te implementeren weet ik het weer: ik kan met koppeltabellen een bepaalde query niet maken, namelijk:
"selecteer alle plaatjes die niet in galleryX (met id: 7) voorkomen"

select g.* from galleries g left join koppelin kin on kin.galleryid = g.id
where ((kin.galleryid <> 7) and (kin.galleryid IS NULL) )


code:
1
2
select p.* from pictures p left join koppelin kin on kin.pictureid= p.id 
where ((kin.galleryid<> 7) and (kin.galleryid IS NULL) )



Het volgende gaat wel:
"selecteer alle plaatjes die niet in een gallery voorkomen"
(dan check je gewoon of een veld in de koppel tabel NULL is)
code:
1
2
select g.* from galleries g left join koppelin kin on kin.galleryid = g.id 
where ((kin.galleryid IS NULL) )
Dat laatste doet niet wat je zegt dat het moet doen. Nu vraag je alle galleries op zonder plaatjes, ongeveer het omgekeerde dus. Maar om even met die query verder te gaan, stel nou dat je alle galleries wilt hebben zonder een specifiek plaatje, dan zou je gewoon een kin.imageid = x toe kunnen voegen.
code:
1
2
select g.* from galleries g left join koppelin kin on kin.galleryid = g.id
and kin.imageid = x where kin.galleryid is null

Datzelfde kun je ook doen voor wat je wilt.
-NMe- schreef op dinsdag 05 juli 2005 @ 17:52:
Je moet daarvoor toch ook gewoon een inner join hebben? :?
Nee, een outer join. :)

[ Voor 13% gewijzigd door Onno op 05-07-2005 18:58 ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Tuurlijk werkt die inner join die je nu post niet. Kijk eens goed wat je doet:
SQL:
1
where ((kin.galleryid<> 7) and (kin.galleryid IS NULL) )

Hoe kan een id nu tegelijk 7 en NULL zijn?
* NMe wrijft even zijn ogen uit en probeert het nog eens. :P

[ Voor 14% gewijzigd door NMe op 05-07-2005 19:03 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Verwijderd

Topicstarter
-NMe- schreef op dinsdag 05 juli 2005 @ 18:56:
Tuurlijk werkt die inner join die je nu post niet. Kijk eens goed wat je doet:
SQL:
1
where ((kin.galleryid<> 7) and (kin.galleryid IS NULL) )

Hoe kan een id nu tegelijk 7 en NULL zijn?
Dat weet ik ;) Ik geef alleen aan wat ik geprobeert heb, maar ik kom er niet meer uit.
Daarom vraag ik jullie hulp.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Probeer dan eens diezelfde inner join die je net postte maar vervang dan die and door een or. Mocht je ook plaatjes zonder album hebben, dan kun je die left join nog eens proberen, maar dan ook weer die and vervangen.

Overigens, NULL is ook ongelijk aan 7, dus dat stuk kan gewoon weg. :P

[ Voor 60% gewijzigd door NMe op 05-07-2005 19:13 . Reden: Goed bezig, Herman. :X ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Onno
  • Registratie: Juni 1999
  • Niet online
-NMe- schreef op dinsdag 05 juli 2005 @ 19:01:
Overigens, NULL is ook ongelijk aan 7, dus dat stuk kan gewoon weg. :P
Nee. NULL <> 7 is false. (of eigenlijk NULL, maar niet true in ieder geval)

[ Voor 13% gewijzigd door Onno op 05-07-2005 19:06 ]


Verwijderd

Topicstarter
Oei, oei, ik vermoed dat ik het enigszins verwarrend heb gemaakt door direct queries tt kopieren uit m'n code. Bij mij zijn pictures namelijk galleries en die zijn gekoppelt aan een website. Laten we even het allemaal wat duidelijker maken: vergeet al het bovenstaande ;-) Laten we uitgaan van het db schema van T-MOB:

code:
1
2
3
4
5
6
7
8
galleries:
Galleryid | foo | bar

images:
Imageid | foo | bar

imggal: (de koppeltabel)
Galleryid | Imageid


"geeft me alle galleries"
code:
1
select * from galleries


"geef me alle plaatjes van gallery met id: 7"
code:
1
2
select * from images i left join imggal k on i.imagid=k.imageid 
where k.galleryid=7


"geef me alle plaatjes die niet in een gallery voorkomen"
code:
1
2
select * from images i left join imggal k on k.imageid=i.imageid 
where k.galleryid IS NULL


Nu komt het probleem:
"geef me alle plaatjes die niet in gallery met id: 7 voorkomen"
code:
1
2
select * from images i inner join imggal k on k.imageid=i.imageid where 
((k.galleryid<> 7) or (k.galleryid IS NULL) )


Weet iemand hoe ik de laatste query werkend krijg?

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
"geef me alle plaatjes die niet in gallery met id: 7 voorkomen"
code:
1
2
3
4
SELECT * 
FROM images i 
LEFT OUTER JOIN imggal k on k.imageid=i.imageid AND k.galleryid = 7 
WHERE k.galleryid IS NULL

Oops! Google Chrome could not find www.rijks%20museum.nl


Verwijderd

Topicstarter
P_de_B schreef op dinsdag 05 juli 2005 @ 19:30:
"geef me alle plaatjes die niet in gallery met id: 7 voorkomen"
code:
1
2
3
4
SELECT * 
FROM images i 
LEFT OUTER JOIN imggal k on k.imageid=i.imageid AND k.galleryid = 7 
WHERE k.galleryid IS NULL
Dank je! Deze werkt :) Het is wel een ingewikkelde, een "left outer join", ik moest eerst even kijken wat dat nu ook alweer deed.

Maar als ik het goed begrijp haalt de db nu eerst alle rijen in de images tabel op, daarna alle rijen in de imggal tabel. Vervolgens bewaart de db alle rijen waar "k.imageid=i.imageid AND k.galleryid = 7" en zet vervolgens bij de rijen waar deze conditie niet geldig is de waarden in de rij uit "imggal" op NULL.
Tenslotte doet het "where" statement de rest.
Eigenlijk best logisch, maar verdomt lastig om zelf uit te vinden.

Deze pagina vond ik wel handig:
http://www.devx.com/dbzone/Article/17403/0/page/4

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Nou, je uitleg klopt niet helemaal :)

Je kunt tabellen JOINen op meerdere statements, een soort WHERE maar dan in de join clausule. Ik zeg dus in je query je moet de twee tabellen koppelen op imageid, en je moet er voor zorgen dat k.galleryid gelijk is aan 7. Omdat het een LEFT OUTER join is retourneert de query sowieso alle rijen van images, in het WHERE statement zeg ik dat ik alleen rijen wil zien waar k.galleryid NULL is, dus allee rijen die niet aan de join criteria van k.galleryid = 7 voldoen.

Oops! Google Chrome could not find www.rijks%20museum.nl


Verwijderd

Topicstarter
Dat bedoelde ik zo ongeveer ook ([edit] nog even nagelezen, ik had het toch niet helemaal goed), alleen verwoorde ik het wat minder goed ;)

Maar toch altijd mooi om het even bevestigd te zien.

[ Voor 20% gewijzigd door Verwijderd op 05-07-2005 21:37 ]

Pagina: 1