[SQL] bitselectie enum/set->algoritme *

Pagina: 1
Acties:

  • it0
  • Registratie: April 2000
  • Laatst online: 27-12-2025

it0

Mijn mening is een feit.

Topicstarter
Misschien een beetje raar geformuleerd, maar ik weet eigenlijk niet hoe ik naar mijn vraag moet zoeken. Ik heb het vermoeden dat dit namelijk eerder voorbij is gekomen.

Stel je hebt 3 namen
1 Jan
2 Piet
4 Kees

Dan wil je bv
Alleen de records zien van jan
select * from user where name=1
Alleen de records van Jan en Kees
select * from user where name=5

Kortom netzoals bij bitmasks zoals je netmask. Maar mijn vraag is hoe doe je dit elegant?

Ik heb geen zin om X kolommen te maken en dan AND/OR clausules te bouwen want dat vind ik lelijk en inefficient.

Ik heb een vermoeden dat het kan met het dataype enum of set, maar als ik de enum docs lees kan ik het ook fout hebben.

Hmm ik heb weer te snel gepost, volgens mij kan ik het oplossen met het SET datatype

[ Voor 10% gewijzigd door it0 op 10-02-2004 20:15 ]


  • chem
  • Registratie: Oktober 2000
  • Laatst online: 21-05 08:48

chem

Reist de wereld rond

En wat dacht je van...
SQL:
1
select * from user where name in ('jan','kees');
:?

Klaar voor een nieuwe uitdaging.


  • it0
  • Registratie: April 2000
  • Laatst online: 27-12-2025

it0

Mijn mening is een feit.

Topicstarter
chem schreef op 10 februari 2004 @ 20:16:
En wat dacht je van...
SQL:
1
select * from user where name in ('jan','kees');
:?
Ik wist niet dat dit kon, maar volgens wil ik het inverse.

Dus ik wil in 1 record/kolom , een aantal namen geven en dan deze recrods selecteren als de naam er in voor komt.

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
* P_de_B heeft het vermoeden dat er niet goed genormaliseerd is hier


Kun je iets duidelijker zijn met wat je precies wilt?

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


  • chem
  • Registratie: Oktober 2000
  • Laatst online: 21-05 08:48

chem

Reist de wereld rond

Nu kom ik er ook niet meer uit.

Klaar voor een nieuwe uitdaging.


  • vinnux
  • Registratie: Maart 2001
  • Niet online
Hij bedoelt dat het id bitwise is
1 Jan = 001
2 Piet = 010
4 Kees = 100

Je kunt binnen SQL server bitwise operatoren gebruiken.
Dus Alleen de records zien van jan
select * from user where id & 1 = id
Alleen de records van Jan en Kees
select * from user where id & 5 = id

Echter ontgaat mij het nut in dit specifieke geval.
Ooit heb ik hetzelf wel eens gebruikt omdat een bepaalde gebruiker 32 rechten had en ik op een ontzettende snelle manier wilde checken of iemand wel beschikte over een bepaald recht. Kan soms wel 90% je query sneller maken :D

[ Voor 93% gewijzigd door vinnux op 10-02-2004 20:35 ]


  • it0
  • Registratie: April 2000
  • Laatst online: 27-12-2025

it0

Mijn mening is een feit.

Topicstarter
Dit is inderdaad wat ik bedoel, ik ben een simpel fotodagboek aan het maken voor mijn vrouw en de feature die zij wil is een nieuw dagboek in te voeren die over 1 of meer kinderen gaat. (ik heb er 2 en er komt een derde aan).

Dus ik zocht een elegant manier om combinaties van kinderen op te slaan en te selecteren.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 24-05 09:13

Janoz

Moderator Devschuur®

!litemod

Het lijkt me veel handiger om dit op te lossen met een koppeltabel.

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


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Als ik het goed begrijp heb je X foto's en Y mensen, en iedere foto kan 0..* users bevatten, en iedere user kan op 0..* foto's staan.

Dan heb je idd geen goed genormaliseerde database :)

Je hebt hier een zogenaamde M-op-N relatie, aka many-to-many. Hiervoor heb je een koppeltabel nodig. Ongeveer:
code:
1
2
3
4
5
6
7
8
9
10
11
table Foto
  primary key FotoId
  [...meer foto info...]

table User
  primary key UserId
  [...meer user info...]

table UserInFoto
  foreign key UserId
  foreign key FotoId

En je zoekt vervolgens ongeveer deze SQL:
SQL:
1
2
3
4
select * from Foto 
join UserInFoto on UserInFoto.FotoId = Foto.FotoId
where UserInFoto.UserId =
    (select UserId from User where UserName = 'kees');

Ik ga er hierbij van uit dat je een unique constraint hebt op UserName, anders moet je 'in' gebruiken :)

Als je zonder subquery wil (MySQL vind dat niet zo lief geloof ik) kan het ook nog met een double join:
SQL:
1
2
3
4
select * from Foto 
join UserInFoto on UserInFoto.FotoId = Foto.FotoId
join User on UserInFoto.UserId = User.UserId
where UserName = 'kees';

Of op de klassieke minder nette manier:
SQL:
1
2
3
4
select * from Foto, UserInFoto, Foto
where UserInFoto.FotoId = Foto.FotoId
  and UserInFoto.UserId = User.UserId
  and UserName = 'kees';

Ik vermoed dat de eerste versie op een goede DB-server sneller zal zijn, en de laatste 2 zijn functioneel identiek.

[ Voor 52% gewijzigd door curry684 op 11-02-2004 12:04 ]

Professionele website nodig?


  • it0
  • Registratie: April 2000
  • Laatst online: 27-12-2025

it0

Mijn mening is een feit.

Topicstarter
Curry: ik heb je reply een stuk of 5x gelezen.

Als ik het goed begrijp als er een foto(1) is waar jan(1) en kees(2) op staan dan doe je
code:
1
2
insert into UserInFoto UserId,FotoId VALUES(1,1);
insert into UserInFoto UserId,FotoId VALUES(2,1);


Is de oplossing van vgouw dan niet eleganter en efficienter?
Jouw oplossing heeft als voordeel dat het schaalbaarder is.

Of zijn er meer verschillen die ik zou moeten zien?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

it0 schreef op 11 februari 2004 @ 14:08:
Curry: ik heb je reply een stuk of 5x gelezen.

Als ik het goed begrijp als er een foto(1) is waar jan(1) en kees(2) op staan dan doe je [...knip...]
Goed gelezen d:)b

Dit is standaard-DB-concept: je hebt 1..1 relaties, 1..* relaties en *..* relaties, en de laatste definieer je met een een koppeltabel.
Is de oplossing van vgouw dan niet eleganter en efficienter?
Jouw oplossing heeft als voordeel dat het schaalbaarder is.
Je geeft zelf al aan waarom ie absoluut niet eleganter kan zijn, en efficienter ga je ook op terugkomen.
Of zijn er meer verschillen die ik zou moeten zien?
Met een bitfield leg je het aantal categorieen programmatisch vrijwel vast (tenzij je de bitfields in een tabel zet, maar dan ben je niet meer sneller en nog steeds limited to 32). Met de correcte aanpak ben op een grotere tabel net zo snel (indexes = rap) en zit je niet in de shit als je op een dag het realistische besluit neemt dat je categorieen 'parkiet Sjaak', 'huis in Lutjebroek' en 'oude hek in de tuin' wil toevoegen aan je fotoalbum.

Voor het correct meten van de efficientie van een oplossing moet je ook het aantal uren dat je in de toekomst jankend je hoofd tegen een muur gaat bonken meetellen ;)

Professionele website nodig?


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 24-05 09:13

Janoz

Moderator Devschuur®

!litemod

De oplossing van vgouw negeert compleet dat we hier met een database te maken hebben. De structuur die Curry aangeeft is gewoon de standaard oplossing in dit soort gevallen.

Een bitvelt maakt het erg lastig om nog iemand doe te voegen en al helemaal om de gebruikerstabel ermee te joinen. Als je je indexen goed legt dan hoef je je over efficientie ook nauwelijks zorgen te maken.

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


  • vinnux
  • Registratie: Maart 2001
  • Niet online
Janoz schreef op 11 februari 2004 @ 14:29:
De oplossing van vgouw negeert compleet dat we hier met een database te maken hebben. De structuur die Curry aangeeft is gewoon de standaard oplossing in dit soort gevallen.
Inderdaad, maar performence technisch gezien is het wel de snelste oplossing als je maar een paar waardes hebt. Maar voordat je zo een oplossing gaat gebruiken moet je wel zeker weten dat je preformence probleen hebt en dat is alleen in uitzonderingsgevallen.

[ Voor 1% gewijzigd door curry684 op 11-02-2004 15:40 ]


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 24-05 09:13

Janoz

Moderator Devschuur®

!litemod

Zo'n performance probleem is in de praktijk vaak goedkoper op te lossen door de server wat te upgraden ;). Dat is iig een stuk goedkoper dan het werk wat er later aan moet worden besteed...

[ Voor 29% gewijzigd door Janoz op 11-02-2004 15:38 ]

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

Pagina: 1