Gimliho web „foggy point” - programování, php, outdoor, o ničem...Skip to main content.

MySQL a číselné řady

Potřeboval jsem přečíslovat ID položek v databázi. Chtěl jsem, aby to byla postupně rostoucí řada, která ale nebude začínat od 1, ale od nějaké konstanty…

Rád bych hned z kraje upozornil, že na těch ID nebylo nic dalšího vázáno, tedy nebylo nutno počítat s žádným integritním omezením. Tento článek tedy slouží jednoznačně pouze jako inspirace, nikoli použitelné hotové řešení problému. Stejně tak se to dalo vyřešit jednoúčelovým php skriptem, který by postupně přečísloval IDčka rovnou v původní tabulce, ale chtěl jsem se pokusit problém řešit výhradně na straně databázového serveru.

Nejjednodušší bylo využít vlastnost auto_increment. Takže jsem si založil novou tabulku, nastavil vhodnou počáteční hodnotu auto_incrementu a jen do ní přelil stará IDčka. MySQL se sama postarala o nagenerování nových. Pak už zbývalo původní updatovat podle nové tabulky.

1. varianta

-- vytvorime tabulku
CREATE TABLE IF NOT EXISTS usr2 (
  id int(5),
  nove int(5) auto_increment,
  PRIMARY KEY  (nove)
) AUTO_INCREMENT=666;

-- nalejem data ze stare a rovnou nechame pridelit nove ID .{color:gray}
INSERT INTO usr2 (SELECT id, 0 FROM users);

Pak mě ale napadlo, že pokud bych chtěl mít novou řadu IDček rostoucí ne po 1, ale po X, případně naopak třeba klesající, či se zápornými hodnotami, tak si s auto_incrementem nevystačím. Psát se mi vlastní stored proceduru nechtělo, takže jsem vyzkoušel v MySQL poměrně novou věc – a to triggery. Ukázka 2 tedy řeší stejný problém jako první, ale jinak 😉. Variabilita je skutečně široká, mohl jsem trigger nastavit, aby se spouštěl až po příkazu (tedy klíčové slovo AFTER místo BEFORE), nemusel být vázán na UPDATE, ale rovonu na INSERT atd… Tento přístup se mi zdá užitečný, pokud potřebujeme nějaké hodnoty měnit na základě ostatních, které už v tabulce jsou. Pro vytvoření číselné řady rostoucí po jedné je to ale zbytečné takto lámat přes koleno a použijeme auto_increment. Na druhou stranu proč si nevyzkoušet vícero postupů…

2. varianta

-- vytvorime tabulku
CREATE TABLE IF NOT EXISTS usr (id int(5), nove int(5));

-- nalejem data ze stare
INSERT INTO usr (SELECT id, 0 FROM users);

-- nastavime novou pocatecni hodnotu o 1 nizzsi nez skutecne chceme
UPDATE usr SET nove=665 WHERE id=1;

-- vyrobime si trigger, ktery zvetsi vsechny polozky nove o 1
delimiter //
CREATE TRIGGER mujtriger BEFORE UPDATE ON usr
FOR EACH ROW
begin
  SET NEW.nove=(SELECT MAX(nove)+1 FROM usr);
end
//

delimiter ;

-- nechame trigger precislovat vsechny zaznamy...
UPDATE usr SET nove=nove WHERE 1;

-- odstranime trigger
DROP TRIGGER mujtriger;


Gimli2 | Vyšlo: 21. 9. 2007 - 15:51:01 | Zobrazení: 3603

Články podobné

Podobnost je určována triviální cestou shody některého ze slov z nadpisu článku. Jsem zvědavej, co to tu bude nabízet za asociace ;-)