ugrás a tartalomhoz

Felhasználók, kedvencek, kategóriák hármasának logikus kezelése

montressor · 2006. Szep. 28. (Cs), 09.13
Van harom tabla: users, kedvencek, kategoriak valahogy igy:
users:
user_id | jelszo ...


kategoriak:
kat_id | nev


kedvencek:
id | user_id | kat_id


ez utobbinal a user_id es a kat_id idegen kulcs, a masik ket tabla elsodleges kulcsa. Barmelyik felhasznalonak, tobb kulcsa lehet, igy a kedvencekben tobb azonos user_id is elofordulhat, es ugye tobb ugyanazon kat_id is szerepelhet, igy:

kedvencek:
id | user_id | kat_id
1  | 1       | 2
2  | 1       | 3
3  | 1       | 4
4  | 2       | 2
5  | 2       | 4

harom dolog okoz fejtorest nekem
1, ha a felhasznalo kategoriat valtoztat, mindig le kell torolnom a rekordjait (ez 1 query (where user_id='xx')), es ujra felvenni amit bejelolt (ez annyi insert, ahanyat bejelolt (sok))
Nem lehet-e ezt elegansabban megoldani?

2, eddig jol megvoltam a delete/drop jog nelkul, nem tudom gaz-e ha ezt is pepoccintem (igaz update-tel is lehet kart tenni), szokas-e, kell-e?

3,ha majdan ki szeretnem iratni phpben, az osszes kategoriat, es becsekkolni azt ami az aktualis felhasznalonak a kedvence, akkor ez elegge korulmenyes (legalabb is a 4. ponthoz kepest):

kell egy elso select * from kedvencek where user_id='xx';
kell egy masodik select * from kategoria, h megtudjam a kategoriak nevet

es utanna valami while, de nem tudom hogy hozzam ossze a ket selectet,
mert ugye egy ciklus fut vegig az osszes kategorian kiirashoz, es meg kene neznem, h az aktualis kategoria be van-e jelolve az elso szelekt eredmenyeiben. Na ezt hogyan?

4,gondoltam ra, h esetleg a user tablaban letrehozok annyi boolean kategoriat amennyi van, es akkor egy update az egesz, ez nagyon egyszeru es tetszene, csak elvesztem azt a lehetoseget, h uj kategoriat szurok be, akkor azt csak a kategoria tablaba kelljen megtennem-> esik szet a program, es a db...

Ti mit gondoltok? Koszonom
 
1

Jó struktúra

Anonymous · 2006. Szep. 29. (P), 08.00
Szerintem a felvázolt struktúrád teljesíti az összes normálforma követelményét, tehát tökéletes. A 4. pontban említett, gondolataidban felsejlett megoldást gyorsan felejts el, későbbiekban sokkal több felesleges szívást tartogat, mint amennyi előnyt most, rövid távon jelentene.

Ha már így a végén kezdtem, menjünk visszafelé:
- a 3. pontban leírt 2 select összevonható, ajánlom figyelmedbe az outer join tanulmányozását (a kategória táblához kell hozzá-join-olni a kedvenceket outer :-) )!

- a delete jog természetesen kell, de a drop futásidőben nem, mert az táblát nem akarod eldobni, csak belőle az adatok egy részét.

- az 1. pontban vázolt eljárás szerintem tökéletes, én is így csinálom. Némi optimalizáció persze elképzelhető: egyrész olvasd fel előre a kategóriákat globálisan (felesleges minden felhasználónál külön-külön [cache]), majd szaladj rajtuk végig, és a becsekkoltakathoz futtass insert-et. Az insert utasítások tök egyformák, úgyhogy ha az sql motorod tud ilyent (nem írtad mit használsz) preparáld meg a query-t (prepare) és cserélgesd benne a paramétereket, vagy nyiss egy tranzakciót és azon belült hajtsd végre az összes insert-et (egy felhasználóra), esetleg vesd be mindkét technikát (MySQL újabb verziói tudomásom szerint tudnak tranzakciót, de a prepare-t nem tudom, Interbase/Firebird tudja mindkettőt)

Ha valaki tud ennél jobb megoldást, engem is érdekel!

N0r3i
2

1-es pont

Anonymous · 2006. Szep. 29. (P), 08.35
1, ha a felhasznalo kategoriat valtoztat, mindig le kell torolnom a rekordjait (ez 1 query (where user_id='xx')), es ujra felvenni amit bejelolt (ez annyi insert, ahanyat bejelolt (sok))
Nem lehet-e ezt elegansabban megoldani?

de. az a kérdés, hogy hogyan változtatod a kategóriákat. ha egy formon keresztül kezeled az összeset (például egy multiple select segítségével), akkor tudod az összes új kategória azonosítót, amit megkaptál, valamint tudod az összeset, ami eddig szerepel a felhasználóhóz kapcsolva (ez legfeljebb egy selectbe fog kerülni). szerintem logikus, hogy a két tömb különbsége egyrészt megadja, hogy miket kell törölni, másrészt megadja, hogy miket kell felvinni.
ha php-t használsz, akkor erre az array_diff függvényt tudod használni, például:

<?php
  $letezo=array(1,2,4); // a már hozzárendelt kategóriák
  $ujak=array(1,2,3);   // az űrlapon kapott adatok
  foreach (array_diff($letezo,$ujak) as $kat_id) {
    // delete from kedvencek where user_id=? and kat_id=$kat_id
    // törli a 4-es kategóriát
  }
  foreach (array_diff($ujak,$letezo) as $kat_id) {
    // insert into kedvencek set user_id=?, kat_id=$kat_id
    // felviszi a 3-as kategóriát
  }
?>
én legalábbis így csinálnám.

gex