Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Sekvenca se ne uveccava za 1 pri particionisanju tabela

[es] :: PostgreSQL :: Sekvenca se ne uveccava za 1 pri particionisanju tabela

[ Pregleda: 5334 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

karas

Član broj: 5574
Poruke: 482
*.1.eunet.yu.



+1 Profil

icon Sekvenca se ne uveccava za 1 pri particionisanju tabela17.12.2006. u 10:37 - pre 190 meseci
Neka je data tabela
Code:

CREATE TABLE parent(id serial, message text); 

i dve koje je nasledjuju
Code:

CREATE TABLE child1(CHECK(id >= 1 AND id <= 20)) INHERITS(parent);
CREATE TABLE child2(CHECK(id >= 21 AND id <= 40)) INHERITS(parent);
ALTER TABLE child1 ALTER id DROP DEFAULT;
ALTER TABLE child2 ALTER id DROP DEFAULT;

Sa ALTER je onemogucceno da kolona id u nasledjenim tabelama child1 i child2 dobija automatsku vrednost preko sekvence. Dalje,
Code:

CREATE OR REPLACE RULE r1 AS ON INSERT TO parent WHERE id >= 1 AND id <= 20
    DO INSTEAD INSERT INTO child1 values(new.id, new.message);
CREATE OR REPLACE RULE r2 AS ON INSERT TO parent WHERE id >= 21 AND id <= 40
    DO INSTEAD INSERT INTO child2 values(new.id, new.message);

Ovim pravilima se za id izmedju 1 i 20 vrednosti ubacuju u child1 a za id izmedju 21 i 40 ubacuju u child2. Dakle, sekvenca parent_id_seq je podrazumevana vrednost samo za id u parent tabeli i pochinje od vrednosti 1. Medjutim, ako se uradi
Code:

INSERT INTO parent(message) VALUES('hello');

u tabelu parent ubachena je vrednost sa id = 5. Daljim ubacivanjem je id = 11 pa id = 17, itd. tj. sekvenca parent_id_seq se ne uveccava za po 1. Zashto, ako se ona koristi samo u tabeli parent?
Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.routotelecom.com.



+1 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela19.12.2006. u 15:04 - pre 190 meseci
Da preformulishem problem:
Code:

CREATE TABLE parent(id serial, message text);
CREATE TABLE child() INHERITS(parent);
ALTER TABLE child ALTER id DROP DEFAULT;

Ako se postavi pravilo
Code:

CREATE OR REPLACE RULE r AS ON INSERT TO parent DO INSTEAD INSERT INTO child VALUES(NEW.id, NEW.message);

onda svaki INSERT u tabelu parent poveccava sekvencu parent_id_seq za 1 kao shto i treba. Ali ako se pri kreiranju pravila ubaci uslov po id
Code:

CREATE OR REPLACE RULE r AS ON INSERT TO parent WHERE id>=1 AND id <= 100 DO INSTEAD INSERT INTO child VALUES(NEW.id, NEW.message);

onda se sekvenca uveccava za 5 pri svakom INSERT u tabelu parent.
Ne vidim gde greshim, vishe mi lichi na greshku u samom PostgreSQL-u.

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

chachka
Srđan Mijatov
Programer
BUS Computers
Kikinda

Član broj: 53780
Poruke: 576
*.dialup.neobee.net.

Sajt: www.baze-podataka.net


+4 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela21.12.2006. u 08:49 - pre 190 meseci
Cini mi se da je greska do PostgreSQL-a
"The best code is no code at all."
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming."
- Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.routotelecom.com.



+1 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela22.12.2006. u 09:30 - pre 190 meseci
Ovo se deshava u verzijama 8.1.4 i 8.2.0 (za Linux). Poslao sam im bug report pa ccemo videti shta cce odgovoriti.

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.routotelecom.com.



+1 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela26.12.2006. u 08:45 - pre 190 meseci
Evo i odgovora:
Citat:

"id" is basically a macro that gets replaced with the expression being
inserted, ie, the nextval() call. So you're getting bit with multiple
evaluation.

There isn't any very safe way to do this sort of thing with a rule.
Consider using a trigger instead.

regards, tom lane

Kako god, ovakvo ponashanje pri particionisanju tabele uopshte nije intuitivno, niti je naglasheno u dokumentaciji.
Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

chachka
Srđan Mijatov
Programer
BUS Computers
Kikinda

Član broj: 53780
Poruke: 576
80.74.160.*

Sajt: www.baze-podataka.net


+4 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela27.12.2006. u 22:14 - pre 190 meseci
Hvala na kompletiranoj prici.
Naravoucenije - ne koristiti rule-ove!?
"The best code is no code at all."
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming."
- Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.routotelecom.com.



+1 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela04.01.2007. u 11:44 - pre 190 meseci
Još jedna stvar povezana sa ovom: iako u dokumentaciji za verziju 8.0.0. postoji nasleđivanje tabele, čini se da ne radi kako treba sa verzijom 8.0.3. Naime, INSERT i DELETE na nasledjenoj tabeli rade bez problema, ali DROP i ALTER zaglupljuju server. Sa verzijama 8.1.4 i 8.2.0 nije bilo problema.

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

chachka
Srđan Mijatov
Programer
BUS Computers
Kikinda

Član broj: 53780
Poruke: 576
*.ADSL.neobee.net.

Sajt: www.baze-podataka.net


+4 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela06.09.2007. u 22:23 - pre 182 meseci
Dok sam danas čitao tekst o particionisanju tabela, setio sam se starog Karasovog problema :) U tekstu se predlaže alternativan način za particionisanje koji se zasniva na trigerima, a ne na rulovima.

Odmah sam probao kako se ponaša Karasov problem i... ponaša se odlično, baš kako bi i trebalo :) Another nail in the RULE coffin!

Znači ako imamo:
Code:

CREATE TABLE parent(id serial, message text);
CREATE TABLE child() INHERITS(parent);
ALTER TABLE child ALTER id DROP DEFAULT;

Uslov particionisanja po koloni id postavljamo pomoću trigera:
Code:

CREATE OR REPLACE FUNCTION f_bi_par () RETURNS trigger AS
$body$
BEGIN
  -- uslov particionisanja
  IF NEW.id>=1 AND NEW.id <= 100 THEN
    INSERT INTO child VALUES(NEW.id, NEW.message);
  END IF;
  -- Ovo je bitno, da triger vrati NULL,
  -- tako da red nece biti upisan u tabelu parent
  RETURN NULL;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

CREATE TRIGGER tr_bi_par BEFORE INSERT 
ON parent FOR EACH ROW 
EXECUTE PROCEDURE f_bi_par();

Ovaj kod se ponaša po očekivanju i id se uvek povećava za 1!

Naravno, ovde fale još trigeri za UPDATE i DELETE, ali poenta je prikazana.

NAPOMENA 1: Stranica broj 26 linkovanog PDF fajla zna da blokira Acrobat Readera. Ona uopšte nije bitna, samo je treba na brzinu preskočiti i nastaviti sa daljim čitanjem.

NAPOMENA 2: Testirano na PostgreSQL 8.2.4
"The best code is no code at all."
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming."
- Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.routotelecom.com.



+1 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela07.09.2007. u 14:38 - pre 182 meseci
Sekvence se ponašaju kako treba ali podaci se upisuju i u parent i u child!? Koristio sam 8.2.0 pod Linuksom.
Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

chachka
Srđan Mijatov
Programer
BUS Computers
Kikinda

Član broj: 53780
Poruke: 576
*.ADSL.neobee.net.

Sajt: www.baze-podataka.net


+4 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela07.09.2007. u 15:13 - pre 182 meseci
Parent tabela prikazuje podatke svih tabela koje su je nasledile. Pošto je red pomoću trigera upisan u child tabelu (INSERT INTO child ...) taj red će biti vidljiv i u parent tabeli. Red nije upisan u parent tabelu jer to sprečava deo trigera RETURN NULL!

Kreirajmo strukturu iz predhodnog posta i proverimo da li su tabele prazne
Code:

karas=# SELECT * FROM parent;
 id | message
----+---------
(0 rows)

karas=# SELECT * FROM child;
 id | message
----+---------
(0 rows)

Tabele jesu prazne. Sada unesemo nešto u child tabelu
Code:

karas=# INSERT INTO parent (message) VALUES ('Hello!');
INSERT 0 0
karas=# INSERT INTO parent (message) VALUES ('HELLO!');
INSERT 0 0

Proverimo rezultat:
Code:

karas=# SELECT * FROM parent;
 id | message
----+---------
  1 | Hello!
  2 | HELLO!
(2 rows)

karas=# SELECT * FROM child;
 id | message
----+---------
  1 | Hello!
  2 | HELLO!
(2 rows)

To je to što očekujemo. Tako se ponaša particionisanje.

Da bi se izvršilo brisanje dovoljno je obrisati podatke samo iz child tabele. Da li je to dovoljan dokaz da se podaci ne upisuju i u parent tabelu?
Code:

karas=# DELETE FROM child;
DELETE 2

karas=# SELECT * FROM parent;
 id | message
----+---------
(0 rows)

karas=# SELECT * FROM child;
 id | message
----+---------
(0 rows)




=========================================


Kada bi se u trigeru umesto RETURN NULL koristilo RETURN NEW, tada bi smo imali upis i u child i u parent tabelu.

Pošto sam pobrisao podatke, treba samo da promenim triger.
Code:

CREATE OR REPLACE FUNCTION f_bi_par () RETURNS trigger AS
$body$
BEGIN
  -- uslov particionisanja
  IF NEW.id>=1 AND NEW.id <= 100 THEN
    INSERT INTO child VALUES(NEW.id, NEW.message);
  END IF;
  -- SADA CE SE ZBOG NEW UPISIVATI I U PARENT TABELU!
  RETURN NEW;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

DROP TRIGGER tr_bi_par ON parent;

CREATE TRIGGER tr_bi_par BEFORE INSERT 
ON parent FOR EACH ROW 
EXECUTE PROCEDURE f_bi_par();

Ako sada izvršimo upis dva podatka dobićemo duplirane podatke u parent tabeli jer ona sada prikazuje i podatke koji su upisani u njoj i podatke koji su upisani u njenoj tabeli naslednici.
Code:

karas=# INSERT INTO parent (message) VALUES ('Zdravo!');
INSERT 0 0
karas=# INSERT INTO parent (message) VALUES ('ZDRAVO!');
INSERT 0 0

karas=# SELECT * FROM parent;
 id | message
----+---------
  3 | Zdravo!
  4 | ZDRAVO!
  3 | Zdravo!
  4 | ZDRAVO!
(4 rows)

karas=# SELECT * FROM child;
 id | message
----+---------
  3 | Zdravo!
  4 | ZDRAVO!
(2 rows)

"The best code is no code at all."
- Zidar (ES član)
"Biggest obstacle to learning
SQL is unlearning procedural
programming."
- Joe
Celko
"Minimize code, maximize data."
- A. Neil Pappalardo
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.routotelecom.com.



+1 Profil

icon Re: Sekvenca se ne uveccava za 1 pri particionisanju tabela10.09.2007. u 14:57 - pre 181 meseci
Moja greška prillikom postavljanja upita. Dovoljno je bilo da stavim ONLY u upit
Code:

SELECT * FROM ONLY parent;

i da vidim da nema ničega u roditeljskoj tabeli. Hvala na detaljnom odgovoru.

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

[es] :: PostgreSQL :: Sekvenca se ne uveccava za 1 pri particionisanju tabela

[ Pregleda: 5334 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.