Random nummer genereren dat nog niet bestaat in database

Status
Niet open voor verdere reacties.

Stinuz

Terugkerende gebruiker
Lid geworden
14 jun 2003
Berichten
1.245
Hey, titel zegt eigenlijk genoeg. Ik maak een webshop, en bij check-out wil ik graag een order-nummer genereren. Dit kan ik natuurlijk heel simpel doen met
Code:
rand();
maar hoe kan ik voordat dit nummer gebruikt wordt checken of het niet al bestaat in de MYSQL database? Want 2 keer hetzelfde nummer voor verschillende orders, dat kan natuurlijk niet ;)

Het gaat er als volgt uitzien:

PHP:
INSERT INTO bestelling (ordernummer, productnummer, naam,...)
VALUES (?????, $product[0], $pro_cart->naam,...)

Deze query wordt voor elk product uitgevoerd, dus bij 3 producten in de winkelwagen krijg je zoiets als dit:

Ordernummer-------Productnummer------Naam
345345345--------------------432--------------------Paperclip
345345345--------------------454--------------------Schoen
345345345--------------------546--------------------Robot

Zoals je ziet moeten meerdere entries dus gebruik maken van dit ordernummer, dus auto-increment kan ik niet gebruiken.
 
Laatst bewerkt:
Random nummers zijn nooit goed in order systemen, ik neem aan dat dit nummer ook gebruikt gaat worden als factuur nummer?
 
Van ordernummer kun je het beste een primaire key met auto_increment maken. Als je dan een bestelling toevoegt aan het systeem, zorgt mysql ervoor dat het een uniek nummer krijgt toegewezen. Dit is niet iets dat je in php moet opvangen.

Het argument dat je het niet zou kunnen gebruiken is onzin, dat wil alleen maar zeggen dat het data model niet klopt.
 
Van ordernummer kun je het beste een primaire key met auto_increment maken. Als je dan een bestelling toevoegt aan het systeem, zorgt mysql ervoor dat het een uniek nummer krijgt toegewezen. Dit is niet iets dat je in php moet opvangen.

Het argument dat je het niet zou kunnen gebruiken is onzin, dat wil alleen maar zeggen dat het data model niet klopt.

Geen bezwaar, maar dat is geen onzin.

sqlcw.jpg


Zoals je ziet worden er meerdere entries gemaakt met hetzelfde ordernummer, vervolgens kan ik alle ordernummers bekijken met SELECT DISTINCT, en als ik dan op een ordernummer klik, krijg ik netjes een lijstje te zien met alle items die bij de order horen.

Als ik auto-increment zou gebruiken, zou elke entry een ander nummer hebben, telkens eentje hoger dus

En ja Raymond, het wordt ook gebruikt als factuurnummer, heb je misschien een alternatief, aangezien dit een slecht idee is volgens jou?:thumb:
 
in de hierboven afgebeelde tabel mis je nog een generiek id dat de primaire key wordt, in je algemene order tabel (met dingen als een besteldatum) kun je de id zetten dat uiteindelijk je order nummer wordt.
 
Ben het toch met flitsflitsflits eens je database model klopt niet helemaal.

Bovendien is een factuur compleet statisch wanneer je nu bijvoorbeeld een product prijs aanpast worden alle oude facturen ook direct van prijs veranderd lijkt me ook niet de bedoeling

Dus wat krijg je dan voor een database model, let op basis opzetje om je in beetje in de richting te duwen.

factuur

id
datum
klant
adres
enzovoorts .... .

factuur_regel

id
factuur_id
omschrijving
prijs

Heb dit even snel bedacht, database model zou beter kunnen

En het is een slecht idee omdat factuur nummers opvolgend horen te wezen, als het namelijk niet zo is kun je alles weer veranderen van de belastingdienst
 
Eventjes wat de beste manier is terzijde (en de factuur verzin ik hopelijk nog wel wat op).

Ik heb mijn hele website al om het rand(); principe heen gebouwd dus ik denk dat ik dit gewoon aanhoud als order nummer, en maak daarnaast wel een aparte tabel voor een factuurnummer.

Dus mijn vraag nu is gewoon heel simpel, ik heb nu
Code:
$ordernummergenereren = rand();
Is het mogelijk er voor te zorgen dat dit nummer niet dubbel wordt aangemaakt, en dus altijd uniek is? Door hem op de een of andere manier eerst langs de database te laten lopen om te kijken of het nummer al bestaat, en zo ja, een ander nummer kiezen. :thumb:
 
Unique constraint erop gooien, proberen te inserten en de "duplicate key" errors afvangen en als je er eentje krijgt, opnieuw proberen.

Note: naarmate je meer rijen toevoegt gaat de insert time exponentieel toenemen tot het punt waarop je hele niet meer vooruit te branden is omdat hij een uur bezig is om een nummer te zoeken dat nog niet bestaat.

Dit is echt geen goeie manier om het aan te pakken en je kunt je programma beter verbeteren voordat het te laat is.
 
Wellicht de random waarde via de database laten regelen? MySQL: RAND()

Toch zijn er volgens mij genoeg argumenten al gegeven om een efficienter database-model te bedenken
 
Ook een unique constraint gaat niet werken omdat Stinuz hetzelfde ordernummer meerdere keren in de tabel zet. Dus dan zul je het moeten proberen door een query uit te voeren en vervolgens het resultaat tellen
PHP:
$result = mysql_query("select distinct(Ordernummer) from tabelnaam where Ordernummer=".$ordernummergenereren , $link);
if (mysql_num_rows($result) == 0) {
// stop! maak nieuw nummer
} else {
// doorgaan
}
 
Ow dat gaat dan idd ook fout :/

Dan moet je idd eerst opvragen en dan inserten. Dat vergroot de kans op collisions omdat er een gat zit tussen "is dit nummer er nog?" en "voeg nieuw nummer toe", als in dat gat nog een keer gevraagd wordt "is dit nummer er nog?" voordat het nummer ingevoegd is heb je 2 orders met hetzelfde ID.

Dit probleem bovenop alle andere, reeds bestaande problemen in deze oplossing.
 
Ook een unique constraint gaat niet werken omdat Stinuz hetzelfde ordernummer meerdere keren in de tabel zet. Dus dan zul je het moeten proberen door een query uit te voeren en vervolgens het resultaat tellen
PHP:
$result = mysql_query("select distinct(Ordernummer) from tabelnaam where Ordernummer=".$ordernummergenereren , $link);
if (mysql_num_rows($result) == 0) {
// stop! maak nieuw nummer
} else {
// doorgaan
}

Dit lijkt perfect te werken
PHP:
$ordernummergenereren = rand();
$checkunique = mysql_query("select distinct(Ordernummer) from bestelling where Ordernummer=".$ordernummergenereren);
if (mysql_num_rows($checkunique) == 0) {
/////// code uitvoeren \\\\\\\
}
else{
echo'<META HTTP-EQUIV="refresh" CONTENT="1">';
}
Bij het verversen van de pagina wordt namelijk een nieuw rand(); nummer gemaakt. Als ik ergens anders tegenaan loop zal ik toch de structuur wat om moeten gooien maar ik hoop dat dit gewoon werkt zo :thumb:
 
Laatst bewerkt:
Dat lijkt te werken. Naarmate je systeem groter wordt, gaat het echter steeds langer duren en gaat je pagina steeds langer flitsen van het continu refreshen.

Daarbij ben je op deze manier ook je $_POST gegevens kwijt want die worden door een meta refresh niet meegestuurd volgensmij.
 
Er is op die pagina nog geen sprake van POST gegevens, en de database zal nooit zo groot worden dat er echt vaak een nummer gekozen zal worden dat al bestaat.. die kans is sowieso al wel heeel erg klein. :thumb:
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan