Mazání záznamů
Školení, která pořádám
Pro vymazání řádků z databáze slouží příkaz DELETE, některé záznamy se ale může hodit fyzicky nemazat, ale pouze zakázat jejich zobrazování. Dá se k tomu použít sloupec nezobrazovat bool
(pokud má být výchozí stav zobrazeno) nebo zobrazovat bool
(samozřejmě lze použít i hodnota DEFAULT). Někteří lidé zastávají názor, že z databáze by se nikdy nic mazat nemělo, podle mě to ale řadu dotazů jenom zbytečně zesložiťuje a příznak smazání tak doporučuji používat pouze u záznamů, ke kterým se uživatel bude moci chtít v budoucnu ještě vrátit. Pokud potřebujeme mít přehled o tom, co bylo do databáze kdy vloženo a z ní smazáno, je k tomu určitě lepší použít binární log, který ošetřuje i případy, kdy uživatel nesmaže záznam pomocí naší aplikace, ale přímo.
Pro data s nastaveným příznakem zobrazování je ideální vytvoření pohledu.
Další věc je mazání historických záznamů. Osobně jsem spíše toho názoru, že i historická data by se mohla někdy hodit a se správně navrženými indexy by neměla aplikaci významně zpomalovat. V některých situacích už ale není jiné cesty, v tom případě bych data alespoň zazálohoval, přímo v MySQL se k tomu dá použít typ tabulky ARCHIVE.
Pro rychlé smazání všech dat z tabulky slouží příkaz TRUNCATE, který navíc vynuluje i zapamatované hodnoty sloupce AUTO_INCREMENT.
Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.
Diskuse
JersyWoo:
Truncate jsem neznal. Díky
Leo:
Dubois v MySQL profesionalne pise, ze DELETE * FROM tabulka NEKDY muze smazat autoincrement, a reseni je vynutit si mazani radek po radku podminkou WHERE ktera je splnena pro kazdy radek. Leo
Možná lepší než binlog by bylo řešení přes triggery.
Václav Vaník:
jsem též zastánce sloupce "zobrazovat bool".
veškerá data pak lovím přes pohled WHERE zobrazovat = 1
Stoupa101:
Taky pouzivam mazani stylem _delete = 1.
Problem mi nastal kdyz sem mel unikatni sloupec (vazba sloupec _delete) a 2x ho vytvoril a smazal. Musel jsem vytvorit dalsi sloupecek _history, ktery jsem dal do uniqe (misto _delete) a kam davam cislo (z generatoru ciselnych rad) kolikaty zaznam z dane tabulky byl smazan. Toto cislo slouzi jen k udrzeni unikatnosti jineho sloupce. Pri insertu nebo updatu obsahuje vzdy 0. Krasne je ze se pak da na mazani jakehokoli radku pouzit jednoducha funkce (primarni klic je stejny jako nazev tabulky bez _):
function SmazRadek($tab, $id) {
f_DBconn($adodb);
$save_db = $adodb->Execute('select * from '.$tab.' where '.str_replace('_','',$tab).'='.$id);
$data = array();
$data['_delete'] = 1;
$data['_history'] = GetGenHist($tab);
$adodb->LogSQL();
$updateSQL = $adodb->GetUpdateSQL($save_db, $data);
$update = $adodb->Execute($updateSQL);
$adodb->LogSQL(false);
}
derhaa:
ahoj a co kdyz mam v tabulce sloupec (kde uvadim pouze cestu do adresare): /img/obrazek.gif , takze pri smazani dojde sice ku smazani radku, ale ne souboru..? jak nato?
Dave Lister:
za prikazem na smazani radku z databaze zavolej jeste
<?php
if (file_exists("./img/obrazek.gif")) {
unlink("./img/obrazek.gif");
}
?>
nebo jen
<?php
@unlink("./img/obrazek.gif");
?>
Radek Cvek:
se zkušeností s uploadováním obrázků na hosting, bych přidal změnu atributu
<?php
if (file_exists($obrazek)) {
chmod($obrazek, 0777);
unlink($obrazek);
}
?>
Diskuse je zrušena z důvodu spamu.