Een goede vriend van mij heeft een kapsalon en heeft mij gevraagd of ik voor hem een simpele webapplicatie kan maken voor het maken/beheren van de knipafspraken tbv zijn klanten.
Hieronder wat uitleg over het DB-design:
In totaal heb ik 3 tabellen gemaakt.
Omdat er een many-to-many relatie bestaat tussen gebruikers en behandelingen heb ik hiervoor een aparte tabel gemaakt met orders zodat er one-to-many relatie bestaat.
Ik ben benieuwd naar wat jullie van het design vinden en/of jullie nog opmerkingen/aanmerkingen hebben.
Tabelstructuur voor tabel Behandelingen
Kolom Type Leeg Standaardwaarde
BehandelingID int(11) Nee
BehandelingNaam varchar(255) Nee
BehandelingPrijs decimal(10,2) Nee
Tabelstructuur voor tabel Orders
Kolom Type Leeg Standaardwaarde
OrderID int(11) Nee
GebruikerID int(11) Nee
BehandelingID int(11) Nee
DatumUitvoering datetime Nee
?Onbekende gebruiker
30-12-2020 21:10
Er zijn ook hosters die PostgreSQL aanbieden, je hebt keuze.
Hoofdlettergevoeligheid is gedoe, zoals wel meer dingen in MySQL..
Zie: https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html
Als je echt onderscheid wilt kunnen maken tussen een identifier als datumactief en DatumActief, moet je die laatste tussen backticks schrijven, zoals dit: `DatumActief`. Maar je kunt ook kiezen voor namen met kleine letters en een underscore, zoals dit: datum_actief. Die hoef je nooit tussen backticks te zetten. Hoewel je het kunt opvatten als een kwestie van smaak, raad ik het toch aan omdat het gedoe kan voorkomen.
Ik raad je aan om TEXT te gebruiken in plaats van VARCHAR en al helemaal boven CHAR.
Stel dat je zou zeggen dat kolom `Voornaam` van het type CHAR(20) is. Een kortere voornaam als Jan wordt opgeslagen als 'Jan ' (met 17 extra spaties). Je gooit dus ruimte weg. De enige reden om voor CHAR te kiezen is als de rijgrootte van een kolom een vaste lengte moet hebben voor het sneller kunnen opzoeken van data. Maar dat is hier niet van toepassing.
Zie: https://dev.mysql.com/doc/refman/8.0/en/char.html
VARCHAR is gedoe in MySQL. Neem bijvoorbeeld VARCHAR(255). Het slaat nergens meer op, maar het wordt veel gebruikt als voorbeeld. De 255 is niet (zoals je zou verwachten) het maximum aantal karakters, maar het maximum aantal bytes (in C "char"). Tegenwoordig gebruiken veel mensen UTF-8 (utf8mb4), maar dan kan een niet US-ASCII-karakter tot 6 bytes ruimte innemen. En alsof dat al niet ingewikkeld genoeg is om rekening mee te houden, heeft MySQL bedacht dat elke rij - zelfs met InnoDB - maximaal 65535 (64k - 1) bytes kan bevatten. Als je dus een bredere tabel hebt, met een paar kolommen met VARCHAR(32767), dan gaat MySQL tegensputteren.
Zie: https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html
De meest eenvoudige oplossing is om TEXT als kolomtype te gebruiken. Dan hoef je niet na te denken over extra bytes voor UTF-8, en je kunt eventueel eenvoudig opschalen naar MEDIUMTEXT of LONGTEXT. Als je dat zou willen kan je nog steeds een limiet op het aantal bytes zetten met een CHECK CONSTRAINT als LENGTH(`Voornaam`) <= 20. En de data van een kolom met het TEXT-datatype telt niet mee in de rijlimiet.
Simpeler kan MySQL het helaas niet maken, het is meer gedoe dan PostgreSQL. In PostgreSQL heb je geen limiet op rijen, in PostgreSQL maakt het niet uit of je VARCHAR of TEXT gebruikt, in PostgreSQL zijn aantallen in karakters in plaats van in bytes. In PostgreSQL ligt de focus op data, niet op technisch geneuzel. Vandaar mijn aanbeveling.
Als de prijzen afhangen van geslacht, dan heb je hiervoor een aparte kolom nodig in de prijstabel.
Maak niet de fout om ooit het datatype ENUM te gebruiken. In het geval van jouw kapper; er zijn ook LHBTI-mensen, of mensen waarvan het geslacht onbekend is, of die het überhaupt niet geregistreerd willen hebben. En dan komt de kapper weer bij jouw voor extra opties in de kolom geslacht. Gewoon altijd ENUM vermijden, dat werkt het beste.
Het meest puur is om een tabel geslacht aan te maken met een eigen id. Kan je die meteen extra kolommen geven als code en aanhef.
Vanuit de prijstabel maak je een kolom geslacht, met een FOREIGN KEY CONSTRAINT naar de tabel geslacht. In dezelfde prijstabel heb je ook een kolom nodig met een kolom product, met een FOREIGN KEY CONSTRAINT naar de producttabel.
Op de twee kolommen product en geslacht maak je een PRIMARY KEY constraint, je gebruikt hier geen AUTO_INCREMENT.
Je kunt eventueel de dubbele sleutel achterwege laten, en een extra id kolom maken waar wel een AUTO_INCREMENT op zit. Daarmee verschuift verantwoordelijkheid om data-integriteit te bewaken van de MySQL naar PHP. Sommige raamwerken kunnen slecht met dubbele sleutels overweg, dit kan een reden zijn om toch voor die id kolom te kiezen. Mijn aanbeveling is om alle data-gerelateerde taken zoveel mogelijk bij de database te beleggen, dus om wel te werken met een dubbele sleutel.
Of mannen of vrouwen geknipt worden zou ik in ieder geval zeker niet koppelen aan de klant.
Maak er gewoon een apart product van: Knippen heren, knippen vrouwen.
Voor hetzelfde geldt betaalt de man zelf de knipbeurt voor de vrouw.
Ik denk dat je daar een punt hebt. Ik ga denk ik twee aparte tabellen maken, gezien het twee aparte behandelingen zijn, dus eentje voor mannen en andere voor vrouwen met elk andere behandelingen erin.
Is het zo praktisch vraag ik mij af om twee aparte tabellen aan te maken, want ik wil dat juiste keuzemenu dus "behandelingen voor een man of een vrouw worden geladen vanuit DB" wanneer het geslacht wordt gekozen?
Twee tabellen, dus een voor mannen, en een voor vrouwen?
Nee, dat is niet bepaald netjes genormaliseerd. Je product (is overigens geen order) moet gewoon vertellen wat het is. Eventueel een veld of het een product is voor mannen, of voor vrouwen, of 'niet van toepassing' als je er nog wilt filteren.
Knippen heren - 15 euro - heren
Knippen vrouwen - 25 euro - vrouwen
Watergolven - 20 euro - vrouwen
Tondeuse heren - 10 euro - heren
Haarkleuren - 50 euro - niet van toepassing
Fles Hairlotion 0,33 l - 15 euro - niet van toepassing
Fantastic HairGel - 2,50 euro - niet van toepassing
Dat kan dus prima in een tabel.
En waarom ik in de records de geslachten in de titels plaats is heel simpel: Ook op het bonnetje wil je aan de klant laten zien welk product er gekozen is. Dan weet Annie bijvoorbeeld dat er gewoon 'Knippen vrouwen' is aangeslagen, wat meer vertrouwen geeft dan enkel 'Knippen' wat ook voor heren zou gelden.
Je kan ook de gelachts-velden bij de omschrijving betrekken, maar ik denk dat je het dan nodeloos complex maakt als je statistieken wilt uitdraaien. Feitelijk is er een groot verschil tussen knippen van dames en heren ;-)
?Onbekende gebruiker
31-12-2020 13:55
Mohamed nvt op 30/12/2020 22:58:54
Ik denk dat je daar een punt hebt. Ik ga denk ik twee aparte tabellen maken, gezien het twee aparte behandelingen zijn, dus eentje voor mannen en andere voor vrouwen met elk andere behandelingen erin.
Is het zo praktisch vraag ik mij af [..]
Ik heb een hele verhandeling uitgetypt, misschien heb je daar iets aan?
Twee tabellen, dus een voor mannen, en een voor vrouwen?
Nee, dat is niet bepaald netjes genormaliseerd. Je product (is overigens geen order) moet gewoon vertellen wat het is. Eventueel een veld of het een product is voor mannen, of voor vrouwen, of 'niet van toepassing' als je er nog wilt filteren.
Knippen heren - 15 euro - heren
Knippen vrouwen - 25 euro - vrouwen
Watergolven - 20 euro - vrouwen
Tondeuse heren - 10 euro - heren
Haarkleuren - 50 euro - niet van toepassing
Fles Hairlotion 0,33 l - 15 euro - niet van toepassing
Fantastic HairGel - 2,50 euro - niet van toepassing
Dat kan dus prima in een tabel.
En waarom ik in de records de geslachten in de titels plaats is heel simpel: Ook op het bonnetje wil je aan de klant laten zien welk product er gekozen is. Dan weet Annie bijvoorbeeld dat er gewoon 'Knippen vrouwen' is aangeslagen, wat meer vertrouwen geeft dan enkel 'Knippen' wat ook voor heren zou gelden.
Je kan ook de gelachts-velden bij de omschrijving betrekken, maar ik denk dat je het dan nodeloos complex maakt als je statistieken wilt uitdraaien. Feitelijk is er een groot verschil tussen knippen van dames en heren ;-)
Ik heb hier nogmaals naar gekeken en opzich vind ik het logisch om de behandeling, dus knippen voor mannen en vrouwen in een apart veld te benoemen. Dat is dan overzichtelijk wanneer de afspraak ingepland wordt.
Alleen de presentatie van deze behandelingen dmv dynamische dropdown-menu te laten zien, is dan niet compleet.
Want tegelijkertijd kan er één behandeling geselecteerd wordt en dat is volgens mij niet compleet. Want misschien wil een klant behalve knippen ook zijn baard doen, haren wassen...
Ik vraag mij af hoe ik dit kan doen als de dynamische dropdown-menu hiervoor niet geschikt is.
Bedankt voor je suggesties en dit zijn hele goeie hoor.
Als ik dan kijk naar het gebruikersvriendelijkheid aspect kan ik denk ik beter kiezen voor een checkbox optie ipv dat een gebruiker dmv Ctrl meerdere behandelingen kan kiezen.
Met een checkbox heb ik het volgende bedacht:
Vanuit het DB laad ik alle behandeling in een kolom of een eigen div en links ervan is er een checkbox zodat een behandelaar kan een betreffende behandeling kiezen. Volgens mij is dit nog gebruikersvriendelijk.
Als ik dan een stapje verder denk, denk ik dat het zou handiger zou zijn om het nog eenvoudiger te maken door enerzijds gebruiker te maken van categorieën. Hiermee bedoel ik dat wanneer een behandelaar kiest voor alle behandelingen voor mannen, dat alleen die voor mannen worden weergegeven en hetzelfde geldt voor vrouwen.
Een andere optie is wanneer de behandeling linken aan het geslacht.
Hiermee bedoel ik dat tijdens het boeken van een afspraak dat wanneer het geslacht wordt gekozen dat alleen behandelingen voor betreffend geslacht worden weergegeven.
Ik ben er nog niet over uit...
vwb behandelingen in een ziekenhuis is er uiteraard meer keuzes, maar die zullen waarschijnlijk hebben gecategoriseerd om het enigszins overzichtelijk te maken.
Ik denk dat een datalist geen optie voor mij is, maar ik zal er nog verder naar kijken.
[size=xsmall]Toevoeging op 01/01/2021 14:57:23:[/size]
Rob Doemaarwat op 31/12/2020 16:56:41
[quote="Adoptive Solution op 31/12/2020 15:31:49"]
Je kan een dropdown menu ook vullen met typen :
Dat kan tegenwoordig "een tikje eenvoudiger" met een datalist
[/quote]
Het autocomplete optie is zeker handig wanneer het recond al bestaat. Dus stel je voor dat een afspraak wordt gemaakt voor Pietje en dan hoe je niet telkens zijn naam in te vullen, maar dat je het kan selecteren na het invullen van een paar letters...
[size=xsmall]Toevoeging op 01/01/2021 14:58:57:[/size]
Ad Fundum op 31/12/2020 13:55:52
[quote="Mohamed nvt op 30/12/2020 22:58:54"]
Ik denk dat je daar een punt hebt. Ik ga denk ik twee aparte tabellen maken, gezien het twee aparte behandelingen zijn, dus eentje voor mannen en andere voor vrouwen met elk andere behandelingen erin.
Is het zo praktisch vraag ik mij af [..]
Ik heb een hele verhandeling uitgetypt, misschien heb je daar iets aan?
[/quote]
Nogmaals dank voor je reactie.
Ik ga nog een keer naar kijken en erover nadenken. Het eea hangt af van gebruikersvriendelijkheid..
Het autocomplete optie is zeker handig wanneer het recond al bestaat. Dus stel je voor dat een afspraak wordt gemaakt voor Pietje en dan hoe je niet telkens zijn naam in te vullen, maar dat je het kan selecteren na het invullen van een paar letters...
Meer praktisch lijkt het me ook omslachtig, tijdrovend, foutgevoelig en niet klantvriendelijk als bij de kassa of aan de balie steeds om persoonsgegevens en toestemming voor het verwerken van die persoonsgegevens moet vragen.
?Onbekende gebruiker
05-01-2021 08:01
Aan Ward; ontzettend goede reactie met oog voor privacywetgeving en handige link.
In mijn programma maak ik gebruik van dergelijke constructie, om mensen die zich vaker dan eens hebben aangemeld te herkennen. Dat herkennen is in mijn specifieke geval een gerechtvaardigd belang.
Maar je komt niet zomaar weg met een datalist vullen, er hoort vanalles bij: je moet mensen inderdaad om toestemming vragen, of ze op voorhand duidelijk maken dat hun gegevens worden bewaard en wat de rechten zijn (in termen van Nederlands recht), zoals recht van inzage. Maar je moet ook een redelijke bewaartermijn hanteren. En de opslag van gegevens moet voldoen aan veiligheidseisen zoals van NEN-IEC/ISO 27001 en 27002 en OWASP.
En dat alles moet overeind kunnen blijven staan wanneer een jurist er naar kijkt.