PostgreSQL - kolejność rekordów

0

Witam
Korzystam z postgresql 9.1

mam 2 tabele:

CREATE TABLE layer
(
layer_name character varying(256) NOT NULL,
layer_type character varying(30) NOT NULL,
description character varying(256),
enabled boolean,
srid character varying(16) NOT NULL,
CONSTRAINT layer_pk PRIMARY KEY(layer_name)

);

CREATE TABLE attribute
(
layer_name character varying(256) NOT NULL,
attr_name character varying(256) NOT NULL,
attr_type character varying(30) NOT NULL,
description character varying(256),
"length" integer,
nillable boolean,
CONSTRAINT attribute_pk PRIMARY KEY (layer_name, attr_name),
CONSTRAINT attribute_fk FOREIGN KEY(layer_name) REFERENCES layer(layer_name) ON DELETE CASCADE
);

W swoim programie dodaje do bazy danych do tabeli attribute rekordy.

Gdy chce je odczytać także w programie zwracane są w kolejności uporządkowanej alfabetycznie, ja natomiast nie ustawiam żadnego sortowania -
"SELECT attr_name, attr_type, description, length, nillable FROM attribute WHERE layer_name = ?;"

Doszedłem do tego (testowane w pgAdminIII), że

SELECT * FROM attribute WHERE layer_name = 'da1111111'; - zwraca posortowane
SELECT * FROM attribute; - zwraca w kolejności w której było wrzucane

Czy to zależy od jakichś ustawień bazy? Jak to zmienić?
Z góry dziękuje za odpowiedzi.

1

Na tabeli attribute masz indeks klastrowany na polach (layer_name, attr_name).
Gdy chcesz otrzymać tabelę bez używania warunków to PostgreSQL zwraca kolejne rekordy z tabeli czyli w takiej kolejności jak były wstawiane.
Gdy używasz warunku na polu, które jest indeksowane PostgreSQL korzysta z indeksu aby znaleźć żądane rekordy, z kolei indeks jest posortowany alfabetycznie, stąd taki wynik.

2

Trzeba stosować ORDER BY. Można śmiało przyjąć że bez tego rekordy będą zwracane w losowej kolejności, która zależy od wielu rzeczy tak naprawdę.

0

Generalnie powinieneś zakładać każdą tabelę bez wyjątku z polem id typu SERIAL (odpowiednik auto_increment), które będzie automatycznie przybierało kolejne wartości od 1 do x w takiej kolejności w jakiej wstawiano rekordy do bazy. Na polu id powinien być PK, a oprócz tego można osobno założyć zwykły indeks, bądź indeks klastrowany. W przypadku gdy w SELECT użyłbyś warunku na polu z indeksu, to wystarczy dodać ORDER BY id i już masz rekordy w kolejności wstawiania, a oprócz tego baza zachowuje się tak jak wcześniej i korzystasz ze wszystkich zalet indeksów.

0

zasada jest bardzo prosta - chcesz mieć posortowane dane to je posortuj. Koniec i kropka. Liczenie na to, że baza sama się domyśli w jakiej kolejności chcesz mieć zwrócone dane jest niedorzeczne.

0

W tej chwili zrobiłem tak, że korzystam z CTID: SELECT CTID, * FROM attribute WHERE layer_name = 'x' ORDER BY CTID
nie wiem na ile to poprawne, na razie zdaje egzamin

0

Obawiam się, że CTID rekordu update-owanego albo po wykonaniu VACUUM FULL zmieni się. Dodaj kolumnę id SERIAL żeby mieć pewność, że uzyskasz rekordy w kolejności wstawiania.

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