MySQL táblák tervezése
Sziasztok!
Olyan adatbázist szeretnék amiben minden regisztrált felhasználó adatainak a módosításai visszakereshetőek és a felhasználó szinte minden adata módosítható. Autodidaktaként tanulok programozni. Melyik verziót ajánlott használni ehhez? Egyéb elképzelést is szívesen fogadok.
Első verzió:Második verzió:Harmadik verzió:Melyiket ajánlott használni? A felhasználói felületen a lekérdezések gyorsasága az elsődleges cél. Ha több munka van a lekérdezések megírásával vagy magával az adatbázis kialakításával az nem baj.
■ Olyan adatbázist szeretnék amiben minden regisztrált felhasználó adatainak a módosításai visszakereshetőek és a felhasználó szinte minden adata módosítható. Autodidaktaként tanulok programozni. Melyik verziót ajánlott használni ehhez? Egyéb elképzelést is szívesen fogadok.
Első verzió:
create table `users` (
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp
);
create table `username` (
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp,
`content` text not null, -- felhasználónév
`user_id` int not null,
foreign key(`user_id`) references `users`(`id`)
);
create table `user_sex` (
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp,
`content` tinyint(1) not null, -- neme: 1=férfi|2=nő
`user_id` int not null,
foreign key(`user_id`) references `users`(`id`)
);
create table `users` (
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp,
`username` text not null, -- regisztrációkor megadott felhasználónév
`sex` tinyint(1) not null, -- regisztrációkor megadott nem
);
create table `username` (
-- a regisztráció utáni esetleges módosítások
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp,
`content` text not null, -- felhasználónév
`user_id` int not null,
foreign key(`user_id`) references `users`(`id`)
);
create table `user_sex` (
-- a regisztráció utáni esetleges módosítások
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp,
`content` tinyint(1) not null, -- neme: 1=férfi|2=nő
`user_id` int not null,
foreign key(`user_id`) references `users`(`id`)
);
create table `users` (
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp
);
create table `user_data` (
`id` int not null auto_increment primary key,
`upload` timestamp default current_timestamp,
`key` text not null, -- példa: username
`value` text not null, -- példa: i
`user_id` int not null,
foreign key(`user_id`) references `users`(`id`)
);
Hogyan?
Melyik fenti megoldás teszi ezt lehetővé? Mert a fenti kitételeket nem látom megvalósítottnak egyikben sem. Amit én tennék, hogy lenne egy mező ami meghatározza, hogy melyik az aktuális, és minden módosítás létrehozna egy új sort a táblában, megjelölve, hogy ez az aktuális, adva hozzá egy időbélyeget, és minden korábbi sort, ami a felhasználóra vonatkozik megjelölném, hogy az nem az aktuális.
külön tábla
user tábla nem volna terhelve a history infókkal
adott userhez könnyen és szépen ki lehetne listázni a változásokat
Miért strukturálatlanul
ha változik az alap tábla
nem használja úgysem join-okra stb az adatokat, unique_key-k sem mennének, meg az indexek is feleslegesek.
ha csak diff-et rak bele, az is kisebb.
Esetleg hasonlóan, mint ahogy
Elkészíted a user táblát, majd ennek megfelelően egy újabbat (user_history), majdnem azonos szerkezettel. A különbség annyi lenne, hogy hozzá teszel egy datetime mezőt amiben azt tárolod, hogy mikor volt módosítva (userid + ez lehetne az összetett kulcs).
Azonos táblába én azért nem tenném, mert ha a felhasználók száma megugrik és még módosítani is szeretik az adataikat akkor feleslegesen sok lesz a rekord, két tábla összekapcsolásánál ez meg abszolút fájdalmas lehet.
Ennyire - ahogy te tetted - pedig azért nem szedném szét, mert szerintem felesleges. Nagyjából azért lehet tudni, hogy a felhasználó milyen adatait akarod tárolni, nem? :)
Ha nem kifejezetten userekre vonatkozna, hanem tartalmakra is akkor az első verzió egész jó, de a drupál(7) adatbázisát ajánlom tanulmányozásra :)
Félelmek
Történetesen ha mondjuk a jelszót is külön táblában tárolnám és ezzel valami gond lenne a regisztrációs űrlap kitöltése utáni felvitelkor, akkor a felhasználó be se tudna lépni mert a password táblában nem szerepelne a felhasználó azonosítójához tartozó jelszó.
Én nagyon szeretnék mindent külön táblában tárolni mint ahogy az első verzióban van, de ott ugye rengeteg táblát kell létrehozni és ha mondjuk egy felhasználó minden adatát megszeretné változtatni, akkor gyakorlatilag 10 táblába is fel kéne vinni az adatot.
Wordpress adatbázisánál már találkoztam JSON megoldással, de valahogy nem nyerte el a tetszésem pedig tudom, hogy PHP oldalon nagyon könnyű ezt az adatot PHP tömbbé alakítani.
Amit írtatok az user_history pedig azért nem tetszik mert módosításkor itt is több táblához kéne hozzá nyúlni. Egyrészt az aktuális adatok táblában kellene egy UPDATE, másrészt kellene egy INSERT a régiek közé. Gondoljunk csak bele, hogy sikeres az UPDATE, de sikertelen az INSERT, így nem tudnánk már soha többé visszakeresni adatbázisban, hogy mikor mi történt.
Valahogy megkéne oldani, hogy ne féljek a több táblák használatától. Segítsetek ebben! Kezdő vagyok és nincs gyakorlatom. Köszi előre is!
tranzakció
Ha erről van szó akkor a
Tranzakciókezelés
Azt hiszem ez a tranzakciókezelés a varázsszó minden eddigi kérdésemre.
Tudnátok küldeni linkeket ezzel a témával kapcsolatban ahol az alapoktól példákon át láthatom a tranzakciókezelést? Örülnék ha magyar lenne, de angol is jöhet. Egy PDF-nek örülnék a legjobban.
Olvasnivaló
http://ade.web.elte.hu/wabp/lecke5_lap1.html#hiv10
http://dev.mysql.com/doc/refman/5.0/en/commit.html
(Ez is megvolt, de...
Tulajdonképpen mi lehet a feladat és a hozzá tartozó elgondolás?)
Tranzakciók
Tranzakció működése
2. Ezután az összes INSERT-UPDATE-DELETE végrehajtódik, de visszavonható módon. Ami történik az számodra látható, más számára nem mutatkozik meg. ( A "másik" természetesen login-t, más sql kapcsolatot jelent.) A SELECT csak neked adja vissza a módosításokat menet közben.
Van egy kivétel, az auto increment típusú mezők. Maga az INSERT visszavonható, a mező számláló viszont nem. Az lép egyet, akkor is ha megszakítod a tranzakciót.
3. Befejezni COMMIT paranccsal, vagy függvénnyel tudod az eseménysort.
4. Ha el akarsz dobni mindent, erre a ROLLBACK szolgál. Ez az alapértelmezett parancs. Kijelentkezés, program befejezés kiváltja.
Köszönöm!
1. INSERT, UPDATE, ...
2. COMMIT
3. hibakeresés
4. Ha van hiba ROLLBACK
vagy
1. INSERT, UPDATE, ...
2. hibakeresés
3. ha van hiba, akkor ROLLBACK, ha nincs, akkor COMMIT
És akkor azt jól értem, hogyha nincs COMMIT, akkor minden amit csináltunk érvénytelenné válik – kivéve ha volt auto_increment mező mert bár akkor is elvesznek a módosítások az érték attól még növekedni fog?
Ha ez eddig nekem teljesen újdonság és még sohasem találkoztam ezzel a fogalommal, hogy tranzakciókezelés, akkor kulcsszavakban minek nézhetnék még utána? Amit sohasem tudtam, hogy a MySQL függvény = MySQL trigger?
Egyébként ha létrehozok egy függvényt azt hol/hogyan tárolja adatbázisban?
Dokumentáció
Ideje kipróbálni
Az auto increment-tel az a helyzet, hogy a számláló ugrást a következő INSERT után fogod tapasztalni. Mondjuk van 50 rekordod és az utolsó értéked 50. Felvennél egy rekordot 51.-nek, de eldobod ezt a tranzakciót. Maradt 50 rekordod. Újra próbálkozol. Lesz 51 rekordod, és az utolsónak a számlálója 52-őn fog állni.
A triggert nem tudom hol láttad.
Amennyiben az ősi mysql-t használod, vagy hasonló képességű réteget, akkor paranccsal indíthatod be a tranzakciót.
Próbálj ki valamit. Nem ér rögtön témát váltani.
Annyit tennék hozzá, hogy a
A 4. szintén (autocommit). Mindig zárd le explicit a tranzakciót, ahogy a te logikád kívánja!
Naplózás
Egyszerűen csak szeretném naplózni a tevékenységeket. Szeretném tudni ki mikor változtatta meg a felhasználónevét, jelszavát, e-mail címét. Mikor mit mentett el kedvencként, mikor törölte azt, stb. Azt is szeretném tudni, hogy naplóját vagy hozzászólását ha szerkeszti, akkor miért volt szükség a módosításra, stb. Ha valaki panaszkodik valamire vagy valakire, akkor vissza tudjam keresni az aktuális állapotot amiért panaszt tett ami azóta már változhatott, stb.