Klantentabel met verschillende eigenschappen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
Ik ben bezig met het maken van een universele webapplicatie waar meerdere partijen en account kunnen krijgen en zij daarin hun klanten kunnen beheren. Nu is het zo dat het ene bedrijf bijv. het sofinummer van zijn klanten wil kunnen invoeren en een andere partij wil bijv. de geboortedatum en het interne klantnummer kunnen invoeren.

Nu zat ik te denken hoe dit databasetechnisch gezien het beste kan. Ik dacht aan twee mogelijkheden:

- een tabel klanten met daarin de velden die iedereen altijd wil gebruiken (adres, plaats, telefoonnummer etc.)
- een tabel met eigenschappen die sommige klanten willen (sofinummer, intern klantnummer bijv.)
- een koppeltabel met daarin het eigenschaptype (bijv. sofinummer) en de waarde ervan, gekoppeld aan de betreffende klant
- een tabel waarin gedefinieerd is welke partij welk eigenschaptype wil kunnen invoeren

OF

- in de eerste tabel helemaal geen klantgegevens plaatsen, maar elke eigenschap variabel, zoals sofinummer etc.

of zijn er betere ideeen?

Kleine voetnoot, het liefst maak ik gebruik van ORM maar dat lijkt me in dit geval toch niet handig. Hoor het graag als iemand daar anders over denkt.

Acties:
  • 0 Henk 'm!

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 11-09 22:33
Waarom niet gewoon een tabel voor elke klant? Zal de ene klant namelijk leuk vinden als hij (per ongeluk) gegevens van anderen krijgt te zien 8)7.

Acties:
  • 0 Henk 'm!

  • -DarkShadow-
  • Registratie: December 2001
  • Niet online
Je bent een multi tenant applicatie aan het ontwikkelen en je zou naar EAV kunnen kijken.

Specialist in:
Soldeerstations
Oscilloscoop


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

alex3305 schreef op zondag 19 februari 2012 @ 11:42:
Waarom niet gewoon een tabel voor elke klant? Zal de ene klant namelijk leuk vinden als hij (per ongeluk) gegevens van anderen krijgt te zien 8)7.
Of leuker nog: key collisions omdat dezelfde persoon klant is bij zowel bedrijf A als bedrijf B. :+

'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.


Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
alex3305 schreef op zondag 19 februari 2012 @ 11:42:
Waarom niet gewoon een tabel voor elke klant? Zal de ene klant namelijk leuk vinden als hij (per ongeluk) gegevens van anderen krijgt te zien 8)7.
Dat is uiteraard gescheiden dmv een veld klant_id (met klant_id bedoel is dus mijn klant, en die klant heeft er weer allerlei van zijn contacten in staan).

Een aparte tabel voor elke klant lijkt me behoorlijk wat onderhoud opleveren (op het eerste gezicht) maar ik zal het eens uitzoeken.

[ Voor 10% gewijzigd door mrwiggs op 19-02-2012 12:12 ]


Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
-DarkShadow- schreef op zondag 19 februari 2012 @ 11:43:
Je bent een multi tenant applicatie aan het ontwikkelen en je zou naar EAV kunnen kijken.
Bedankt ga er even op Googlen.

Acties:
  • 0 Henk 'm!

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 11-09 22:33
Waarom levert dat extra onderhoud op? Je werkt gewoonweg met SQL queries die een tabel aanmaken bij een nieuwe klant met de juiste velden. Zou je zelfs helemaal variabel kunnen maken met een simpele webapp.

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Een database-in-a-database is denk ik niet echt een oplossing hier, in ieder geval niet het antwoord op de probleemstelling "mijn klanten moeten kunnen zoeken op verschillende velden" (zoals ik het lees, tenminste). Als het probleem inderdaad "het kunnen opslaan van onbekende velden" is, is een EAV wel een oplossing. Maar dan alleen voor de onbekende eigenschappen.
alex3305 schreef op zondag 19 februari 2012 @ 12:22:
SQL queries die een tabel aanmaken bij een nieuwe klant
Heerlijke oplossing , ja. ;)

[ Voor 71% gewijzigd door CodeCaster op 19-02-2012 12:47 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
CodeCaster schreef op zondag 19 februari 2012 @ 12:27:
Een database-in-a-database is denk ik niet echt een oplossing hier, in ieder geval niet het antwoord op de probleemstelling "mijn klanten moeten kunnen zoeken op verschillende velden" (zoals ik het lees, tenminste). Als het probleem inderdaad "het kunnen opslaan van onbekende velden" is, is een EAV wel een oplossing. Maar dan alleen voor de onbekende eigenschappen.
Ik heb nergens iets gezegd over zoeken, het ging over invoeren. De ene klant wil van zijn contacten de haarkleur kunnen invoeren en de schoenmaat (ik zeg maar wat). Ik heb even EAV nagekeken en dat ziet er inderdaad goed uit (is ook deels de mogelijke oplossing die ik schetste in het starttopic).

Ook lijkt me een aparte database per klant (van mij) ook een optie, maar daarin de velden die die klant wil gebruiken. Helemaal afmaken zou dan zijn dat ik een apart ORM model per tabel aanmaak zodat ik gemakkelijk met elke tabel kan communiceren. Toch ben ik echter wel bang dat het dan allemaal een zooitje wordt (stel ik heb 1000 klanten dan heb ik ook gelijk 1000 tabellen).

Bedankt voor het meedenken!

Edit: laatste idee wat ik nog had, eigen velden toevoegen in een veld "extra_fields" (TEXT) en dan JSON geëncodeerd opslaan. Maar erin zoeken wordt dan weer lastiger.

[ Voor 16% gewijzigd door mrwiggs op 19-02-2012 12:50 ]


Acties:
  • 0 Henk 'm!

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 11-09 22:33
Want dat is ook echt vergelijkbaar met wat ik aangaf :S.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Een tabel per klant lijkt aardig op dat voorbeeld, waarom een tabel per klant geen oplossing is moet je zelf maar even over nadenken...

Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
Cartman! schreef op zondag 19 februari 2012 @ 14:41:
Een tabel per klant lijkt aardig op dat voorbeeld, waarom een tabel per klant geen oplossing is moet je zelf maar even over nadenken...
Geen oplossing omdat het niet schaalbaar is? Of zijn er meer argumenten?

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Ik heb nergens iets gezegd over zoeken, het ging over invoeren.
Excuus, ik las verkeerd.

Over de tabellen per klant: het verschil tussen een tabel voor de ene en de andere klant is misschien één of wellicht zelfs géén kolommen. Waarom zou je dan een andere tabel bouwen?

Je komt verder gewoon in de knoop met je relaties. Je kunt geen koppeling leggen op Klant.ID omdat de tabel bij wijze van spreken Klant42 heet, je zult daarom een hoop kunst- en vliegwerk moeten vertonen om het geheel werkend te krijgen (strong-typed views worden bijvoorbeeld lastig indien van toepassing, je ORM wordt lastiger te koppelen).

Een losse key-value-tabel (EAV, zoals gesuggereerd) lijkt me inderdaad de gemakkelijkste en meest degelijke oplossing: alle informatie die je klant-objecten delen met elkaar (id, naam, BSN, enzovoorts) sla je op in de Klant-tabel, en je tabel (give it a name) KlantEigenschappen heeft de velden KlantId, Name, Value, waarbij je ook weer heel gemakkelijk eigenschappen op Name kunt zoeken zonder te hoeven rommelen met CSV's, JSON of XML (bah, database-in-database).

[ Voor 8% gewijzigd door CodeCaster op 19-02-2012 15:45 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
CodeCaster schreef op zondag 19 februari 2012 @ 15:42:Je komt verder gewoon in de knoop met je relaties. Je kunt geen koppeling leggen op Klant.ID omdat de tabel bij wijze van spreken Klant42 heet, je zult daarom een hoop kunst- en vliegwerk moeten vertonen om het geheel werkend te krijgen (strong-typed views worden bijvoorbeeld lastig indien van toepassing, je ORM wordt lastiger te koppelen).
Ik had mezelf al bijna overtuigd dat een aparte tabel per klant in het begin nog de beste oplossing is. Maar je hebt gelijk wat betreft relaties en dubbele id's, dat wordt echt gekkenwerk.
Een losse key-value-tabel (EAV, zoals gesuggereerd) lijkt me inderdaad de gemakkelijkste en meest degelijke oplossing: alle informatie die je klant-objecten delen met elkaar (id, naam, BSN, enzovoorts) sla je op in de Klant-tabel, en je tabel (give it a name) KlantEigenschappen heeft de velden KlantId, Name, Value, waarbij je ook weer heel gemakkelijk eigenschappen op Name kunt zoeken zonder te hoeven rommelen met CSV's, JSON of XML (bah, database-in-database).
Dat lijkt me dan inderdaad ook de beste oplossing, en mocht niemand meer met een genialere oplossing komen ga ik voor deze oplossing.

Acties:
  • 0 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 00:41

The Eagle

I wear my sunglasses at night

Wat voor DBMS gebruik je, en hoe lang mag het duren voordat een klantomgeving klaar is voor gebruik? Met name die laatste is interessant, omdat dat de overweging kan uitmaken tussen het gebruiken van losse DB instances of schema's etc per klant of het gebruik van EAV achtige oplossingen.

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


Acties:
  • 0 Henk 'm!

  • SPee
  • Registratie: Oktober 2001
  • Laatst online: 11-09 15:48
- een tabel klanten met daarin de velden die iedereen altijd wil gebruiken (adres, plaats, telefoonnummer etc.)
- een tabel met eigenschappen die sommige klanten willen (sofinummer, intern klantnummer bijv.)
- een koppeltabel met daarin het eigenschaptype (bijv. sofinummer) en de waarde ervan, gekoppeld aan de betreffende klant
- een tabel waarin gedefinieerd is welke partij welk eigenschaptype wil kunnen invoeren
Zoals hierboven gezegd, krijg je dan een database-in-database. Misschien is het handig als je de links leest, maar mijn ervaring: niet doen!
  1. De waarde tabel wordt gigantisch groot, omdat je maar 1 waarde per regel invoert
  2. Zoeken gaat langzaam
  3. Je hebt 3 queries (of joins) nodig om 1 waarde te krijgen
  4. Het is (bijna) niet te controleren welke waardes zijn ingevuld of niet
En nog wel meer nadelen op te noemen.

Ga dan eerder voor een extra veld met XML of JSON data.
  1. Er zijn veel libraries voor beschikbaar
  2. Ondersteuning voor databases groeit
  3. Je kan de inhoud zelf definieren
Of je limiteert de keuze van je klanten tot een bepaald aantal velden, die jij bepaalt.
Deze kun je dan specifiek maken en/of door de klant zelf in te laten stellen. En dan de vraag of ze het gebruiken ja of nee.
b.v.:
tabel KLANTVELD:
  • bsn
  • extreference
  • optioneel1
  • ...
  • optioneel255

let the past be the past.


Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
The Eagle schreef op zondag 19 februari 2012 @ 17:05:
Wat voor DBMS gebruik je, en hoe lang mag het duren voordat een klantomgeving klaar is voor gebruik? Met name die laatste is interessant, omdat dat de overweging kan uitmaken tussen het gebruiken van losse DB instances of schema's etc per klant of het gebruik van EAV achtige oplossingen.
MySQL. Omgeving opzetten hoeft niet realtime, kan best enkele dagen duren en mag ook best eventjes wat tijd kosten aan onze kant.

Losse DB's zou wel het flexibelst en qua programmeren wel het makkelijkst zijn, maar lijkt me een hel in onderhoud.

@Spee
het zal niet om zo denderend veel records gaan dat die tabel gigantisch groot wordt. Dat het een stuk lastiger te programmeren is ben ik me inderdaad van bewust.

Echter, werken met een JSON encoded string in een databaseveld lijkt me echt niet fijn, voor zover ik weet kan MySQL daar zelf niet direct mee overweg en dat is voor mij al een reden het niet te gebruiken.

Je laatste optie druist toch wel tegen mijn normalisatieprincipes in, maar bij nader inzien lijkt het toch wel een goede oplossing. Heel veel verschillende velden zullen er niet komen en bepaalde kolommen zijn natuurlijk onzichtbaar te maken voor bepaalde klanten. Tevens werkt het natuurlijk het makkelijkst met 1 tabel qua zoeken, invoeren, updaten etc.

Wat zijn er toch veel mogelijkheden en veel meningen 8)7

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
iPhone-post dus kort: het valt me nog mee dat NoSQL nog niet gevallen is; ook dat is niet de Holy grail maar zeker eens het bekijken waard.

[ Voor 4% gewijzigd door RobIII op 19-02-2012 19:17 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

SPee schreef op zondag 19 februari 2012 @ 17:13:
[...]


Zoals hierboven gezegd, krijg je dan een database-in-database. Misschien is het handig als je de links leest, maar mijn ervaring: niet doen!
• De waarde tabel wordt gigantisch groot, omdat je maar 1 waarde per regel invoert
Maakt met de juiste indexes niets uit.
• Zoeken gaat langzaam
Maakt met de juiste indexes niets uit. Ook kun je een koppeltabel opnemen waar je de namen van waarden aan een ID hangt, en dan dat ID samen met de waarde koppelt aan een klantId. Dan hoeft alleen het ID in de koppeltabel opgezocht te worden op de naam van de waarde, wat weer sneller is dan een string zoeken in de waardennaam-kolom.

[quote]
• Je hebt 3 queries (of joins) nodig om 1 waarde te krijgen

Wat is er mis met joins?
• Het is (bijna) niet te controleren welke waardes zijn ingevuld of niet
Waarom niet? Kwestie van de juiste joins gebruiken.
Ga dan eerder voor een extra veld met XML of JSON data.
  1. Er zijn veel libraries voor beschikbaar
  2. Ondersteuning voor databases groeit
  3. Je kan de inhoud zelf definieren
En het is langzaam, want iedere regel moet gelezen worden om de data die erin staat op te halen.
Of je limiteert de keuze van je klanten tot een bepaald aantal velden, die jij bepaalt.
Deze kun je dan specifiek maken en/of door de klant zelf in te laten stellen. En dan de vraag of ze het gebruiken ja of nee.
b.v.:
tabel KLANTVELD:
  • bsn
  • extreference
  • optioneel1
  • ...
  • optioneel255
En dan per klant weer een tabel bijhouden om aan te geven wat voor data er in die kolommen staat? Of de weer te geven naam in het invoerscherm? Of ga je daar de magische regel met ID 0 voor gebruiken?

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • mrwiggs
  • Registratie: December 2004
  • Laatst online: 08:17
Bedankt voor alle reacties, ik denk dat ik eruit ben. Nog even een korte omschrijving, ik heb dus enkele klanten en die verenigingen hebben elk weer een hoop leden. Er komt 1 tabel leden met alle mogelijke eigenschappen als los veld, elke row gekoppeld aan een bepaalde klant_id. Ik denk deze tabel echt maximaal zo'n 50 velden zal hebben. Verder heb ik een tabel velden waarin de velden (en de volgorde ervan) staan die in de tabel klanten staan en een koppeltabel klanten_velden waarin staat welke klant welke velden wil zien.

Verder staan alle velden met validatieregels en labelnaam etc. in mijn ORM model, waarin in de benodigde velden dynamisch toewijs. Ofwel hij haalt de benodigde velden voor die specifieke klant uit de database en zorgt dat het model alleen die velden bevat. Hiermee kan ik dan gelijk de juiste formulieren mee genereren, validaties doen en gemakkelijk invoeren en updaten, allemaal via het model.

Mooie oplossing lijkt me zo, erg makkelijk in gebruik. Schaalbaar nog niet helemaal, maar als het zover is dat er meer dan 50 specifieke velden nodig zijn, zal er enig budget zijn om wat externe hulp in te schakelen.

[ Voor 21% gewijzigd door mrwiggs op 20-02-2012 00:42 ]


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
RobIII schreef op zondag 19 februari 2012 @ 19:16:
iPhone-post dus kort: het valt me nog mee dat NoSQL nog niet gevallen is; ook dat is niet de Holy grail maar zeker eens het bekijken waard.
Dit, ik zat te denken aan MongoDb, werkt met BSON (binary json) waarin je dan ook kan zoeken en je hebt geen tables verder dus je kan de properties per user gewoon laten verschillen.

Acties:
  • 0 Henk 'm!

  • Gé Brander
  • Registratie: September 2001
  • Laatst online: 06-09 09:32

Gé Brander

MS SQL Server

1 tabel met algemene contact gegevens voor klanten, leden en alle andere soorten contacten en die gekoppeld middels joins aan specifieke klantgegevens tabellen, ledengegevens tabellen etc. Dan kan je later altijd nog een nieuwe categorie toevoegen door een extra gegevens tabel aan te maken voor die specifieke groep.

Het voordeel van die extra gegevens tabellen is dat je specifieke gegevens voor bijvoobeeld leden, in een tabel hebt en specifieke gegevens voor klanten ook etc.

De contacten tabel is universeel.

Vroeger was alles beter... Geniet dan maar van vandaag, morgen is alles nog slechter!


Acties:
  • 0 Henk 'm!

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

Ik ben zelf altijd geneigd om in dit soort databases bvb een Persoon tabel aan te maken, die heel basic is, en vervolgens specialisaties heeft in ContactPersoon en joins naar de Adres tabel. Ik zie zo vaak databases waarbij een tabel vol met klanten drie adressen bevat en allerlei hele specifieke gegevens die in een ander proces weer totaal niet nodig zijn (mensen die alleen de nieuwsbrief krijgen bijvoorbeeld). Dus staat óf zo'n tabel vol met NULLable of lege velden, of er wordt weer ergens anders een tabelletje opgetuigd weer met voornaam achternaam email en alle andere standaard dingen. Daar moet weer code voor geschreven worden volgens, die natuurlijk niemand weer onderhoudt.

Dus je zou kunnen zeggen Persoon 1:0..1 Lid 1:0..1 VoetbalclubDeHeiskuppersLid

Zo kun je ook heel makkelijk generieke functionaliteit bouwen voor het tonen van een Lid of Persoon, en hoef je al die code niet dubbel te onderhouden. Nadeel is soms performance, en dat je vaker moet gaan refactoren (bijvoorbeeld een VoetbalclubLid er tussen zetten voor alle voetbalclubs gelijk)

En zo kijk je dan ook naar Adres als een losse entiteit ipv onderdeel van een Lid. Een club kan een of meerdere adressen hebben, een Persoon kan dat hebben, een Leverancier kan dat hebben. En dan schrijf je gewoon maar één keer een Adres control, en één keer alle validaties en dergelijke en dat doe je dan gewoon heel goed want het hoeft maar één keer.

[ Voor 14% gewijzigd door BikkelZ op 20-02-2012 10:32 ]

iOS developer


Acties:
  • 0 Henk 'm!

  • EricBruggema
  • Registratie: Maart 2007
  • Laatst online: 23-08 11:22
Ik gebruik zelf ook vaak voor sites het EAV model, domweg omdat ik zo ruimte bespaar en deze gegevens in veel van de gevallen niet direct nodig heb!

Zelf zou ik gaan voor een klant tabel en een klantExtra tabel voor de extra gegevens waarbij ik in klantExtra alleen 4 velden beschikbaar stel (klantid, datum/tijd, naam, gegeven). Zo kun je simpel en snel alle gegevens bij je klant zoeken en zoeken naar klanten met bepaalde gegevens zal ook rap gaan!

Dus EAV all the way! :)

Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10-09 18:14

alienfruit

the alien you never expected

Ik maakte hiervoor altijd gewoon een database per klant...
Pagina: 1