Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: nextval() dla kazdego uzytkownika osobno
Forum PHP.pl > Forum > Bazy danych > PostgreSQL
Helios
Witam

Tworze pewna baze danych z tabela przechowujaca uzytkownikow oraz uslugi, ktore ci uzytkownicy beda posiadac. Problem jest w tym, ze tych uslug bedzie wiele, tysiace dla kazdego uzytkownika, ktory bedzie je sobie mogl dodawac i usuwac.

Chce, aby uzytkownikowi numeracja uslug leciala od poczatku np. usluga#1, usluga#2 a nie jak w przypadku nextval() usluga#2831381.

Napisalem prosta funkcje w plpgsql:

  1. CREATE OR REPLACE FUNCTION nextdbid(users_id integer)
  2. RETURNS integer AS $BODY$
  3. DECLARE
  4. last_id integer;
  5. BEGIN SELECT db.id INTO last_id FROM db WHERE db.users_id=users_id ORDER BY id DESC LIMIT 1 ;
  6. IF NOT FOUND THEN
  7. RETURN 1;
  8. END IF;
  9. RETURN last_id+1;
  10. END;
  11. $BODY$
  12. LANGUAGE 'plpgsql' VOLATILE
  13. COST 100;
  14. ALTER FUNCTION nextdbid(integer) OWNER TO "admin";


i teoretycznie dziala, jednak przy dodawaniu rekordu musze wklepywac:

  1. INSERT INTO db VALUES (nextdbid(2), 2); -- itd.


rozumiem, ze nie da sie zrobic czegos w stylu:

  1. CREATE TABLE db (
  2. id INTEGER NOT NULL DEFAULT (nextdbid(users_id)),
  3. -- itd.
  4. );


questionmark.gif

Oprocz tego funkcja ta nie dziala dokladnie tak samo jak nextval gdyz podaje wartosc ostatniego id powiekszona o jeden, nie uwzgledniajac czy uzytkownik mial juz jakies uslugi i je wykasowal (po zwolnieniu sie identyfikatorow nie powinny one byc brane pod uwage).

Czy ktos ma jakies lepsze rozwiazanie tego problemu?

Pozdrawiam
Sedziwoj
Cytat(Helios @ 17.10.2008, 22:58:19 ) *
Oprocz tego funkcja ta nie dziala dokladnie tak samo jak nextval gdyz podaje wartosc ostatniego id powiekszona o jeden, nie uwzgledniajac czy uzytkownik mial juz jakies uslugi i je wykasowal (po zwolnieniu sie identyfikatorow nie powinny one byc brane pod uwage).


Przecież praca na sekwencjach też nie uwzględnia usuwania rekordów więc nie wiem o czym teraz piszesz.

Ogólnie jak się upierasz przy tym numerowaniu (bo moim zdaniem nie ma sensu bawić się czy to będzie usługa#2098 czy usługa#190, no chyba że tak masz w specyfikacji), to masz prostą sytuacje, dla każdego użytkownika musisz mieć osobną sekwencję. I ja widzę teraz dwa rozwiązania, albo tworzysz dla każdego użytkownika sekwencję postgresową, albo tworzysz swój mechanizm sekwencji, czyli np. tabela z kolumnami user_id|seq i w seq przechowujesz niewykorzystany identyfikator. (oczywiście najlepiej obsługę tego zamknąć w funkcje)
Helios
Cytat(Sedziwoj @ 18.10.2008, 12:17:14 ) *
Przecież praca na sekwencjach też nie uwzględnia usuwania rekordów więc nie wiem o czym teraz piszesz.


Uwzglednia usuwanie rekordow, bo jak dodasz 3 wpisy do tabeli i je usuniesz to nextval dla sekwencji zwroci Ci i tak 4, a w opisanej sytuacji jezeli bede mial uzytkownika, 1, 2, 3, 4 i usune 4, to funkcja mi zwroci 4, a wiec wczesniej wykorzystane id znowu bedzie uzyte.
Sedziwoj
A jak będą wykorzystane 1, 2, 3, 4 i usunie 3? Robisz coś bez sensu, w ogóle jeśli masz jakieś usługi to powinny mieć stały numer i jedynie oznaczać niektóre jako usunięte.
Wydaje mi się że robisz podstawowy błąd, czyli masz błędne założenia jak coś ma funkcjonować.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.