ugrás a tartalomhoz

Több szintű törlés MySqlben

therest · 2011. Május. 12. (Cs), 13.49
Elvesztem a mysql terén kicsit.

Van három táblám, sorba kapcsolva, kettes táblának van egy oszlopa ahol a mezők az egyes tábla vonatkozó id-jét tartalmazza. A 3. tábla pedig a kettesre mutat e módon.
Példának: Galériák(id), fotók(id,galeriaId), kommentek(id,fotoId).
Nem tudom milyen módszer lenne itt a jó ha törölni kell egy galériát, és ezzel együtt a képeket, és a kommenteket is.
A helyzetet bonyolítja, hogy a képeket nem csak az adatbázisból, hanem fájlként is törölni kell.
Eddig így csináltam:
1.Lekérdeztem a képek táblából az összes megfelelő galeriaId-jű képet.
2.A result-on végigszaladva töröltem a képfájlokat, és az idket összefűztem ,-vel elválasztva, egy $ids változóba.
3.Töröltem a kommenteket a kommentek táblából a következő segítségével: "WHERE in IN ($ids)"
4.Töröltem a képek táblából a galeriaId alapján.
5. Töröltem a galériát.

Lehet ezt hatékonyabban? Az első query-t nem lehet megkerülni, de a 3 törlésest gondolom össze lehetne vonni, bár gőzöm sincs hogyan. Érdemes, hoz kézzel fogható sebesség növekedést?
 
1

Nézz utána a foreign key-nek.

dragi · 2011. Május. 12. (Cs), 14.20
Nézz utána a foreign key-nek. Azzal meg lehet azt csinálni ami neked kell. Cascadeolva.
2

CASCADE példa

Arcos · 2011. Május. 12. (Cs), 14.34
Hi

Gondolom valami ilyesmire gondoltal, nem ellenőriztem le hogy jó e, de ha a táblát ugy hozod létre hogy törlés esetén a hivatkozo külső kulcsokat is törli (szóval ha törölsz a t1 böl, akkor t2 böl törlödik az összes sor ami rá hivatkozott)
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

pl

CREATE TABLE t1(
id int NOT NULL AUTO_INCREMENT,
t1name varchar(20) NOT NULL,
PRIMARY KEY(id)
)

CREATE TABLE t2 (
id int NOT NULL AUTO_INCREMENT,
t1id int NOT NULL,
comment1 varchar(20) NOT NULL,
comment2 varchar(20) NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY (t1id) REFERENCES t1(id) ON DELETE CASCADE
)
3

És ha jól tudom, ilyesmit

bb0072 · 2011. Május. 12. (Cs), 15.32
És ha jól tudom, ilyesmit csak innoDB típusú táblákkal lehet csinálni. Ennek meg az a hátránya, hogy ilyen táblákra meg nem tehetsz például fulltext indexet, tehát például a szövegeket is tartalmazó cikk táblán már nem valósíthatod meg, feltéve, hogy a cikkek szövegében keresni is akarsz. De a galériákkal talán még működik.
4

Ez a cascade jónak tűnik.

therest · 2011. Május. 12. (Cs), 16.44
Ez nagyon hasznos infó volt, sok mindent megold a jelenlegi problémámban. Létezik-e olyan delete query ami vissza is adja a törölt sorokat? Ez ugye arra kéne, hogy ne kellejen a fájlok törléséhez először egy selectet csinálni. Azt tudom hogy DELETE-ből alapból csak TRUE/FALSE jöhet.

Azt, hogy érted, hogy nem lehet keresni a szövegben? A fulltext index már nem mondott semmit. :)
5

Ha a cikkek teljes szövegében

bb0072 · 2011. Május. 13. (P), 11.10
Ha a cikkek teljes szövegében akarsz keresni, és elfogadható válaszidőt is akarsz, akkor a szöveget tartalmazó mezőre fulltext indexet kell rakni (és a WHERE feltételben pedig MATCH - AGAINST szerkezetet kell használni). Ha a tábla innoDB típusú, tehát tranzakciókezelésre is használható, ill. cascade-olt törlésre, akkor viszont ez nincs. Fulltext indexet csak MyISAM típusú tábláknál használhatsz, nem tudom miért. Remélem ezt majd javítják előbb-utóbb.
6

Na tanultam valami újat

therest · 2011. Május. 13. (P), 14.24
Na tanultam valami újat ismét, a mach-againstről sem hallottam még. Kisebb szöveges mezőkben (varchar1-255) %LIKE% -al szoktam keresni, ez megfelelő sebességű?

Szerencsére a galéria rendszernél nincs kereshető adat, szóval ott nem számít.
7

A like az teljesen jó

bb0072 · 2011. Május. 13. (P), 14.48
A like az teljesen jó varcharnál. Text, mediumtext, longtext típusú mezőknél viszont már nem ajánlanám.
8

Joinnal is lehet!

therest · 2011. Május. 13. (P), 15.49
DELETE g,i,c FROM `galeries` as g LEFT JOIN `images` AS i ON i.gID=g.id LEFT JOIN `commments` AS c ON c.iId=i.id WHERE g.id='123123';