[MySQL] auto_increment

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Marcellito1 20. 7. 2010 01:04

Zdravím,
mám menší problém, mám nejakú tabuľku v ktorej sú napríklad takéto hodnoty:
1
2
3
5
6
Ako ste si všimli, chýba tam 4, a tu je ten "problém" nedá sa to číslovanie nejako resetovať aby išlo od začiatku a novú vetu vložilo s hodnotou 4 a nie s hodnotou 7?
Marcellito1
Junior
Uživatelský avatar

Odeslat příspěvekod gandor 20. 7. 2010 02:19

1, mozes insertnut tak, ze primarny kluc tiez vyplnis.
2, Mozes updatnut tabulku tak, ze kazdemu klucu zmenis hodnotu o jedna menej a potom nastavis autoincrement spravne (pozor ale na radenie, v tomto pripade chces radit od najmensieho po najvecsie - nech sa updatne najskor ten zaznam, co ma najmensie ID - nech nemas pocas vykonavania dotazu duplicity)
3, mozes zmenit hodnotu autoincrementu na "4" ale ked vlozis este dalsi zaznam, tak ti vyvola chybu (lebo autoincrement bude vtedy akurat na hodnote "5", ktora uz v tabulke je)....
4, mozes prestat pouzivat autoincrement a zacat sa spoliehat napr. na maxint a podobne, ale tvoris si potom zbitocne problemi ked sa 2 uzivatelia budu snazit nieco zapisat v tom istom momente (preto to nedoporucujem)

PS. na zmenu autoincrementu sa pouziva prikaz ALTER TABLE [tabulka] AUTO_INCREMENT = [cislo];

PPS. na ten jeden chybajuci zaznam by som sa (na tvojom mieste) teda fakt vybodol... Mas nejaky realny dovod, preco potrebujes mat "zaznam po zazname"? Skus napisat dovod a ja ti poviem v com mas chybu a ako by sa to malo riesit normalne ;)
gandor
Mírně pokročilý

Odeslat příspěvekod Marcellito1 20. 7. 2010 09:53

Nazdar,
ďakujem za pomoc, ide o to, že mám nejakú tabuľku a pri prihlásení užívateľa sa do nej zapíše nová veta a tá obsahuje okrem iného aj nejaké jedinečné ID užívateľa, no a problémy sú dva, predpokladám, že za deň sa môže prihlásiť aj 1000 užívateľov (možno viac možno menej) takže si nemôžem dovoliť vytvárať stále nové vety (a keď predchádzajúcu zmažem tak aj tak to čísluje ďalej, trebárs sú tam záznamy "1" a "2", zmažem "2" ale vloží už záznam "3") a druhá vec je ako si správne spomenul, potrebujem fakt jedinečnú hodnotu a na nejaké max, min sa nemôžem spoliehať lebo sa môže stať, že dvaja vložia ten istý čas vetu s rovnakým číslom.

Mimochodom, v PHP som nováčik a robím takú dajme tomu školskú stránku, niečo ako diskusné fórum so špecifickými prvkami ... kamarát mi vraví, že ak chcem riešiť prihlásenie užívateľov mám vytvoriť pri novom užívateľovi novú session, rozumiem pojem session ešte v starej Foxke čo to znamená ale tu v MySQL je to u mňa Španielska dedina a on programuje v ASP.NET a SQL, takže neviem či takéto finty pozná MySQL a neviem si dobre predstaviť ako to môže fungovať, keď napríklad budem chcieť vidieť históriu kto bol a je online ...
Marcellito1
Junior
Uživatelský avatar

Odeslat příspěvekod hekrhy 20. 7. 2010 10:31

Sessions jsou záležitost PHP, ne MySQL.

Používat k identifikaci přihlášeného uživatele jeho číslo v databázi, to je naprostý nesmysl (co když někdo číslo podvrhne, dá si o jednovyšší - to pak bude přihlášen za jiného uživatele?).

Pokud už si chceš přihlašování řešit sám (a nevyužiješ sessions), vytvářej při přihlášení nějaký dostatečně dlouhý náhodný řetězec, který předej tomu přihlášenému uživateli např. jako cookie, aby se pomocí něj pak mohl identifikovat (a samozřejmě si ten řetězec ulož do databáze, společně s nějakou vazbou na uživatele, ukládej si tam i třeba datum poslední aktivity, aby přihlášení mohlo po nějaké době vypršet atd.)

Kdyžtak např. http://www.linuxsoft.cz/article.php?id_article=543 +další díly seriálu by mohly pomoct ;-)
hekrhy
Junior
Uživatelský avatar

Odeslat příspěvekod gandor 20. 7. 2010 13:28

Pouzi session.
Session pouzivas velmi jednoducho. Je to "superglobalna" premenna, presnejsie pole. A presne tak s nim narabas. Mas uzivatela jozo, ktory sa prave prihlasil, tak si definujes
Kód: Vybrat vše
$_SESSION['prihlaseny_uzivatel']='jozef';

K "zapnutiu" sessioniek (- ak ich chces akymkolvek sposobom na tejto stranke pouzit) ale potrebujes uplne na zaciatku v prvom subore (a pred tym nez vyspises cokolvek ine !POZOR NESMIES VYPISAT ANI ENTER ANI MEDZERU ANI NIC! das iba tento riadok
Kód: Vybrat vše
<?php session_start(); ?>

Vyhoda session je v tom, ze ked ich nastavis raz, tak ti ostanu aj po prejdeni na dalsiu stranku a budu existovat tak dlho, dokym nevypnes okno prehliadaca, alebo nebudes dlhu dobu neaktivny (zakladne nastavenie je minimalne 3 hodiny necinnosti k vymazaniu sessionky)...

Z toho vyplyva nasledujuce: na stranku das prihlasovaci formular. V nom bude policko pre meno a heslo. Po odoslani formulara sa pozries, ci dany riadok v databaze medzi uzivatelmi existuje. Ak ano, tak nastavis session (dalej sa o prihlasovanie nikdy viac nestaras). Ked potrebujes vediet, ci je uzivatel prihlaseny, zistis to cez tento riadok kodu
Kód: Vybrat vše
if (isset($_SESSION['prihlaseny_uzivatel'))
{
  //uzivatel JE prihlaseny
} else {
  // uzivatel prihlaseny NIEJE
}


PS. ak si si dobre vsimol, tak som nikde konkretne ID nepouzil, nezmienil ani nepotreboval. Nieje to nahoda.... Konkretne ID je pre teba bezpredmetne. Pokial ho ale potrebujes kvoli dalsim vezbam (niekde budes chciet vypisat ulicu alebo nieco podobne o uzivatelovi), tak si ju tiez mozes pripojit k sessionke...

PPS. Sessionky sa uchovavaju na strane serveru a preto su (relativne) bezpecne. Nemusis sa obavat, ze cokolvek v nich ulozene uvidi aj utocnik (jedine co sa prenasa je jednoznacny kluc uzivatela, nech sa vie spravne prepojit uzivatel/session, na to uz ale musi byt utocnik tak trochu macher aby sa zmocnil cudzej session), takze do session mozes kludne vkladat aj senzitivne data...

PPPS. ak z nejakeho nepochopitelneho dovodu by si sa rozhodol, ze tie ID-cka aj tak potrebujes porade (naozaj neodporucam, nevidim dovod, sam si dostatocne nevysvetlil k comu by to bolo dobre), tak sa aj toto da dosiahnut. Treba len zamknut tabulku na cas, dokym tie ID-cka poupratujes (zamknutie tabuliek -> lock tables). Zvysok k tomuto ak by ta to nahodou zaujimalo najdes v dokumentacii k mysql pomocou stricka google :)
gandor
Mírně pokročilý

Odeslat příspěvekod karlos00x 20. 7. 2010 15:51

no a v cem je spatne mit id = 15485620174 ?
Upgrade který má smysl: SSD. Zažijete svižný počítač.
karlos00x
Pokročilý

Odeslat příspěvekod Marcellito1 20. 7. 2010 19:54

Díky chalani, moc ste mi pomohli ...
Gandor ty si "pán" :) Ono keď človek nemá dostatočné vedomosti tak potom vymýšľa rôzne sprostosti ako ja. Ponímanie "session" som mal trochu pomýlené z predchádzajúcej praxi, ale to je teraz jedno. Hovoríš, že je to bezpečné tak to sa mi páči. Mimochodom, vytvoril som si nejakú funkciu na šifrovanie hesla, takže v tabuľke sú zašifrované hodnoty. Možno aj to robím zle, ktovie, ale predpokladám, že dostať sa fyzicky k stránkam php by bolo komplikovanejšie ako keby niekto čítal dáta (vlastne to by bolo tiež blbé :D).
Ešte jedna vec, pri registrácií pri užívateľovi budem vytvárať jedinečné ID (pretože všetko to bude koncipované hlavne na užívateľa a bude tam dosť dát naviazaných na neho), registrácia užívateľov samozrejme nebude taká častá ako to čo som "vymýšľaľ". Ale tak či tak, z praxe viem, že treba myslieť na všetko a preto to spravím asi tak a pýtam sa či to tak môže byť. Zamknem tabuľku, vložím do nej novú vetu a napokon ju odomknem. Toto dám do cyklu aby sa to vykonávalo napríklad po každej pol sekunde, ak by ten istý čas zapisoval do tabuľky niekto druhý. Mohlo by to tak byť?
hekrhy ja som to chcel kontrolovať na to jedinečné ID a na meno užívateľa, takže ten dobrák čo by chcel zvýšiť o jedno ID tak by musel vedieť aj meno užívateľa, samozrejme pripúšťam, že to nie je moc bezpečné a že je to konina ... díky za postreh
karlos00x už som upustil od toho ako teraz vidíš, ale vtedy by som ti odpovedal v tom zmysle, že sa snažím minimalizovať tabuľku teda zbytočne nepoužívať trebárs longint ale radšej smallint unsigned atď. a ten je ohraničený na 65000 a dáke drobné, v tomto minimalizovaní samozrejme chcem pokračovať ďalej, keďže čím menšia tabuľka tak predpokladám, že sa to odrazí celkovo aj na prístupe dát a bude to celé svižnejšie ... dúfam
Marcellito1
Junior
Uživatelský avatar

Odeslat příspěvekod hekrhy 20. 7. 2010 20:21

Do DB nikdy neukládej hesla, ani v zašifrované podobě...ukládej hashe, nejlíp nějak "zasolené", ať případný útočník, i když získá přístup k databázi, tak zjistí prd ;-)

Tu část s registrací a zapisováním do tabulky po půl sekundě jsem nějak nepochopil... :nenapadne

btw. tím, že bys místo Integeru použil něco menšího, bys ušetřil 2 bajty...to je absolutně nic. Mnohem víc zrychlíš databázi správným návrhem, indexy a dobře napsanými dotazy. Navíc existuje něco jako zákon schválnosti a těch 65536 kombinací bude jednou málo a předělávat pak kvůli toho tabulky a aplikaci...to za to nestojí ;-)
hekrhy
Junior
Uživatelský avatar

Odeslat příspěvekod gandor 20. 7. 2010 20:27

Marcelito:
Velkost tabuliek je sice rozumne optimalizovat, ale netreba ist do extremov. Pokial das na primarny kluc klasicky int, tak spravis lepsie ako tam davat nejaky smallint a pocase sa cudovat, ze preco to nejde. Uvedom si, ze pri 1 000 000 zaznamoch (a to v beznej aplikacii ich tolko mat asi nebudes) by si usetril kolko? 1MB pamete? Ako velmi sa vdaka 1MB v dnesnej dobe urychli system?
Este dodam, ze vecsina ludi (a myslim, ze rozumne) dokonca maju taku tendenciu "setrit" miestom, ze zaznami vobec nevymazavaju, len ich schovavaju (vytvoria si novy field v tabulke, ktory hovori len o tom, ci je zaznam zmazany alebo nie), lebo data (kludne zmazane omylom) su ovela cennejsie ako ta trocha mrhanej pamete (osobne tiez rad takto "mrham" volnym miestom)...

Co sa tyka kodovania hesla - ano, dokonca sa to v praxi priamo pouziva. Vecsinou si ale ludia nerobia vlastne algoritmy, ale pouziju uz existujuce hashovacie funkcie (v php (a som presvedceny ze aj v mysql) mozes pouzit sha1() pripadne starsie md5() pripadne inu hashovaciu funkciu) - len nezabudni dobre zasaltovat ;) .
Vytvarat si vlastnu moze aj nemusi byt najlepsi napad. Ono ludia, ktory sa tomu fakt venuju a su matematicky "bohovia" asi vymyslia nieco lepsie ako to, co sa podari tebe. U teba tym padom asi vznikne viac kolizii/lahsie sa bude dat heslo spetne rozsifrovat. Na druhej strane budes mat nieco svoje vlastne, co by pre utocnika znamenalo robit specialne desifrovanie "na mieru". Osobne by som ale aj tak viac doveroval matematikom. :)

K napadu zamikania - preco nepouzit autoincrement priamo z mysql? Ten si uz to zamikanie robi sam. Caste zamikanie tabulky tiez nieje celkom najlepsi napad, lebo vyrazne znizujes vykon (potom ta optimalizacia tabulky co si spominal hore nema ani za mak vyznam - tu sa tie casove straty prejavia ovela viac).
Popravde sa ale musim priznat, ze som nie celkom pochopil, k comu to zamikanie vobec potrebujes. Rad by som ta ale este upozornil na existenciu tranzakcii - v reali vecsinou ked chces locknut tabulku, tak v skutocnosti chces len pouzit transakciu (narychlo som nasiel nieco k transakciam napr. tu http://dev.mysql.com/doc/refman/5.0/en/commit.html). Pomocou nich vies viac prikazov spustit "ako jeden".
Pozor si ale treba dat, ze MySQL podporuje transakcie (z beznych) len s enginom InnoDB. Takze treba na tento nastavit (mozno pouzivas engine MyIsam, ktory transakcie nepodporuje).
Nebudem sa rozpisovat v rozdieloch medzi tymito enginmi (vsak na ne si sa ani nepytal), to je na celu knizku, ale velmi skratkovito/priblizne. Vyhoda InnoDB - transakcie, lahsie zotavenie po havarii. Nevyhoda - moznost vzniku deadlocku (cela aplikacia zahadne zamrzne (pomerne vzacna vec, ked sa nevhodne pouziju transakcie a uzivatel ma smolu) - mozno by bolo pripadne rozumne narychlo o tom nieco pogooglit), o kusok mensia rychlost.
gandor
Mírně pokročilý

Odeslat příspěvekod Marcellito1 20. 7. 2010 21:07

Vidím že som riadna lama pri Vás :D Toto je môj prvý taký vážny projekt tak možno sa Vám to zdá viac menej od veci, sa len učím na svojich chybách ...
hekrhy musím si o tých hasch-och niečo prečítať, vidím, že zase robím niečo úplne na ***** :D díky za typ, s tým šetrením, asi sa teda na to teda vybodnem
gandor ako som vyššie spomínal, vykašlem sa na také šetrenie, keďže podľa vás to nemá zmysel, momentálne na našom "starom fóre" mám po vyčistení od spamu okolo 1000 príspevkov (prvý rok spustenia) a teraz to chcem prerobiť na niečo vlastné (chcem si spraviť nejaké portfólie a jednoducho sa niečo naučiť ...) no ale chcel som tým povedať, že k tomu číslu, milión príspevkov sa len tak ľahko určite nedostanem. Btw ja som mal z matematiky 2 na výške C tak bacha :D Ale keď sa kriticky na ten svoj algoritmus pozriem tak by som ho rozšifroval za pol hodinu a to som asi dosť veľký optimista, možno by to bola otázka pár minút :D Radšej pozriem tie hashovacie funkcie ktoré spomínate. Čo sa týka zamykania a toho celého čo som spomínal, v tomto prípade to bude asi fakt blbosť a použijem klasický auto_increment v mysql, keďže tieto vety sa nebudú len tak for fun mazať (ak niekto nebude aktívny tak ho zmažem čo ja viem po roku). Inak tie tranzakcie to je super vec ale v MySQL som magor, vo VFP sme používali niečo ako BEGIN TRANSACTION ... kod ... END TRANSACTION, ked sa nieco pokazilo tak sa to cele elegantne vratilo naspet, repektive tie vety boli realne zapisane az pri "end transaction", toto sa dalo vyuzit aj v MS SQL, tusim som to pouzival ked som robil trigger ale uz si presne nepametam co som riesil ... jednoducho tam to slo ale co sa tyka MySQL a PHP som uplny novacik, musim si to pozriet, diky za typy
Marcellito1
Junior
Uživatelský avatar

Odeslat příspěvekod gandor 20. 7. 2010 21:48

:) rad som pomohol.
K tym transakciam ano je to presne tak iste aj tu. Len miesto begin transaction mas start transaction a miesto end transaction mas commit a ta transakcia sa da aj zrusit (pomocou prikazu rollback - pokial teda nastane chyba a commit nieje zelany)...

PS. na odstranenie prvej najvecsiej zlozky spamu staci naozaj jednoducha captcha. A nemusis si ju pisat ani sam, na webe ich je uz napisanych milion (je to velmi jednoduchy skript, v jednoduchosti iba ulozis do session par nahodnych znakov a pritom vygenerujes obrazok s tymito znakmi - ten vygenerovany obrazok das do formularu. Po odoslani formularu len pozries ci je zhoda medzi tym v session a tym z formulara).
Jediny problem s ktorym sa mozes stretnut je, ze nebudes mat povolenu akurat tu danu kniznicu na tvorenie obrazkov. Riesenie je najst taky skript, ktory pouziva u teba instalovanu kniznicu, resp. povolit uz nainstalovanu kniznicu ktora je len deaktivovana, resp. nainstalovat nakomplet danu kniznicu, v najhorsiom pouzit par uz hotovych obrazkov a len sa tvarit, ze nejake generujes (posledne dava najmenej zabezpecenia, ale aj tak vecsinou staci)...
gandor
Mírně pokročilý

Odeslat příspěvekod Václav M. 21. 7. 2010 21:26

gandor píše:len nezabudni dobre zasaltovat ;) .

Okořenění - tak to je věc, kterou nepoužívám, protože jsem to jednou zkusil a něco jsem udělal špatně. A od té doby se tomu vyhýbám, přestože je mi jasné, že to je blbost.

Pokud jde o šifrování v MySQL, používám funkci PASSWORD.
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Vebloud 22. 7. 2010 00:14

Salt je ochrana proti slovníkovému útoku. To kdykoliv se ti něco nepovede, tak už to pak neděláš?

Ad password funkce. Jo ta je hezká, ale až se zase jednou Oracel rozhodne, že hashe ve kterých jsou zašifrované přístupy jsou málo bezpečné a zase změní algoritmus jako při přechodu na 4.1, tak budeš v.... viz http://dev.mysql.com/doc/refman/5.1/en/ ... shing.html
Žít a nechat žít, ty máš svůj názor, já mám svůj názor, já ti nebudu nutit svůj, nemusím souhlasit s tvým, ale udělám vše, abys ho mohl svobodně vyjádřit.
Vebloud
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod Marcellito1 22. 7. 2010 14:55

Zdravím, trochu som si to preštudoval a môj záver je.
Ak sa útočník dostane k heslám, je viac než pravdepodobné, že sa dostane aj k ostatným údajom, ako som čítal v jednom príspevku, táto ochrana sa nerobí kvôli dátam ale kvôli tomu, že väčšina užívateľov používa rovnaké heslo na rôzne služby.
No ale k veci, ak sa útočník dostane k dátam, teda k databáze MySQL, má nejaký význam to solenie alebo rôzne "sekanie" hesla na menšie časti a potom to kadejako pospájať, trebárs to aj viac krát za sebou zahashovať. Avšak, ak dokáže byť útočník taký dobrý, tak predsa môže získať aj prístup k FTP a potom si už môže prečítať čo je naša soľ, jednoducho celí postup. Preto si myslím, že to solenie asi moc k ochrane dát nepomôže a skôr by som sa bál, aby sa útočník nezmocnil zdrojákov php a to ochrániť je asi dosť komplikované.
Marcellito1
Junior
Uživatelský avatar

Odeslat příspěvekod Vebloud 22. 7. 2010 15:23

Solení pomůže v tom, že útočníkovi je k prdu předgenerovaný slovník zdroj->hash, který by mohl použít na extrakci hesla z hashe.

Pokud máš zasoleno, tak si musí celý slovník přegenerovat s tvojí solí. A ještě existuje jedna věc a to, že sůl si pro každé jedno heslo generuješ náhodně a ukládáš si ho do databáze k hashy. Pak útočníkovi nepomůže ani slovník přegenerovaný s tvojí solí, protože by ho musel dělat pro každé heslo znova.

Co se postupu týče, tak na jeho neznalost útočníkem se spoléhat nedá, to je security by obscurity což se prostě nepoužívá, spoléhá se na sílu algoritmů. Takže různé sekání a spojování hesel ne, ale solení ano.

Takže jako hash je značně bezpečnější než MD5 používat SHA1 ale spíš SHA256 a vyšší.
Žít a nechat žít, ty máš svůj názor, já mám svůj názor, já ti nebudu nutit svůj, nemusím souhlasit s tvým, ale udělám vše, abys ho mohl svobodně vyjádřit.
Vebloud
VIP uživatel
Uživatelský avatar

Další stránka

Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků