Problem z rekordami i kluczami w PostgreSQL

0

Witam,
mam mały problem z bazą danych PostgreSQL. Mam taką tabelkę:

CREATE TABLE dane (
  id serial NOT NULL,
    id integer,
    id_modulu varchar(20),
    czas timestamp without time zone,
    dane1 real,
    dane2 real,
    PRIMARY KEY (id)
);

Różne urządzenia zapisują dane do tej tabeli... I bardzo często dane te są zdublowane (dochodzi do miliona rekordów dubli dziennie):/

Czy da się coś zrobić coś żeby się nie dublowało po stronie bazy?

Dubla rozpoznajemy po tym że: id_modulu, czas i dane1 są identyczne.

Aktualnie mam klucz założony na ID - może da się coś dodatkowego nałożyć na czas i id_modulu jednocześnie żeby zablokować ewentualne zdublowane wpisy?

W urządzenia nie mogę ingerować - muszę załatwić to po stronie bazy...

Wie ktoś może jak to zabezpieczyć?

Z góry dziękuje za pomoc,
Łukasz

0

Dokumentacja PostgreSQL: Primary keys - zobacz ostatni przyklad.

0

@up - osobiście nie zakładałbym primary key na inne kolumny niż id ale ostatecznie też tak można.

Proponuję napisać procedurę do której będziesz przekazywał dane. Procedura będzie sprawdzała czy dany wpis już istnieje w bazie, jeżeli nie istnieje to wykona insert.

Inne możliwości to założenie unique constraint na te kolumny:

UNIQUE(id_modulu, czas, dane1)

albo napisanie triggera before insert.

0

a da się zrobić tak, żeby baza nie wywalała błędu? (te klucze uniq)
Urządzenia się resetują przy otrzymaniu błędu...:/

trigger działa automatycznie - w momencie dodawania nowego rekordu?

0

W takim razie napisz procedurę w której będziesz sprawdzał czy rekord istnieje.

IF NOT EXISTS (SELECT 1 FROM dane WHERE id_modulu = @id_modulu AND czas = @czas AND dane1 = @dane1)
  INSERT INTO dane (id, id_modulu, czas, dane1, dane2) VALUES (@id, @id_modulu, @czas, @dane1, @dane2)

trigger działa automatycznie - w momencie dodawania nowego rekordu?

tak

0
AdamPL napisał(a)

W takim razie napisz procedurę w której będziesz sprawdzał czy rekord istnieje.

IF NOT EXISTS (SELECT 1 FROM dane WHERE id_modulu = @id_modulu AND czas = @czas AND dane1 = @dane1)
  INSERT INTO dane (id, id_modulu, czas, dane1, dane2) VALUES (@id, @id_modulu, @czas, @dane1, @dane2)

trigger działa automatycznie - w momencie dodawania nowego rekordu?

tak

czyli po dodaniu ww kodu takie zapytania:
insert into dane (id_modulu, czas, dane1) values (4, 5, 6);
insert into dane (id_modulu, czas, dane1) values (4, 5, 6);

  • nie przedją, bo będzie dubel i wejdzie tylko 1 rekord

pozwoli za to na taką:
insert into dane (id_modulu, czas, dane1) values (4, 5, 6);
insert into dane (id_modulu, czas, dane1) values (4, 5, 7);

wejdą oba zapytania?

0
Northwest napisał(a)

czyli po dodaniu ww kodu takie zapytania:
insert into dane (id_modulu, czas, dane1) values (4, 5, 6);
insert into dane (id_modulu, czas, dane1) values (4, 5, 6);

  • nie przedją, bo będzie dubel i wejdzie tylko 1 rekord

pozwoli za to na taką:
insert into dane (id_modulu, czas, dane1) values (4, 5, 6);
insert into dane (id_modulu, czas, dane1) values (4, 5, 7);

wejdą oba zapytania?

Tak.

1 użytkowników online, w tym zalogowanych: 0, gości: 1