Topic: Mažiausio id radimas

Sveiki, kurį laiką suku galvą kaip rasti mažiausią neegzistuojantį skaičių stulpelyje.

Tarkime turiu stulpelį su tokiais skaičiais:

id

1
2
3
7
9
11
20

Tad man reikia rasti šiuo atveju skaičių 4, kad vėliau galėčiau įkelti naujus duomenis su šiuo id. Iš bėdos tai gali būti ir ne pats mažiausias skaičius, svarbu, kad jo nebūtų toje lentelėje.
Kokiu būdu geriausia tai padaryti ?

Re: Mažiausio id radimas

aaarnas wrote:

Sveiki, kurį laiką suku galvą kaip rasti mažiausią neegzistuojantį skaičių stulpelyje.

Tarkime turiu stulpelį su tokiais skaičiais:

id

1
2
3
7
9
11
20

Tad man reikia rasti šiuo atveju skaičių 4, kad vėliau galėčiau įkelti naujus duomenis su šiuo id. Iš bėdos tai gali būti ir ne pats mažiausias skaičius, svarbu, kad jo nebūtų toje lentelėje.
Kokiu būdu geriausia tai padaryti ?

į klausimus šiandien neatsakinėsiu.
Kodas:

<?php

$array = array("1", "2", "3", "7", "9", "11", "20"); //pagrindinis masyvas
$array2 = array(); //kuriame naują masyvą
$count = count($array) + 1; //skaičiuojame reikšmes ir išmetame nulį.
for ($i=1; $i<$count; $i++) {
$array2[] .= ( $i ); // viso elementu. (id);
}
$result = array_diff($array2, $array); //lyginame..
print_r ($result); //visas masyvas su neegzistuojančiais
$current = current($result); //pirmas mažiausias
echo $current; //isvedame pirmą mažiausią..
?>

Re: Mažiausio id radimas

Tai taip išeina, kad neištraukus visų duomenų iš duombazės, rasti ko reikia nepavyks. Na dėkui už pagalbą, persidarysiu kiek kitaip.

Re: Mažiausio id radimas

Kaip tu gali rasti kazka jei nezinai kas jau yra?

Kitas klausimas butu ar tau tikrai reikia ieskoti maziausio neegzistuojancio id? Negi pritrukai vietos irasu id?

P.S. masyvo skaitymui naudociau foreach (jis greitesnis uz for)

5 (edited by aaarnas 2011-05-29 09:27:42)

Re: Mažiausio id radimas

Esmė tokia:

1. žmogus suformatuoja savo duomenis ir spaudžia pirkti.
2. Ištrinami seni, nepanaudoti įrašai.
3. įrašomi žmogaus duomenys į duombazę.
4. Jam į ekraną išvedami duomenys apie apmokėjimo žinutę, kurioje yra kodas, pagal kurį atpažįstami jo duomenys duombazėje.

Išsiunčiama žinutė:

1. Sms servisas į php serverį atsiunčia žinutę.
2. Gaunamas žmogaus įrašytas kodas.
3. Pagal kodą surandami jo duomenys ir suteikiamos paslaugos.

Siekiu, kad žinutės tekstas būtų kuo paprastesnis ir trumpesnis.

Re: Mažiausio id radimas

O kas bus jei as tarkim po gero menesio ivesiu gauta koda, kuris jau bus priskirtas naujam pirkejui?

Re: Mažiausio id radimas

Apskritai ta žinutė siunčiama iš karto kai parodoma informacija žmogui. Po gero mėnesio jei nori pirkti vėl ateini, suformatuoji duomenis ir perki. Bus parašyta, kad išsiųsti galima per savaitę.

Ten labai dažnai spaudinėjama, tad kam man laikyti įrašus, kurie nebus panaudoti ?

8 (edited by qutwala 2011-05-29 13:13:55)

Re: Mažiausio id radimas

Neodan wrote:

Kaip tu gali rasti kazka jei nezinai kas jau yra?

Kitas klausimas butu ar tau tikrai reikia ieskoti maziausio neegzistuojancio id? Negi pritrukai vietos irasu id?

P.S. masyvo skaitymui naudociau foreach (jis greitesnis uz for)

Turėsiu minty kitą kartą, dėkui. :)

aaarnas wrote:

Apskritai ta žinutė siunčiama iš karto kai parodoma informacija žmogui. Po gero mėnesio jei nori pirkti vėl ateini, suformatuoji duomenis ir perki. Bus parašyta, kad išsiųsti galima per savaitę.

Ten labai dažnai spaudinėjama, tad kam man laikyti įrašus, kurie nebus panaudoti ?

Pagal operacijų greitį:

1) operacija1: delete/insert
2) operacija2: update

Tai manau, kad greitesnis būtų antras variantas..
Tiesiog prieš perkant kažką informuok, kad prieš tai neatliktos operacijos užsisakinėjant naują bus pašalinamos.. Tokiu atveju manau dėl patogumo turėtum sukurti "šablonų" skyrių kur vartotojas galėtų kaupti kažkokius tai užsakymų šablonus ir galėtų juos esant reikalui patvirtinti, kaip galiojančius užsakymus. Tokiu principu išvengtum daug iki galo neįvykdytų užsakymų, vartotojas būtų suinteresuotas pabaigti vieną užsakymą norėdamas pradėti kitą.

Mano nuomone, koją kiša čia tau ta "sms sistema", kai visi gali be jokios atsakomybės ribojimo prispaudyti ko tik nori, o tu sms'us siunti, nuostolius patiri ir jokios naudos.
Tokiu atveju reiktų sistemą pergalvoti arba bent jau įdėti kokią capthą, kad asmeniui tiesiog nebūtų jokio noro spaudinėti ar bent jau šį sumažinti... :)

Re: Mažiausio id radimas

Matai, ten ne web, o aplikacija (tiksliau žaidimo serveris), tad dėl to spaudinėjimo nėra problemos.

Labai gera mintis. Kaip tik yra registruojami visi prisijungiantys vartotojai, dėl to, kitoje lentelėje kiekvienas turi savo unikalų id, tad kiekvienas galės turėti tik 1 savo užsakymą. Dėkui, taip ir padarysiu :)

Re: Mažiausio id radimas

jei tavo duomenys pasensta po savaitės, tai ne lengviau pvz po 3 tiesiog ištrinti visą bloką ir jį vėliau naudoti iš naujo.
O tarp 5249 ir 99799 žmogui nėra didelio skirtumo, tačiau tu jau turi 100k galimų variantų.

Jei dar panaudosi ir raides pvz AB-358 ar ABX - 369 (juk valstybinį numerį žmonės lengvai atsimena) turėsi ~26^3*10*10*9 =15 818 400 variantų. Kai per dieną parduodant po 10 000, tau jų užteks bent 4 metams. Tačiau jei pardavinėsi po 10 000 vnt per dieną, ir bandysi ieškoti mažiausio neegzistuojančio ID, serveris tikrai tau nepadėkos.

11 (edited by aaarnas 2011-05-29 16:11:51)

Re: Mažiausio id radimas

Lukas wrote:

jei tavo duomenys pasensta po savaitės, tai ne lengviau pvz po 3 tiesiog ištrinti visą bloką ir jį vėliau naudoti iš naujo.
O tarp 5249 ir 99799 žmogui nėra didelio skirtumo, tačiau tu jau turi 100k galimų variantų.

Jei dar panaudosi ir raides pvz AB-358 ar ABX - 369 (juk valstybinį numerį žmonės lengvai atsimena) turėsi ~26^3*10*10*9 =15 818 400 variantų. Kai per dieną parduodant po 10 000, tau jų užteks bent 4 metams. Tačiau jei pardavinėsi po 10 000 vnt per dieną, ir bandysi ieškoti mažiausio neegzistuojančio ID, serveris tikrai tau nepadėkos.

Jei trinsi visą bloką, tai gali papulti, kad žmogus ir negaus pirktų paslaugų, nebent naktį pratrinti, tada galima.

Tas mažiausio id ieškojimas tikrai labai prastas variantas, jau pasidariau su qutwala variantu, viskas labai gražiai pritiko.

Taip, kodinė identifikaciją irgi neblogas variantas, buvo antra sąraše :]

Re: Mažiausio id radimas

aaarnas wrote:

Jei trinsi visą bloką, tai gali papulti, kad žmogus ir negaus pirktų paslaugų, nebent naktį pratrinti, tada galima.

Jei bloką trini po mėnesio ar metų, tie kodai jau senai bus nebeaktualūs.

13 (edited by minde 2011-05-29 17:58:52)

Re: Mažiausio id radimas

Skaičiau tik pirmus pranešimus todėl tik parašysiu, kaip MySQL'e gauti mažiausią neegzistuojantį ID: tarkime turime lentele_1, kurioje yra kažkoks auto_increment ID, kur trinami įrašai. Reikia sukurti papildomą lentelę (tarkim lentele_2), kurioje bus vienas stulpelis ID, į kurį rašysime visus ID atsirandančius lentelėje_1. Antroje lentelėje jokių įrašų niekada netriname. Tokiu atveju visada antroje lentelėje turėsime iš eilės einančių skaičių seką, kur didžiausias ID bus toks pats kaip ir teorinis didžiausias ID iš pirmos lentelės. Norėdami gauti mažiausią neegzistuojantį ID iš pirmos lentelės mes turime sujungti abi lenteles JEFT_JOIN pagalba, atfiltruoti tuos įrašus, kurių nėr pirmoje lentelėje (NULL) ir a) surikiavus didėjimo tvarka pasilikti vieną įrašą (LIMIT 1) arba b) iš rezultaų išrinkti minimalų ID (MIN funkcija).

Pvz.:

SELECT lentele_2.id
FROM lentele_2
     LEFT JOIN lentele_1 ON id
WHERE lentele_1.id IS NULL
ORDER BY lentele_2.id ASC
LIMIT 1

Re: Mažiausio id radimas

Va šito ir reikėjo, bet pasiliksiu prie ano varianto, nes jis tinkamesnis :)

Re: Mažiausio id radimas

aaarnas wrote:

Va šito ir reikėjo, bet pasiliksiu prie ano varianto, nes jis tinkamesnis :)

Prie kurio varianto likai? Jeigu su PHP masyvais tai nekokia mintis. Aplamai, geriausia, kaip sakė kažkas unikalius ID ir palikti unikaliais, nes ne visada suvokdamas ką tiksliai gamini gali gauti labai netikėtų rezultatų overwritindamas senus ID.

16 (edited by aaarnas 2011-05-29 22:47:13)

Re: Mažiausio id radimas

Pasinaudojau qutwala pasiūlymu.
Kadangi visi vartotojai registruojami, tai kiekvienas turi savo unikalų id.
Tad orders lentelėje saugau visus užsakymus pagal vartotojo id.
Per naują užsakymą updatinu senąjį įrašą.
Jei orders lentelėje nėra jokių to vartotojo įrašu, tai afected_rows gražina 0 ir su insert įterpiu naują įrašą (jis po to visą laiką lieka, nebent vartotojas pats ištrins šį įrašą). čia kaip krepšėlis tik su 1 pirkimu vienu metu.

O žinutėje rašomas to vartotojo id, pagal ką viskas tvarkoma toliau.