Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PostgreSQL - jak najlepiej definiować dynamiczne pola?

635 views
Skip to first unread message

Marek

unread,
Jan 30, 2015, 8:19:18 AM1/30/15
to
Witam,

Na etapie projektu powstała tabela

CREATE TABLE tabela
(
tabela_id SERIAL PRIMARY KEY,

pola...
);

Jednakże okazało się iż tabela ta ma mieć dodatkowe pola zarówno
informacyjna jak i czasem biorące udział w wyszukiwaniu. Pól będzie
przybywać i mają być definiowane na bieżąco. Typ nieprzewidywalny -
niektóre tekstowe, niektóre liczbowe. Pomyślałem zatem, że mógłbym
wykorzystać pole typu tablicowego

CREATE TABLE tabela
(
tabela_id SERIAL PRIMARY KEY,

pola...
uniwersalne text[];
);

Zapis qusi-pól wyglądałby tak, że w polu "uniwersalne" trzymałbym
wartości. Kłopot w tym, że PostgreSQL nie ma tablic asocjacyjnych więc
musiałbym się posiłkować tabelą słownikową konwertującą nazwę na indeks:

CREATE TABLE name_to_index
(
name_to_index_id SERIAL PRIMARY KEY,

nazwa_pola varchar(100), --nie indeksowane bo tabela będzie miała do
ok 20 rekordów
indeks_odpowiadajacy_w_polu_uniwersalne int
);

Oczywiście w w plpgsql napisałbym funkcję symulującą dostęp do tablicy
asocjacyjnej. Czy taka ideologia jest poprawna? Da się to lepiej
zorganizować?

Czy da się indeksować w tablicy np. indeks 4 i 10ty np.?

--
Pozdrawiam,
Marek

Cezary Grądys

unread,
Jan 30, 2015, 4:24:39 PM1/30/15
to
W dniu 30.01.2015 o 14:19, Marek pisze:
> Witam,
>
> Na etapie projektu powstała tabela
>
> CREATE TABLE tabela
> (
> tabela_id SERIAL PRIMARY KEY,
>
> pola...
> );
>
> Jednakże okazało się iż tabela ta ma mieć dodatkowe pola zarówno
> informacyjna jak i czasem biorące udział w wyszukiwaniu. Pól będzie
> przybywać i mają być definiowane na bieżąco.


To już coś nie tak jest. Tabelę należy rozbudowywać w dół (czyli o
kolejne wiersze), a nie wszerz!


--
Cezary Grądys
czar...@wa.onet.pl

Marek

unread,
Jan 30, 2015, 5:57:56 PM1/30/15
to
W dniu 2015-01-30 o 22:24, Cezary Grądys pisze:

>
> To już coś nie tak jest. Tabelę należy rozbudowywać w dół (czyli o
> kolejne wiersze), a nie wszerz!
>

Nie bardzo wyobrażam sobie sytuację gdy użytkownik aplikacji zadecyduje
o konieczności dodania "dynamicznej właściwości" do np. powiedzmy tabeli
"dokument", co spowoduje wywołanie akcji:

ALTER TABLE dokument ADD COLUMN coś tam

a gdy stwierdzi, że już mu to pole nie jest potrzebne, to usunie je ze
struktury tabeli. Dawno temu zastosowałem takie rozwiązanie. Jest pewien
problem. Przy dużej ilości danych operacja trwa wieki. Pomijając fakt,
że SQL aplikacji nie powinien zmieniać struktur moim zdaniem.

--
Pozdrawiam,
Marek

Cezary Grądys

unread,
Jan 31, 2015, 2:08:20 AM1/31/15
to
W dniu 30.01.2015 o 23:57, Marek pisze:
Nawet o czymś taki nie myśl, co będzie, jak okaże się, że tabela ma
10000 pól? A jak do tego selecta napisać? Przecież wszystkie zapytania
co używają tej tabeli musiały by być też modyfikowane!
To muszą być 2 (conajmniej) tabele. W jednej masz pole z nazwami i
kluczami, a w drugiej wartości i klucze obce odnoszące się do tej
pierwszej tabeli. Skoro nie wiesz jakie dane, to pewnie pole będzie typu
tekstowego.


--
Cezary Grądys
czar...@wa.onet.pl

M.M.

unread,
Jan 31, 2015, 5:20:54 AM1/31/15
to
On Saturday, January 31, 2015 at 8:08:20 AM UTC+1, Cezary Grądys wrote:
> W dniu 30.01.2015 o 23:57, Marek pisze:
> > W dniu 2015-01-30 o 22:24, Cezary Grądys pisze:
> >
> >>
> >> To już coś nie tak jest. Tabelę należy rozbudowywać w dół (czyli o
> >> kolejne wiersze), a nie wszerz!
> >>
> >
> > Nie bardzo wyobrażam sobie sytuację gdy użytkownik aplikacji zadecyduje
> > o konieczności dodania "dynamicznej właściwości" do np. powiedzmy tabeli
> > "dokument", co spowoduje wywołanie akcji:
> >
> > ALTER TABLE dokument ADD COLUMN coś tam
> >
> > a gdy stwierdzi, że już mu to pole nie jest potrzebne, to usunie je ze
> > struktury tabeli. Dawno temu zastosowałem takie rozwiązanie. Jest pewien
> > problem. Przy dużej ilości danych operacja trwa wieki. Pomijając fakt,
> > że SQL aplikacji nie powinien zmieniać struktur moim zdaniem.
> >
>
> Nawet o czymś taki nie myśl, co będzie, jak okaże się, że tabela ma
> 10000 pól? A jak do tego selecta napisać? Przecież wszystkie zapytania
> co używają tej tabeli musiały by być też modyfikowane!
Jaki problem w zmodyfikowaniu zapytania?

> To muszą być 2 (conajmniej) tabele. W jednej masz pole z nazwami i
> kluczami, a w drugiej wartości i klucze obce odnoszące się do tej
> pierwszej tabeli. Skoro nie wiesz jakie dane, to pewnie pole będzie typu
> tekstowego.
Tak, ale nie zawsze takie rozwiązanie jest dopuszczalne. Ostatnio upakowałem
dodatkowe dane w stringa, bo złączenie z kolejną tabelą za wolno działało.
Jeśli po dodatkowych danych nie ma sortowania, wyszukiwania, filtrowania, to
czasami można pokusić się o upakowanie w stringa.
Pozdrawiam

>
>
> --
> Cezary Grądys
> czar...@wa.onet.pl

Marek

unread,
Jan 31, 2015, 11:00:08 AM1/31/15
to
W dniu 2015-01-31 o 08:08, Cezary Grądys pisze:


>
> Nawet o czymś taki nie myśl, co będzie, jak okaże się, że tabela ma
> 10000 pól? A jak do tego selecta napisać? Przecież wszystkie zapytania
> co używają tej tabeli musiały by być też modyfikowane!

A to akurat żaden problem. Jak wspominałem - stosowałem takie właśnie
rozwiązanie. Działało bez zarzutów. W dodatku miało pewną zaletę
względem tego o czym poniżej rozmawiamy: napiszę o tym na spodzie
komentarzy. Nazwijmy to podejściem #1.

> To muszą być 2 (conajmniej) tabele. W jednej masz pole z nazwami i
> kluczami, a w drugiej wartości i klucze obce odnoszące się do tej
> pierwszej tabeli.

Hmmm... ale po coś stworzono tablice w Postgresie. Raczej nie traktuje
się ich w związku z tym jako naganne podejście. Wydaje mi się (choć mogę
się mylić), że w przypadku pól definiowanych przez użytkownika, to dość
dobre rozwiązanie. Nie trzeba robić żadnych JOINów miedzy tabelami.
Dlatego mnie to sprowokowało do napisania wątku. Jak a jest korzyść z
wielokrotnego łączenia w zapytaniu (niekoniecznie JOINowania) tabel?

Zobacz w czym rzecz. Mamy tabelę z danymi, tabelę z kluczami i tabelę z
wartościami tych kluczy. Gdy chcemy wyszukać dane, które mają "klucz A"
=1 i "klucz B"=2 robimy coś takiego:

SELECT d.* FROM dane d
JOIN wartosci w ON (w.dane_id=d.dane_id AND w.wartosc=1)
JOIN klucze k ON (k.klucze_id=w.klucze_id AND k.nazwa='klucz A')
JOIN wartosci w2 ON (w2.dane_id=d.dane_id AND w2.wartosc=2)
JOIN klucze k2 ON (k2.klucze_id=w2.klucze_id AND k.nazwa='klucz B')

czy jakoś tak. Nazwijmy to podejściem #2. W przypadku gdyby "dane"
zawierały dane tablicowe zapytanie byłoby proste:

SELECT d.* FROM dane
WHERE wartosci[2]=1
AND wartosci[15]=2

Nazwijmy to podejściem #3.

> Skoro nie wiesz jakie dane, to pewnie pole będzie typu
> tekstowego.

No więc właśnie... tu jest pewien problem. Dane mogą być tekstem,
liczbą, datą i sam nie wiem czym jeszcze. W podejściu opisanym na
początku użytkownik powodował iż do tabeli z danymi dopisywane było pole
określonego typu. Mógł powstawać w razie potrzeby indeks do tego pola.
Wyszukiwanie i sortowanie w/g tego pola było wydajne. Uwzględniane były
typy. A w przypadku pól tekstowych trzeba wszystko w locie konwertować
na liczbę czy datę. przed sortowaniem czy wyszukiwaniem. Oczywiście w
podejściu #2 i #3 problem konwersji w locie nadal istnieje.

Pytanie: które jest najwłaściwsze? A może jakiś #4 istnieje?

--
Pozdrawiam,
Marek

artiun

unread,
Jan 31, 2015, 12:44:08 PM1/31/15
to
W dniu 2015-01-31 o 17:00, Marek pisze:
Nie rozumiem w tym ujęciu słowa indeks. Chodzi o faktyczne indeksowanie
pola? Czy o indeks tablicy.
Z drugiej strony to:

> SELECT d.* FROM dane
> WHERE wartosci[2]=1
> AND wartosci[15]=2

musiało by ulegać zmianie wszędzie gdzie takie rozwiązanie byłoby zastosowane.

Chodzi mi o różnicę między indeksacją (tu nie widzę indeksowania tabeli a
tablicy) i filtrowanie.

To text[] można równie dobrze zamienić na substr( text ) i też będzie
dobrze. Definicja pola typu text nie określa jego wielkości, mozna ją
narzucić, bowiem do pola text, nikt Ci nie będzie ładował Pana Tadeusza
skoro oczekiwanych jest 6 znaków. A jeśli nawet, to takie coś "Pan Tadeusz"
trzyma się poza bazą.

Pomysły dobre, jednak tylko dla jednego usera, o b. dobrze określonych
warunkach wstępnych. Co się stanie jeśli [2] czynnik będzie podlegał [3]. Bo
se wymyślił, moze to tylko zamienimy miejscami? :) A tak bywa. Wszystkie
zapytania w oprogramowaniu do przebudowy.

W skrócie mam np takie coś:
t1:
text

t2:
id od do type
1 1 6 int
2 7 12 text
3 13 23 dec
... to samo z tablicą ... zamiast od do (substr)

t3 (to definicja kolejności):
id t2_id
1 2
2 3
3 1

odpytuję t3 o kolejność i z t1, t2 wyciągam wartości z typowaniem zawartym w t2.
Niestety, 2 zapytania t3 malutkie, t1, t2 z filtrem - nie ma indeksów na
tabeli, musiały by zależeć od kolejności w t3.

--
Artur
0 weeks 2 days 21 hours 19 minutes 54 seconds and 752 milliseconds.
"pl.comp.bazy-danych"

Tomek Kańka

unread,
Jan 31, 2015, 5:49:15 PM1/31/15
to
Marek <pr...@spamowi.com> napisał(a)
> Witam,
>
> Na etapie projektu powstała tabela
>
> CREATE TABLE tabela
> (
> tabela_id SERIAL PRIMARY KEY,
>
> pola...
> );
>
> Jednakże okazało się iż tabela ta ma mieć dodatkowe pola zarówno
> informacyjna jak i czasem biorące udział w wyszukiwaniu. Pól będzie
> przybywać i mają być definiowane na bieżąco. Typ nieprzewidywalny -
> niektóre tekstowe, niektóre liczbowe.


IMHO nie powinienieś do tego używać relacyjnej bazy danych. Znajdź coś
co pozwala zapisywać rekordy/dokumenty z dowolnymi polami. W Java
użyłbym np. Lucene albo Apache Jackrabbit (armata!).

--
Tomek

Marek

unread,
Feb 1, 2015, 5:06:43 AM2/1/15
to
W dniu 2015-01-31 o 18:43, artiun pisze:

> Nie rozumiem w tym ujęciu słowa indeks. Chodzi o faktyczne indeksowanie
> pola? Czy o indeks tablicy.

CREATE INDEX

> Z drugiej strony to:
>
> > SELECT d.* FROM dane
> > WHERE wartosci[2]=1
> > AND wartosci[15]=2
>
> musiało by ulegać zmianie wszędzie gdzie takie rozwiązanie byłoby
> zastosowane.

Dlaczego? Jeśli tabela nazwa_do_indexu

CREATE TABLE nazwa_do_indexu
(
nazwa_do_indexu_id PRIMARY KEY,
nazwa varchar(100),
indeks int
);

Będzie miała pary "pole A" => 2, "pole B"=>15 a w dodatku będzie z
cache'owana w PHP w postaci pliku, gwarantując zerowy dostęp do bazy, to
kod składający SQL będzie banalny:

$sql="SELECT d.* FROM dane
WHERE wartosci[".$cache["pole A"]."]=1
AND wartosci[".$cache["pole B"]."]=2";

Takie rzeczy robię na bieżąco i działa świetnie.


> Chodzi mi o różnicę między indeksacją (tu nie widzę indeksowania tabeli
> a tablicy) i filtrowanie.

No właśnie.. nie wiem czy można w najnowszym PostgreSQL (nie mam jak
sprawdzić) czy da się zbudować indeks na polu w tablicy?

CREATE INDEX ... ON .. (wartosc[15]) ?

No i jeszcze dodatkowo z narzuceniem typu bo mozemy zdefiniować iż np
wartosc[14] to int, wartosc[15] to text, a wartosc[16] to np. data.

> To text[] można równie dobrze zamienić na substr( text ) i też będzie
> dobrze. Definicja pola typu text nie określa jego wielkości, mozna ją
> narzucić, bowiem do pola text, nikt Ci nie będzie ładował Pana Tadeusza
> skoro oczekiwanych jest 6 znaków. A jeśli nawet, to takie coś "Pan
> Tadeusz" trzyma się poza bazą.

Nie załapałem intencji. text[] to co innego niż substr(text). Np text o
wartościach {'aaa','bbbbb','ccccccc'} spowoduje, że text[1] da 'bbbbb'.
Nie wyobrażam sobie wydobycia za pomocą substr z łańcucha
'aaabbbbbccccccc' wartości trzech pól "wirtualnych". Jakieś separatory i
splitowanie trzeba by zastosować.

> Pomysły dobre, jednak tylko dla jednego usera, o b. dobrze określonych
> warunkach wstępnych. Co się stanie jeśli [2] czynnik będzie podlegał
> [3]. Bo se wymyślił, moze to tylko zamienimy miejscami? :) A tak bywa.
> Wszystkie zapytania w oprogramowaniu do przebudowy.

Żaden problem. Minimalna praca dla algorytmów budujących SQL. Jednakże
jest to problem wyłącznie hipotetyczny gdyż np. w sklepie internetowym
nikt raczej nie wpadnie aby pole oznaczające do tej pory cenę produktu
nagle miało oznaczać długość sznurowadła w sprzedawanym bucie :-D Można
więc przyjąć, że raz ustalona interpretacja wartości będzie niezmienna,
a jeśli się zmieni, to przy rozsądnym napisaniu aplikacji, nie będzie to
żadnym problemem. Takie rozwiązanie dynamicznego tworzenia referencji do
pól stosuję od lat bez żadnej wpadki jak do tej pory.

> W skrócie mam np takie coś:
> t1:
> text
>
> t2:
> id od do type
> 1 1 6 int
> 2 7 12 text
> 3 13 23 dec
> ... to samo z tablicą ... zamiast od do (substr)
>
> t3 (to definicja kolejności):
> id t2_id
> 1 2
> 2 3
> 3 1
>
> odpytuję t3 o kolejność i z t1, t2 wyciągam wartości z typowaniem
> zawartym w t2.
> Niestety, 2 zapytania t3 malutkie, t1, t2 z filtrem - nie ma indeksów na
> tabeli, musiały by zależeć od kolejności w t3.
>

Coś takiego to masakra byłaby. Trzymanie w jednym polu wielu "pól
wirtualnych", definiowanie, że od bajtu A do B to jedna wartość, od B do
C to druga itd i trzymanie tego w innych tabelach praktycznie torpeduje
możliwość sortowania i wyszukiwania. Oprogramowanie takiej konstrukcji
byłoby nie lada wyzwaniem bez sensu skomplikowanym. Dużo łatwiej zapisać
ORDER BY tablica[15] niż za pomocą substr.

--
Pozdrawiam,
Marek

Marek

unread,
Feb 1, 2015, 5:20:40 AM2/1/15
to
W dniu 2015-01-31 o 23:49, Tomek Kańka pisze:

>
> IMHO nie powinienieś do tego używać relacyjnej bazy danych. Znajdź coś
> co pozwala zapisywać rekordy/dokumenty z dowolnymi polami. W Java
> użyłbym np. Lucene albo Apache Jackrabbit (armata!).

Hmm... jak pobieżnie się zorientowałem (bo to z tego co widzę spora
maszyna), to chodzi o programowe tworzenie struktur i przechowywanie ich
np. w jednym polu bazy danych czy pliku na dysku? Czy nie jest to armata
na wróble i to pracująca w oderwaniu od bazy danych?

Bazując na PHP to żaden problem bez stosowania takich wyrafinowanych
dodatków. Wystarczy zastosować XML. Banalna nawigacja, dodawanie pól
jakie tylko chcesz itp operacje. Bez problemu koduje się to i dekoduje
jako string do przechowania w bazie.

Jednakże kłopot jest w tym, że w ten sposób tworzymy wyłącznie dane do
odczytu. Sortowanie, wyszukiwanie po tak uwikłanych danych nie jest
możliwe z poziomu SQL. Nie jestem specem od baz danych ale chyba powinno
istnieć jakieś podejście koncepcyjne umożliwiające nieograniczone
rozszerzanie ilości pól tabeli w trakcie pracy aplikacji? Nie mówię o
fizycznych polach, mogą to być albo jakieś struktury np 2,3 tabel lub
tablice[] albo jeszcze inne podejście.

--
Pozdrawiam,
Marek

Tomek Kańka

unread,
Feb 1, 2015, 5:50:27 AM2/1/15
to
Marek <pr...@spamowi.com> napisał(a)
> W dniu 2015-01-31 o 23:49, Tomek Kańka pisze:
>
>>
>> IMHO nie powinienieś do tego używać relacyjnej bazy danych. Znajdź coś
>> co pozwala zapisywać rekordy/dokumenty z dowolnymi polami. W Java
>> użyłbym np. Lucene albo Apache Jackrabbit (armata!).
>[ciach]


Jeszcze raz, bo nie zrozumiałem Twojego posta.

Moja propozycja jest taka: jeśli nie masz z góry ustalonej struktury
danych, to nie powinieneś używać do tego relacyjnej bazy danych. Co za
tym idzie, nie będziesz używał również SQLa.

Zaproponowałem Lucene, które znam i Jackabbita, który wiem, że istnieje
i że jest ogromnym kombajnem do przechowywania treści, oferującym
wyszukiwanie, sortowanie, wersjonowanie, replikację i pewnie mnóstwo innych
features, o których nigdy nie myślałem.


W świecie PHP masz np. MongoDB
MongoDB (from "humongous") is an open-source document database, and the
leading NoSQL database.

Możesz oczywiście stworzyć też własne rozwiązanie oparte np. o XML-e,
albo o tabelę w bazie danych typu (doc_id, property_name,
property_value) itd.

Jeśli źle zrozumiełem problem, to przepraszam za zawracnie głowy.

--
Tomek

Marek

unread,
Feb 1, 2015, 6:49:36 AM2/1/15
to
W dniu 2015-02-01 o 11:50, Tomek Kańka pisze:

> Jeszcze raz, bo nie zrozumiałem Twojego posta.

Nie nie - dobrze zrozumiałeś jednakże za bardzo to uprościłeś. Za każdy
komentarz jestem wdzięczny bo jest dla mnie cenny. Baza danych jest
ogromna - ponad 100 tabel. Chodzi teraz o dobudowanie funkcjonalności
polegającej na dynamicznym rozszerzeniu ilości pól w jednej z tych
tabel. Dynamicznym = na żądanie redaktorów treści systemu CMS. C.d.
poniżej.

> Moja propozycja jest taka: jeśli nie masz z góry ustalonej struktury
> danych, to nie powinieneś używać do tego relacyjnej bazy danych. Co za
> tym idzie, nie będziesz używał również SQLa.

Nie wchodzi w grę abym rezygnował teraz z bazy danych, megabajtów kodu
aby teraz przejść na rozwiązanie plikowe, które nie ma szans dorównać
wydajnością bazom danych. Ilość pól w bazach da się zwiększać w tabelach
np. za pomocą tablic, dziedziczenia tabel, dodając na chama nowe pola do
istniejącej tabeli lub stosując dodatkowe, wspomagające tabele. Technik
jest kilka i szukam najlepszego podejścia bazując na Waszych
doświadczeniach.

Jak już sugerowałeś (i nie tylko Ty) rozbudowywanie tabeli wszerz nie
jest dobrym pomysłem. Jednakże w zamian nie ma póki co dobrego wyjścia z
sytuacji. Trudno mi się pogodzić z rozwiązaniami typu:
a) tego się nie da w ogóle zrobić
b) zrezygnuj z baz danych

--
Pozdrawiam,
Marek

nk...@toya.net.pl

unread,
Feb 3, 2015, 4:44:58 AM2/3/15
to
Wolałbym bardziej praktyczny opis problemu np:

masz tablę t1

id p1 p2
-------------
1 a111 a222
2 b111 b222
3 c111 c222


i teraz chcesz aby do tej t1 user sobie utowrzył dowolną kombinację indeksów
do pól np:

szukaj p2+p1
szukaj p1+p2

o to chodzi?

Czy może user tworzy sobie własne pole p3, dodaje tam dane
i teraz musi być możliwość dowolnego zaindeksowania pól t1 włącznie
z dodanym polem p3 i oczywiście możliwość szukania danych wykorzystując utworzone przez usera dowolne kombinacje indeksacji pól w t1?

Andrzej.

Marek

unread,
Feb 3, 2015, 5:50:54 PM2/3/15
to
W dniu 2015-02-03 o 10:44, nk...@toya.net.pl pisze:


> Czy może user tworzy sobie własne pole p3, dodaje tam dane
> i teraz musi być możliwość dowolnego zaindeksowania pól t1 włącznie
> z dodanym polem p3 i oczywiście możliwość szukania danych wykorzystując utworzone przez usera dowolne kombinacje indeksacji pól w t1?

Dokładnie o to mi chodziło :-)

Najprościej byłoby dodać pole p3 w trakcie działania aplikacji ale to
nie jest "bazodanowe" podejście. Zakłada się zazwyczaj, że tabela ma
mieć N pól, a jeśli trzeba N+1 to programista musi to oprogramować. Jest
to spore ograniczenie, które chciałbym w możliwie elegancki sposób
obejść. Chciałbym tak napisać aplikację aby użytkownik sam sobie dodawał
co mu potrzebne.

--
Pozdrawiam,
Marek

nk...@toya.net.pl

unread,
Feb 4, 2015, 4:46:30 AM2/4/15
to
Takie podejście jest amatorskie aczkolwiek możliwe
do zrealizowania, ale pomyśl - dla każdego usera jego
prywatny indeks na serwerze, do tego jeszcze niezliczona
ilość wziętych z księżyca pól.




W php klucz indeksowy możesz włożyć do zmiennej:

$MyKey="(p2,p3,p1)";
mysql_query("CREATE INDEX nowy_index ON tabela $MyKey");




Andrzej.

artiun

unread,
Feb 4, 2015, 1:11:13 PM2/4/15
to
W dniu 2015-02-04 o 10:46, nk...@toya.net.pl pisze:
Nie macie pojęcia, albo mylicie coś. Indeks jest zakładany na bazie
administracyjnie, to o czym mówicie to filtry. Ktoś zaproponował podejście
tekstowe, tu też można zrobić indeksy (swego czasu rozwinęło się to w DBF -
stare jak i historia baz). Ma to sens (np. xml - ale nie na GB danych)

--
Artur
0 weeks 1 day 13 hours 57 minutes 42 seconds and 16 milliseconds.
"pl.comp.bazy-danych"

nk...@toya.net.pl

unread,
Feb 5, 2015, 4:38:16 AM2/5/15
to
W dniu środa, 4 lutego 2015 19:11:13 UTC+1 użytkownik artiun napisał:

> Nie macie pojęcia, albo mylicie coś. Indeks jest zakładany na bazie
> administracyjnie, to o czym mówicie to filtry. Ktoś zaproponował podejście
> tekstowe, tu też można zrobić indeksy (swego czasu rozwinęło się to w DBF -
> stare jak i historia baz).

Chłopak się uczy i chce jak najwięcej poznać więc podsuwam mu
rozwiązanie.
Prędzej czy później i tak dojdzie do wniosku, że to pomyłka.

Sam z przyzwyczajenia stosuję indeksy mimo, że wystarczyłoby
zwykłe filtrowanie.

> Ma to sens (np. xml - ale nie na GB danych)
>

Według mnie właśnie na GB danych ma sens stosowanie indeksów
oczywiście ich odświeżanie przy insertach/apdejtach jest
czasochłonne ale przy szukaniu są naprawdę błyskawiczne.

A dżojna robiłeś bez indeksów?

Andrzej.

M.M.

unread,
Feb 5, 2015, 8:18:15 AM2/5/15
to
On Sunday, February 1, 2015 at 11:20:40 AM UTC+1, Marek wrote:
> Hmm... jak pobieżnie się zorientowałem (bo to z tego co widzę spora
> maszyna), to chodzi o programowe tworzenie struktur i przechowywanie ich
> np. w jednym polu bazy danych czy pliku na dysku? Czy nie jest to armata
> na wróble i to pracująca w oderwaniu od bazy danych?
Nie wierzę w wydajność tych rozwiązań.


> Bazując na PHP to żaden problem bez stosowania takich wyrafinowanych
> dodatków. Wystarczy zastosować XML. Banalna nawigacja, dodawanie pól
> jakie tylko chcesz itp operacje. Bez problemu koduje się to i dekoduje
> jako string do przechowania w bazie.
Jeśli tylko php, to chyba lepiej serializowanie zmiennych?


> Jednakże kłopot jest w tym, że w ten sposób tworzymy wyłącznie dane do
> odczytu. Sortowanie, wyszukiwanie po tak uwikłanych danych nie jest
> możliwe z poziomu SQL.
Niestety, to spory problem. Czasami pomaga przygotowanie osobnych
zbiorów danych na każdą okoliczność.

> Nie jestem specem od baz danych ale chyba powinno
> istnieć jakieś podejście koncepcyjne umożliwiające nieograniczone
> rozszerzanie ilości pól tabeli w trakcie pracy aplikacji? Nie mówię o
> fizycznych polach, mogą to być albo jakieś struktury np 2,3 tabel lub
> tablice[] albo jeszcze inne podejście.

Odpowiedzieli Ci już. Jest kilka sposobów.
1) Robisz dodatkową tabelę (klucz_obcy,pole,wartosc)
2) Tablice
3) Zwyczajnie dodajesz kolumnę do tabeli
4) Dodajesz jedną tabelę na jedno pole (klucz_obcy,wartosc)
5) Zapisujesz xmla na dysku, a w rekordzie zapamiętujesz ścieżkę.
6) Dane upakowujesz do stringa, itd.


Marek

unread,
Feb 5, 2015, 9:35:31 AM2/5/15
to
W dniu 2015-02-05 o 14:18, M.M. pisze:

> On Sunday, February 1, 2015 at 11:20:40 AM UTC+1, Marek wrote:
>> Hmm... jak pobieżnie się zorientowałem (bo to z tego co widzę spora
>> maszyna), to chodzi o programowe tworzenie struktur i przechowywanie ich
>> np. w jednym polu bazy danych czy pliku na dysku? Czy nie jest to armata
>> na wróble i to pracująca w oderwaniu od bazy danych?
> Nie wierzę w wydajność tych rozwiązań.

No ale nie wiem za bardzo, o których rozmawiamy: czy o rozwiązaniach
bazodanowych czy o plikowych.

>> Bazując na PHP to żaden problem bez stosowania takich wyrafinowanych
>> dodatków. Wystarczy zastosować XML. Banalna nawigacja, dodawanie pól
>> jakie tylko chcesz itp operacje. Bez problemu koduje się to i dekoduje
>> jako string do przechowania w bazie.
> Jeśli tylko php, to chyba lepiej serializowanie zmiennych?

Niekoniecznie. Trawersowanie danych jest łatwiejsze w XML (Xpath). A po
drugie nie wiem czy zaraz nie przyda się to dla JS. Lepiej stosować
bardziej uniwersalny format niż potem głową w mur walić :-)

>> Jednakże kłopot jest w tym, że w ten sposób tworzymy wyłącznie dane do
>> odczytu. Sortowanie, wyszukiwanie po tak uwikłanych danych nie jest
>> możliwe z poziomu SQL.
> Niestety, to spory problem. Czasami pomaga przygotowanie osobnych
> zbiorów danych na każdą okoliczność.

Hmmm.. w zasadzie racja. Przemyślę to.

> Odpowiedzieli Ci już. Jest kilka sposobów.
> 1) Robisz dodatkową tabelę (klucz_obcy,pole,wartosc)

Sęk w tym, że wtedy wyszukiwanie po kilku polach bardzo rozbudowuje sql.
Pojawiają się wielokrotne JOINy. Odczyt takich "dodatkowych" pól wymaga
odrębnego zapytania sql. Sortowanie po takich polach to też wyzwanie.

> 2) Tablice

Czyli moja propozycja z wątku otwierającego... Chyba na to się zdecyduję
mimo iż będzie potrzebne rzutowanie typów przy wyszukiwaniu /
sortowaniu. Ale zastanawiam się nad dublowaniu danych (zgodnie z Twoją
sugestią). Np. przechowujemy je zarówno w tablicy jak i w strukturze #1.
Plpgsql pilnowałby synchronizacji wartości i ilości pól. Indeks pozycji
w tablicy mógłby odpowiadać kluczowi głównemu pola z tabeli dostępnych pól.

> 3) Zwyczajnie dodajesz kolumnę do tabeli

Czyli nie przejmować się zasadami tworzenia baz danych i pozwolić
aplikacji na modyfikowanie struktury tabeli?



--
Pozdrawiam,
Marek

Marek

unread,
Feb 5, 2015, 9:42:09 AM2/5/15
to
W dniu 2015-02-04 o 10:46, nk...@toya.net.pl pisze:

> Takie podejście jest amatorskie aczkolwiek możliwe
> do zrealizowania,

No więc właśnie. Jednakże przy braku "profesjonalnej" opcji trzeba sobie
jakoś radzić. Takie podejście gwarantuje optymalną wydajność i łatwość
dostępu do tych danych bo
1. Zakładasz pola o takich typach jakich potrzebujesz.
2. Możesz budować indeksy do nich w razie potrzeb, JOINować etc
3. Wszystkie pola są w jednej tabeli więc dostępne w SELECT * bez
skomplikowanych zapytań.

> ale pomyśl - dla każdego usera jego
> prywatny indeks na serwerze, do tego jeszcze niezliczona
> ilość wziętych z księżyca pól.

Nie, ilość userów nie ma tu znaczenia. Sprawa się upraszcza. Jeśli jeden
z nich doda pole ceny artykułu w sklepie internetowym, to pozostali będą
mieli je dostępne i będą mogli wypełniać wartościami dla poszczególnych
produktów.


--
Pozdrawiam,
Marek

M.M.

unread,
Feb 5, 2015, 1:50:28 PM2/5/15
to
On Thursday, February 5, 2015 at 3:35:31 PM UTC+1, Marek wrote:
> W dniu 2015-02-05 o 14:18, M.M. pisze:
>
> > On Sunday, February 1, 2015 at 11:20:40 AM UTC+1, Marek wrote:
> >> Hmm... jak pobieżnie się zorientowałem (bo to z tego co widzę spora
> >> maszyna), to chodzi o programowe tworzenie struktur i przechowywanie ich
> >> np. w jednym polu bazy danych czy pliku na dysku? Czy nie jest to armata
> >> na wróble i to pracująca w oderwaniu od bazy danych?
> > Nie wierzę w wydajność tych rozwiązań.
>
> No ale nie wiem za bardzo, o których rozmawiamy: czy o rozwiązaniach
> bazodanowych czy o plikowych.
>
> >> Bazując na PHP to żaden problem bez stosowania takich wyrafinowanych
> >> dodatków. Wystarczy zastosować XML. Banalna nawigacja, dodawanie pól
> >> jakie tylko chcesz itp operacje. Bez problemu koduje się to i dekoduje
> >> jako string do przechowania w bazie.
> > Jeśli tylko php, to chyba lepiej serializowanie zmiennych?
>
> Niekoniecznie. Trawersowanie danych jest łatwiejsze w XML (Xpath). A po
> drugie nie wiem czy zaraz nie przyda się to dla JS. Lepiej stosować
> bardziej uniwersalny format niż potem głową w mur walić :-)
W dzisiejszych czasach zamiana małego xmla na zmienną php to
'jedna instrukcja' - w sumie nie ma o czym dyskutować :)

>
> >> Jednakże kłopot jest w tym, że w ten sposób tworzymy wyłącznie dane do
> >> odczytu. Sortowanie, wyszukiwanie po tak uwikłanych danych nie jest
> >> możliwe z poziomu SQL.
> > Niestety, to spory problem. Czasami pomaga przygotowanie osobnych
> > zbiorów danych na każdą okoliczność.
>
> Hmmm.. w zasadzie racja. Przemyślę to.
Warto zwrócić uwagę na problemy przy późniejszej rozbudowie
aplikacji o nieprzewidziane cechy.

>
> > Odpowiedzieli Ci już. Jest kilka sposobów.
> > 1) Robisz dodatkową tabelę (klucz_obcy,pole,wartosc)
>
> Sęk w tym, że wtedy wyszukiwanie po kilku polach bardzo rozbudowuje sql.
> Pojawiają się wielokrotne JOINy. Odczyt takich "dodatkowych" pól wymaga
> odrębnego zapytania sql. Sortowanie po takich polach to też wyzwanie.
Znowu nie aż tak rozbuduje...
select main.*, (select value from other where id_main=main.id and type='dodatkowe_1), etc.


>
> > 2) Tablice
>
> Czyli moja propozycja z wątku otwierającego... Chyba na to się zdecyduję
> mimo iż będzie potrzebne rzutowanie typów przy wyszukiwaniu /
> sortowaniu. Ale zastanawiam się nad dublowaniu danych (zgodnie z Twoją
> sugestią). Np. przechowujemy je zarówno w tablicy jak i w strukturze #1.
> Plpgsql pilnowałby synchronizacji wartości i ilości pól. Indeks pozycji
> w tablicy mógłby odpowiadać kluczowi głównemu pola z tabeli dostępnych pól.
Szczerze nie mam za dużego doświadczenia z tablicami, mój framework nie
wspomaga ich :)


> > 3) Zwyczajnie dodajesz kolumnę do tabeli
>
> Czyli nie przejmować się zasadami tworzenia baz danych i pozwolić
> aplikacji na modyfikowanie struktury tabeli?
Dlaczego nie?


Pozdrawiam

R.e.m.e.K

unread,
Feb 5, 2015, 2:09:16 PM2/5/15
to
Dnia Thu, 5 Feb 2015 10:50:26 -0800 (PST), M.M. napisał(a):

>> Sęk w tym, że wtedy wyszukiwanie po kilku polach bardzo rozbudowuje sql.
>> Pojawiają się wielokrotne JOINy. Odczyt takich "dodatkowych" pól wymaga
>> odrębnego zapytania sql. Sortowanie po takich polach to też wyzwanie.
> Znowu nie aż tak rozbuduje...
> select main.*, (select value from other where id_main=main.id and type='dodatkowe_1), etc.

Brawo, swietna porada. Takie rady to tzw. niedzwiedzia przysluga.

--
pozdro
R.e.m.e.K

M.M.

unread,
Feb 5, 2015, 3:51:02 PM2/5/15
to
Myślał że to była porada...

nk...@toya.net.pl

unread,
Feb 6, 2015, 3:44:14 AM2/6/15
to
W dniu czwartek, 5 lutego 2015 15:42:09 UTC+1 użytkownik Marek napisał:
> W dniu 2015-02-04 o 10:46, nk...@toya.net.pl pisze:

> > ale pomyśl - dla każdego usera jego
> > prywatny indeks na serwerze, do tego jeszcze niezliczona
> > ilość wziętych z księżyca pól.
>
> Nie, ilość userów nie ma tu znaczenia. Sprawa się upraszcza. Jeśli jeden
> z nich doda pole ceny artykułu w sklepie internetowym, to pozostali będą
> mieli je dostępne i będą mogli wypełniać wartościami dla poszczególnych
> produktów.
>

No tak ale po dodaniu pola cena, którego jeszcze nie było
trzeba utworzyć indeks, czyli do każdego pola plik indeksowy?

Ja lubię konkrety.

Tu na grupie już była dyskusja na ten temat i moja sugestia
była taka aby utworzyć tradycyjnie tabele hierarchiczne grupujące
treść od ogółu do szczegółu (komputery:piecyki/laptopy/tablety...)
a w każdej wielkie pole na cechy/właściwości, w którym zastosować
zapis typu JSON jak w CSS: cecha=wartość,
czyli: "cena=123; color=czerwony kształt=wykrzywiony itd"
(tu skrypt musi to w każdym polu ustawiać cechy w tej samej kolejności,
każda nowa cecha dopisywana na końcu [co z literówkami]).

Radzę sprawdzać w testach czy będą używane indeksy.
Z dużym prawdopodobieństwem nie będą.

Andrzej.

nk...@toya.net.pl

unread,
Feb 6, 2015, 3:49:57 AM2/6/15
to
Zapomniałem o jeszcze czymś ważnym.

Czy zdajesz sobie sprawę jakie chamstwo
grasuje w internecie?

Andrzej.

Marek

unread,
Feb 6, 2015, 5:39:48 AM2/6/15
to
W dniu 2015-02-05 o 19:50, M.M. pisze:

> Znowu nie aż tak rozbuduje...
> select main.*, (select value from other where id_main=main.id and type='dodatkowe_1), etc.

No chyba to nie takie proste jak napisałeś :-)

>> Czyli nie przejmować się zasadami tworzenia baz danych i pozwolić
>> aplikacji na modyfikowanie struktury tabeli?
> Dlaczego nie?

Np. dlatego, że Cezary mnie za takie pomysły obsobaczył :-D (pierwsza
odpowiedź w wątku)

--
Pozdrawiam,
Marek

Marek

unread,
Feb 6, 2015, 5:41:55 AM2/6/15
to
W dniu 2015-02-06 o 09:49, nk...@toya.net.pl pisze:
> Zapomniałem o jeszcze czymś ważnym.
>
> Czy zdajesz sobie sprawę jakie chamstwo
> grasuje w internecie?

Masz na myśli, że ktoś złośliwie będzie dodawał pola? To akurat nie ma
znaczenia również gdyż mowa jest o części redakcyjnej CMS. Sporadycznie
będą powstawać nowe właściwości.


--
Pozdrawiam,
Marek

Marek

unread,
Feb 6, 2015, 5:50:49 AM2/6/15
to
W dniu 2015-02-06 o 09:44, nk...@toya.net.pl pisze:

>
> No tak ale po dodaniu pola cena, którego jeszcze nie było
> trzeba utworzyć indeks, czyli do każdego pola plik indeksowy?

Nie, tylko do tych pól, przy których tworzeniu kliknie się opcję "utwórz
indeks" albo drugi scenariusz: jeśli dane pole ma być kluczem obcym do
innej tabeli, to aplikacja sama wymusi utworzenie indeksu. To żaden problem.

> Tu na grupie już była dyskusja na ten temat i moja sugestia
> była taka aby utworzyć tradycyjnie tabele hierarchiczne grupujące
> treść od ogółu do szczegółu (komputery:piecyki/laptopy/tablety...)
> a w każdej wielkie pole na cechy/właściwości, w którym zastosować
> zapis typu JSON jak w CSS: cecha=wartość,
> czyli: "cena=123; color=czerwony kształt=wykrzywiony itd"
> (tu skrypt musi to w każdym polu ustawiać cechy w tej samej kolejności,
> każda nowa cecha dopisywana na końcu [co z literówkami]).
>
> Radzę sprawdzać w testach czy będą używane indeksy.
> Z dużym prawdopodobieństwem nie będą.

Z praktyki wiem, że będą. Np. zdarzyło się iż klient zażyczył sobie w
trakcie działania aplikacji dorobienia powiązania karty katalogowej
produktu z instrukcją obsługi (która nie zawsze istniała). I kilka
podobnych przypadków. Wcale to nie takie rzadkie sytuacje. Tak więc
notacja a'la JSON raczej nie wchodzi w grę.

--
Pozdrawiam,
Marek

M.M.

unread,
Feb 6, 2015, 6:05:33 AM2/6/15
to
On Friday, February 6, 2015 at 11:39:48 AM UTC+1, Marek wrote:
> W dniu 2015-02-05 o 19:50, M.M. pisze:
>
> > Znowu nie aż tak rozbuduje...
> > select main.*, (select value from other where id_main=main.id and type='dodatkowe_1), etc.
>
> No chyba to nie takie proste jak napisałeś :-)
Przepraszam, ale nie widzę tutaj nic bardziej skomplikowanego - w takim
sensie od jakiego zaczęliśmy rozmowę, czyli "wyszukiwanie po kilku
polach bardzo rozbudowuje sql. " Kilka pól, to kilka podzapytań w
klauzuli select.

>
> >> Czyli nie przejmować się zasadami tworzenia baz danych i pozwolić
> >> aplikacji na modyfikowanie struktury tabeli?
> > Dlaczego nie?
> Np. dlatego, że Cezary mnie za takie pomysły obsobaczył :-D (pierwsza
> odpowiedź w wątku)
Nie reguły bez wyjątku, pomimo że generalnie się zgadzam z Cezarym.



>
> --
> Pozdrawiam,
> Marek

Marek

unread,
Feb 6, 2015, 8:37:49 AM2/6/15
to
W dniu 2015-02-06 o 12:05, M.M. pisze:

>> No chyba to nie takie proste jak napisałeś :-)
> Przepraszam, ale nie widzę tutaj nic bardziej skomplikowanego - w takim
> sensie od jakiego zaczęliśmy rozmowę, czyli "wyszukiwanie po kilku
> polach bardzo rozbudowuje sql. " Kilka pól, to kilka podzapytań w
> klauzuli select.

Wydaje mi się, że wyszukiwanie, że jeśli w jednej tabeli przechowujemy
nazwy pól a w drugiej wartości skojarzone z nazwą pola i powiedzmy
"dokumentem", to wyszukiwanie po "poleA"="aaa" i "poleB"="bbb" będzie
wyglądało tak:

SELECT *
FROM dokument d
JOIN wartosci_pol wp ON (wp.dokument_id=d.dokument_id)
JOIN nazwy_pol np ON (np.nazwy_pol_id=wp.nazwy_pol_id AND np.nick='poleA')
JOIN wartosci_pol wp2 ON (wp2.dokument_id=d.dokument_id)
JOIN nazwy_pol np2 ON (np2.nazwy_pol_id=wp2.nazwy_pol_id AND
np2.nick='poleB')
WHERE wp.value='aaa' AND wp2.value='bbb'

Oczywiście można użyć zamiast JOINów, SELECtów w sekcji WHERE. A teraz
wersja zapytania w opcji gdyby aplikacja dodawała pola dodatkowe
bezpośrednio do tabeli dokument (czyli rozwiązanie "amatorskie" jak to
skomentowano):

SELECT *
FROM dokument d
WHERE poleA='aaa' AND poleB='bbb'

Listowanie pól tu też jest banalne:

SELECT poleA, poleB FROM dokument

No i można decydować o typach pół i budować indeksy dla nich gdy trzeba.

Jest dużo prościej, prawda? To właśnie nazywam mocno rozbudowanym SQLem.
Tworzenie takich zapytań jest dość kłopotliwe, oczywiście można to
zrealizować. Waham się nad tym, która z metod jest lepsza. No i jeszcze
niegłębiony przeze mnie temat tablic. One byłyby najlepsze ale pewnie
nie da się na nich indeksów budować.


>> Np. dlatego, że Cezary mnie za takie pomysły obsobaczył :-D (pierwsza
>> odpowiedź w wątku)
> Nie reguły bez wyjątku, pomimo że generalnie się zgadzam z Cezarym.

Czyli reasumując, stawiasz na dynamiczne dodawanie/usuwanie pól do/z tabel?

--
Pozdrawiam,
Marek

M.M.

unread,
Feb 6, 2015, 1:05:12 PM2/6/15
to
On Friday, February 6, 2015 at 2:37:49 PM UTC+1, Marek wrote:
> Wydaje mi się, że wyszukiwanie, że jeśli w jednej tabeli przechowujemy
> [...]
> Czyli reasumując, stawiasz na dynamiczne dodawanie/usuwanie pól do/z tabel?

Raczej pytam niż stawiam. Dlaczego nie tak?

CREATE TABLE main (
id integer,
value character varying
);

CREATE TABLE fields (
id_main integer,
type character varying,
value character varying
);


select m.*, (select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa') from main as m where m.value='bbb';


Marek

unread,
Feb 6, 2015, 2:03:35 PM2/6/15
to
W dniu 2015-02-06 o 19:05, M.M. pisze:

> Raczej pytam niż stawiam. Dlaczego nie tak?
>
> CREATE TABLE main (
> id integer,
> value character varying
> );
>
> CREATE TABLE fields (
> id_main integer,
> type character varying,
> value character varying
> );
>
>
> select m.*, (select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa') from main as m where m.value='bbb';

Hmm... w zasadzie jest to jakaś myśl. Czyli tabela z dostępnymi nazwami
pól pełniła by funkcję pomocniczą i nie byłaby powiązana z "fields"...
Zastanawiam się czy to coś usprawni. Zamiast type lepiej trzymać ID z
innej tabeli. Usuwanie zmiennej z tej "innej" tabeli pociągnie wtedy
reakcję łańcuchową - automatycznie usunie wartości kasowanej zmiennej.
Ale z drugiej strony można to obejść jakąś funkcją w plpgsql...
Zastanowię się.

W międzyczasie wyczytałem, że w PostgreSQL 9.2+ można budować indeksy na
poszczególnych komórkach tablic. Co więcej - klucze obce także. Choć
jestem ostrożny z takimi nowinkami. Jednakże to też mamy do
wykorzystania potencjalnie.


--
Pozdrawiam,
Marek

M.M.

unread,
Feb 6, 2015, 5:05:52 PM2/6/15
to
On Friday, February 6, 2015 at 8:03:35 PM UTC+1, Marek wrote:
> W dniu 2015-02-06 o 19:05, M.M. pisze:
>
> > Raczej pytam niż stawiam. Dlaczego nie tak?
> >
> > CREATE TABLE main (
> > id integer,
> > value character varying
> > );
> >
> > CREATE TABLE fields (
> > id_main integer,
> > type character varying,
> > value character varying
> > );
> >
> >
> > select m.*, (select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa') from main as m where m.value='bbb';
>
> Hmm... w zasadzie jest to jakaś myśl. Czyli tabela z dostępnymi nazwami
> pól pełniła by funkcję pomocniczą i nie byłaby powiązana z "fields"...
Nie wiem co masz na myśli, moim zdaniem jest powiązana, ponieważ ma
klucz obcy (pomimo że w definicjach tabel tego formalnie nie zrobiłem)

> Zastanawiam się czy to coś usprawni. Zamiast type lepiej trzymać ID z
> innej tabeli.
Może enum wystarczy.

> Usuwanie zmiennej z tej "innej" tabeli pociągnie wtedy
> reakcję łańcuchową - automatycznie usunie wartości kasowanej zmiennej.
Albo wywali błąd, zależy jak usuwać.


> Ale z drugiej strony można to obejść jakąś funkcją w plpgsql...
> Zastanowię się.


> W międzyczasie wyczytałem, że w PostgreSQL 9.2+ można budować indeksy na
> poszczególnych komórkach tablic. Co więcej - klucze obce także.
Miło z jego strony.

> Choć
> jestem ostrożny z takimi nowinkami. Jednakże to też mamy do
> wykorzystania potencjalnie.
To jedna ostrożność. Druga tyczy się wydajności. Ile przyspieszą te indeksy?
Aplikacja zoptymalizowana w C++, która dane trzyma w RAM, może być
szybsza np. 10tys razy niż PHP+SQL.

Pozdrawiam

wloochacz

unread,
Feb 7, 2015, 5:24:17 AM2/7/15
to
W dniu 2015-02-06 o 19:05, M.M. pisze:
> On Friday, February 6, 2015 at 2:37:49 PM UTC+1, Marek wrote:
>> Wydaje mi się, że wyszukiwanie, że jeśli w jednej tabeli przechowujemy
>> [...]
>> Czyli reasumując, stawiasz na dynamiczne dodawanie/usuwanie pól do/z tabel?
>
> Raczej pytam niż stawiam. Dlaczego nie tak?
>
> CREATE TABLE main (
> id integer,
> value character varying
> );
>
> CREATE TABLE fields (
> id_main integer,
> type character varying,
> value character varying
> );
Może być i tak, ale pobieranie danych (czyli select poniżej) jest
zrobione fatalnie...

> select m.*, (select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa') from main as m where m.value='bbb';
Zdajesz sobie sprawę, że zapytanie pobierające wartość pola "dodatkowego":
select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa'

Wykona się dla każdego wiersza? Za każdym razem. No to dołóż sobie
takich pól dodatkowych kilka, albo kilkanaście i będziesz miał "super"
wydajne rozwiązanie...

To samo da się napisać za pomocą złączeń i będzie wielokrotnie bardziej
wydajne.

--
wloochacz

M.M.

unread,
Feb 7, 2015, 7:31:52 AM2/7/15
to
On Saturday, February 7, 2015 at 11:24:17 AM UTC+1, wloochacz wrote:
> W dniu 2015-02-06 o 19:05, M.M. pisze:
> > On Friday, February 6, 2015 at 2:37:49 PM UTC+1, Marek wrote:
> >> Wydaje mi się, że wyszukiwanie, że jeśli w jednej tabeli przechowujemy
> >> [...]
> >> Czyli reasumując, stawiasz na dynamiczne dodawanie/usuwanie pól do/z tabel?
> >
> > Raczej pytam niż stawiam. Dlaczego nie tak?
> >
> > CREATE TABLE main (
> > id integer,
> > value character varying
> > );
> >
> > CREATE TABLE fields (
> > id_main integer,
> > type character varying,
> > value character varying
> > );
> Może być i tak, ale pobieranie danych (czyli select poniżej) jest
> zrobione fatalnie...
>
> > select m.*, (select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa') from main as m where m.value='bbb';
> Zdajesz sobie sprawę, że zapytanie pobierające wartość pola "dodatkowego":
> select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa'
> Wykona się dla każdego wiersza? Za każdym razem.
Nie zdaję sobie sprawy, ponieważ nie będzie wykonane dla każdego -
przeanalizuj jeszcze raz zapytanie. Ale generalnie, w podobnych
przypadkach, zgadzam się z Tobą, pobudki masz słuszne, kiedyś w jakiejś
bazie tak samo się obawiałem. Postanowiłem w niej sprawdzić. Czas na
pod-zapytaniach w klauzuli select był wyraźnie krótszy. Nie umiem tego
wytłumaczyć, strzelam, że optymalizator dobrze zadziałał.


> No to dołóż sobie
> takich pól dodatkowych kilka, albo kilkanaście i będziesz miał "super"
> wydajne rozwiązanie...
>
> To samo da się napisać za pomocą złączeń i będzie wielokrotnie bardziej
> wydajne.
Piszesz jakbyś bardzo szczegółowo rozumiał jak dzialają optymalizatory.
Możesz napisać coś więcej na ten temat?

Pozdrawiam

M.M.

unread,
Feb 7, 2015, 1:59:25 PM2/7/15
to
On Saturday, February 7, 2015 at 1:31:52 PM UTC+1, M.M. wrote:
> [...]
Właśnie sprawdziłem na pewnej bazie...

Tabela glowna1 ma 100tys rekordów.
Tabela glowna2 jest w relacji 1 do 1 z glowna1.
Tabela table1 ma ponad 20mln.
Pozostałe tabele są bardzo małe.

Zapytanie zamieszczam na dole - niezła sieczka, wiele podzapytań. Czas
wykonania to zaledwie od 10 do 60 sekund - zależy jak baza jest cachowana.
Na dobrym sprzęcie i na dużym buforze pewnie to by trwało z 2 sekundy.

Nie tylko wybieram pola z table1, ale jeszcze z nich wybieram ostatnie, a
potem z ostatnich jeszcze liczę średnią. I tak 3 razy, dla kategorii A, B i C.


select
* ,

(select
avg(value)
from (
select (
select
t1.value
from
table1 as t1
where
t1.id_t3 = t3.id order by t1.date desc limit 1
)
from
table2 as t2
join
table3 as t3
on
t2.id = t3.id_t2
join
table4 as t4
on
t4.id = t3.id_t4
where
t4.symbol='A'
AND
t3.id_glowna1 = glowna1.id
)
as avgc
)
AS A
,
(select
avg(value)
from (
select (
select
t1.value
from
table1 as t1
where
t1.id_t3 = t3.id order by t1.date desc limit 1
)
from
table2 as t2
join
table3 as t3
on
t2.id = t3.id_t2
join
table4 as t4
on
t4.id = t3.id_t4
where
t4.symbol='B'
AND
t3.id_glowna1 = glowna1.id
)
as avgc
)
AS B
,
(select
avg(value)
from (
select (
select
t1.value
from
table1 as t1
where
t1.id_t3 = t3.id order by t1.date desc limit 1
)
from
table2 as t2
join
table3 as t3
on
t2.id = t3.id_t2
join
table4 as t4
on
t4.id = t3.id_t4
where
t4.symbol='C'
AND
t3.id_g1 = g1.id
)
as avgc
)
AS C

FROM
glowna1 as g1
JOIN
glowna2 as g2
ON
g1.id = g2.id_g1
ORDER BY
g1.id

wloochacz

unread,
Feb 7, 2015, 2:36:44 PM2/7/15
to
W dniu 2015-02-07 o 13:31, M.M. pisze:
> On Saturday, February 7, 2015 at 11:24:17 AM UTC+1, wloochacz wrote:
>> W dniu 2015-02-06 o 19:05, M.M. pisze:
>>> On Friday, February 6, 2015 at 2:37:49 PM UTC+1, Marek wrote:
>>>> Wydaje mi się, że wyszukiwanie, że jeśli w jednej tabeli przechowujemy
>>>> [...]
>>>> Czyli reasumując, stawiasz na dynamiczne dodawanie/usuwanie pól do/z tabel?
>>>
>>> Raczej pytam niż stawiam. Dlaczego nie tak?
>>>
>>> CREATE TABLE main (
>>> id integer,
>>> value character varying
>>> );
>>>
>>> CREATE TABLE fields (
>>> id_main integer,
>>> type character varying,
>>> value character varying
>>> );
>> Może być i tak, ale pobieranie danych (czyli select poniżej) jest
>> zrobione fatalnie...
>>
>>> select m.*, (select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa') from main as m where m.value='bbb';
>> Zdajesz sobie sprawę, że zapytanie pobierające wartość pola "dodatkowego":
>> select f1.value from fields as f1 where m.id=f1.id_main and type='aaaa'
>> Wykona się dla każdego wiersza? Za każdym razem.
> Nie zdaję sobie sprawy, ponieważ nie będzie wykonane dla każdego -
> przeanalizuj jeszcze raz zapytanie.
To:
where m.id=f1.id_main

Mówi, że będzie. Łączysz się do bieżącego wiersza w podzapytaniu, które
zwraca skalar.
To, że RDBMS jest sprytny i potrafi sporo rzeczy przewidzieć (a jeszcze
więcej keszować), to inna sprawa.
Ale takie zapytania to koszmarek raczej...

> Ale generalnie, w podobnych
> przypadkach, zgadzam się z Tobą, pobudki masz słuszne, kiedyś w jakiejś
> bazie tak samo się obawiałem. Postanowiłem w niej sprawdzić. Czas na
> pod-zapytaniach w klauzuli select był wyraźnie krótszy.
Np. w MySQL to standard (ale nie wiem czy dla każdego Storage - dziwna
ta baza ;-)), że subquery są bardzo wydajne.
Ale nie w każdej bazie jest analogicznie, czasami bywa naprawdę
różnie...
Np. Fireird fatalnie sobie radzi (a raczej radził, bo jak dokładnie jest
teraz - po prostu nie wiem, nie używam) z takim zapytaniem.
lef join był tak ze 100x szybszy, a inner join był szybszy od left -
nawet jeśli zwracały te same dane.

> Nie umiem tego
> wytłumaczyć, strzelam, że optymalizator dobrze zadziałał.
Prawdopodobnie tak; nie wyznaję się na PQSQL, więc nie będę zgadywał.

>> No to dołóż sobie
>> takich pól dodatkowych kilka, albo kilkanaście i będziesz miał "super"
>> wydajne rozwiązanie...
>>
>> To samo da się napisać za pomocą złączeń i będzie wielokrotnie bardziej
>> wydajne.
> Piszesz jakbyś bardzo szczegółowo rozumiał jak dzialają optymalizatory.
Bo bardzo szczegółowo walczyłem z podobnymi problemami i mentalnością
Kolegów.
Ale to dawno było i zakazałem im pisać co bardziej skomplikowane SQLe
bez rewizji kodu i problemy się skończyły ;-)

> Możesz napisać coś więcej na ten temat?
A co tu pisać?
Generalna zasada jest taka - każdy przypadek jest inny i do każdego
należy podejść indywidualnie. Optymalizacja to ciężki kawałek chleba i
nie ma złotych rad (OK, kilka jest - ale to bazodanowe przedszkole, a
więc szkoda czasu o tym pisać na grupie) - czyli rób tak i zawsze będzie
"lighting fast". To tak nie działa, niestety...
Wiele zależy od bazy, jej wersji, danych, układu, obciążenia, statystyk,
indeksów (gdzie większość komercyjnego oprogramowania i ich baz danych
ma fatalnie zrobione indeksy; mam wrażenie, że programiści aplikacji nie
do końca wiedzą co to tak naprawdę ten indeks jest. I traktują go jako
BlackBox), statystyk, itd.

Ale wiele tez zależy od aplikacji, jak ona "gada" z bazą.
Widziałem taki kwiatek, że app robiła "select id from tab"
a potem w pętelce wykonywała StoredProc, która generalnie robiła:
"select * from tab where id = ?id"

Jak widać, wszystko można spartolić.

--
wloochacz

M.M.

unread,
Feb 7, 2015, 5:47:01 PM2/7/15
to
Chyba że masz na myśli "każdy z wyniku głównego zapytania", a nie "każdy
z tabeli" - to się zgodzę że każdy. Bo główne zapytanie też w określonych
przypadkach może mieć klauzulę where, która obetnie tak dużo, że
pozostały koszt jest nieistotny.

> To, że RDBMS jest sprytny i potrafi sporo rzeczy przewidzieć (a jeszcze
> więcej keszować), to inna sprawa.
> Ale takie zapytania to koszmarek raczej...
Moim zdaniem też to jest koszmarek, ale wbrew mojemu i Twojemu zdaniu,
przykład który wkleiłem w poście niżej, działa bardzo sprawnie.


>
> > Ale generalnie, w podobnych
> > przypadkach, zgadzam się z Tobą, pobudki masz słuszne, kiedyś w jakiejś
> > bazie tak samo się obawiałem. Postanowiłem w niej sprawdzić. Czas na
> > pod-zapytaniach w klauzuli select był wyraźnie krótszy.
> Np. w MySQL to standard (ale nie wiem czy dla każdego Storage - dziwna
> ta baza ;-)), że subquery są bardzo wydajne.
> Ale nie w każdej bazie jest analogicznie, czasami bywa naprawdę
> różnie...
Właśnie... Gdy kodzę w C++, to w przybliżeniu wiem jaka implementacja
będzie szybsza. Gdy używam baz slq, to prawie zawsze jestem zdziwiony.
Nie umiem oszacować czasu wykonania zapytania. Bardzo dużo czynników
na to wpływa. I system plików, i buforowanie systemu, i buforowanie
bazy, zebrane statystyki przez bazę, sprzęt, koszt dostępu losowego vs
sekwencyjnego... Najtrudniej chyba jest przewidzieć jak optymalizator
w jakiej sytuacji sobie poradzi.


> Np. Fireird fatalnie sobie radzi (a raczej radził, bo jak dokładnie jest
> teraz - po prostu nie wiem, nie używam) z takim zapytaniem.
> lef join był tak ze 100x szybszy, a inner join był szybszy od left -
> nawet jeśli zwracały te same dane.
Masakra przy planowaniu wydajnych zapytań.


> >> To samo da się napisać za pomocą złączeń i będzie wielokrotnie bardziej
> >> wydajne.
> > Piszesz jakbyś bardzo szczegółowo rozumiał jak dzialają optymalizatory.
> Bo bardzo szczegółowo walczyłem z podobnymi problemami i mentalnością
> Kolegów.
> Ale to dawno było i zakazałem im pisać co bardziej skomplikowane SQLe
> bez rewizji kodu i problemy się skończyły ;-)
Ja nie mam umiejętności optymalizowania baz. Zwykle mierzę czasy. Jeśli
2-3 wersja na sqlu nie wystarcza, to piszę ręcznie jakiegoś klienta
który pośredniczy pomiędzy bazą a programem głównym.

>
> > Możesz napisać coś więcej na ten temat?
> A co tu pisać?
> Generalna zasada jest taka - każdy przypadek jest inny i do każdego
> należy podejść indywidualnie. Optymalizacja to ciężki kawałek chleba i
> nie ma złotych rad (OK, kilka jest - ale to bazodanowe przedszkole, a
> więc szkoda czasu o tym pisać na grupie) - czyli rób tak i zawsze będzie
> "lighting fast". To tak nie działa, niestety...
A miałem jeszcze nadzieję :)

> Wiele zależy od bazy, jej wersji, danych, układu, obciążenia, statystyk,
> indeksów (gdzie większość komercyjnego oprogramowania i ich baz danych
> ma fatalnie zrobione indeksy; mam wrażenie, że programiści aplikacji nie
> do końca wiedzą co to tak naprawdę ten indeks jest. I traktują go jako
> BlackBox), statystyk, itd.
W sumie też wiele nie wiem o indeksach, dla mnie to jest prawie
BlackBox. Albo hash, albo btree, może opcja cluster albo uniq.


> Ale wiele tez zależy od aplikacji, jak ona "gada" z bazą.
> Widziałem taki kwiatek, że app robiła "select id from tab"
> a potem w pętelce wykonywała StoredProc, która generalnie robiła:
> "select * from tab where id = ?id"
> Jak widać, wszystko można spartolić.
Można i to wcale nie z powodu nieumiejętności. Mam wiele różnych
baboli w swoim kodzie i się tego nie wstydzę. Głównie z powodu
braku czasu takie lub inne kwiatki powstają. Coś było do jakiegoś
zadania. Potem zadanie się zmieniło. Stanąłem przed wyborem: albo
szybko stare przerobić na babola, albo długo robić nowe elegancko.
Często wybór padał na babola.

Pozdrawiam

nk...@toya.net.pl

unread,
Feb 9, 2015, 3:40:53 AM2/9/15
to
W dniu sobota, 7 lutego 2015 23:47:01 UTC+1 użytkownik M.M. napisał:

>W sumie też wiele nie wiem o indeksach, dla mnie to jest prawie
>BlackBox. Albo hash, albo btree, może opcja cluster albo uniq.



No to rzeczywiście należą się korki.


Indeksy to pliki porządkujące alfabetycznie rekordy na podstawie pól tabeli.

Masz tabele:

SELECT * FROM t1;

id p1 p2
----------
1 s 1
2 a 30
3 c 20
4 s 2
5 b 1

i teraz tworzysz dla pół p1+p2 plik indeksowy o nazwie ind1.
Czyli masz dwa piki indeksowe: Primary i ind1.

robisz teraz:
SELECT p1,p2 FROM t1;

id p1 p2
----------
2 a 30
5 b 1
3 c 20
1 s 1
4 s 2

Ułożone alfabetycznie.

Mając zaindeksowane pola, select skacze od razu do Kowalskiego,
bez indeksu jedzie od góry do dołu aż znajdzie Kowalskiego.

No i teraz o czymś czego nie lubię w SQL.
robiąc:

EXPLAIN SELECT p1,p2 FROM t1;

w MySQL na końcu jest Extras, które informuje czy jest używany
indeks w selekcie pisze: Using index.

A teraz zrób takie coś, dodaj dowolne pole tu id:
SELECT id,p1,p2 FROM t1;
wyświetli dane nie uporządkowane

EXPLAIN SELECT id,p1,p2 FROM t1;
i Extaras jest puste czyli po dodaniu dowolnego pola indeksy nie są używane.

Indeksy są świetne ale wymagają przemyślanego projektu bazy danych.
A wiec jak ktoś chciałby mieć indesy w kolejności p2+p1 to musi
utworzyć nowy plik indeksowy idn2.

Przy księgowości bez indeksów ciężko byłoby zliczać dane powiązane
z innymi tabelami, no ale to są sztywne rozwiązania, a kolega Marek
chce dowolności w wyborze pól.

Andrzej.

M.M.

unread,
Feb 9, 2015, 6:30:08 AM2/9/15
to
On Monday, February 9, 2015 at 9:40:53 AM UTC+1, nk...@toya.net.pl wrote:
> W dniu sobota, 7 lutego 2015 23:47:01 UTC+1 użytkownik M.M. napisał:
>
> >W sumie też wiele nie wiem o indeksach, dla mnie to jest prawie
> >BlackBox. Albo hash, albo btree, może opcja cluster albo uniq.
>
>
>
> No to rzeczywiście należą się korki.
> Indeksy to pliki porządkujące alfabetycznie rekordy na podstawie pól tabeli.
Są różne indeksy, np. hash nie ma nic wspólnego z porządkowaniem.


> Indeksy są świetne ale wymagają przemyślanego projektu bazy danych.
Są świetne do tego do czego zostały zaprojektowane. Obecnie mam
bazę testową, a więc małą. Cała baza mieści się w buforach RAM.
Gdy jest indeks hash, to teoretycznie przetwarzanie powinno
zachodzić z szybkością okolo 2.5GB na sekudnę przy dostępie do
losowych rekordów. Ale z bazą trzeba się połączyć, jest narzut
na komunikację TCP-IP, baza musi sparsować i skompilować sqla,
sprawdzać uprawnienia, musi wywoływać funkcje systemu, potem
system pewnie też sprawdza uprawnienia, itd. W konsekwencji
zdarza się, że indeks nie daje zauważalnego przyspieszenia na
tabelach o rozmiarze poniżej 500tys rekordów.


> Przy księgowości bez indeksów ciężko byłoby zliczać dane powiązane
> z innymi tabelami, no ale to są sztywne rozwiązania, a kolega Marek
> chce dowolności w wyborze pól.
Może indeks hash w przypadku kolegi Marka będzie lepszy?


Pozdrawiam

Marek

unread,
Feb 9, 2015, 9:50:01 AM2/9/15
to
W dniu 2015-02-09 o 09:40, nk...@toya.net.pl pisze:

> Przy księgowości bez indeksów ciężko byłoby zliczać dane powiązane
> z innymi tabelami, no ale to są sztywne rozwiązania, a kolega Marek
> chce dowolności w wyborze pól.

Czytam, czytam Waszą rozmowę :-)

Wyjaśnię: tak, chcę dowolności choć zależnie od przyjętego rozwiązania
nie musi być to "frywolne powiązanie" bez indeksów. Jeśli przyjęlibyśmy
koncepcję dublowania wartości pól:
a) W tabeli wartości pól
b) W dynamicznie dostawianych polach w tabeli właściwej (tzn.
zawierającej dane, które rozszerzamy o dodatkowe pola) z narzuceniem
typu pól i budowaniem na nich indeksów gdzie trzeba.

To wtedy nie ma problemu w tworzeniu relacji. Aczkolwiek dynamiczne
dostawianie pól to nie jest profesjonalne podejście...

Na wszelki wypadek zobrazuję co mam na myśli. Jakaś tabela, powiedzmy,
że to "dokument", ma pola A, B i C. W trakcie pracy aplikacji klient
zażyczył sobie mieć pole D, które np. ma zawierać ID do innej tabeli.
Wchodzi w edytor rozszerzeń, dodaje sobie nowe pole i informuje system
"to pole ma linkować do ID autora dokumentu" przykładowo. I co się wtedy
dzieje:

1. W tabeli dodatkowych pól powstaje pole D, jego opisy etc.
2. W tabeli wartości następuje skojarzenie w/w pola D z rekordem w
tabeli "dokument" i w uniwersalnym typie text pola "wartość" jest
przechowywana liczba oznaczająca ID użytkownika w tabeli userów. No ale
raczej kiepsko byłoby budować indeksowanie na polu tekstowym, które raz
jest liczbą a innym razem tekstem.
3. Z w/w powodu dostawiamy pole danych D do tabeli "dokument" (lub
tabeli powiązanej poprzez dziedziczenie - inherit) już właściwego typu,
czyli int4 i tworzymy na nim indeks (dynamicznie również - czyli z
poziomu działania logiki aplikacji).

Zazwyczaj w polach rozszerzonych bardzo mało danych będzie
przechowywanych (liczby, krótkie teksty) więc ich dublowanie nie będzie
bolesne objętościowo. Jednocześnie otrzymujemy łatwy dostęp do tych
danych poprzez select * from dokument, działają constrainy.


--
Pozdrawiam,
Marek

wloochacz

unread,
Feb 9, 2015, 12:54:36 PM2/9/15
to
W dniu 2015-02-09 o 15:49, Marek pisze:
> W dniu 2015-02-09 o 09:40, nk...@toya.net.pl pisze:
>
>> Przy księgowości bez indeksów ciężko byłoby zliczać dane powiązane
>> z innymi tabelami, no ale to są sztywne rozwiązania, a kolega Marek
>> chce dowolności w wyborze pól.
>
> Czytam, czytam Waszą rozmowę :-)
Mam nadzieję, że nie wszystko - bo czasem ktoś palnie jakąś głupotę. jak
np. z dodawanie indeksów, które tworzą pliki...
WTF - jakie kurna pliki?
W DBF to faktycznie tak było... I pewnie w MyISAM - bo to jak sama nazwa
wskazuje, takie DBFy (czyli ISAM) są z nakładka SQLa i razem to się zwie
- MySQL.

> Wyjaśnię: tak, chcę dowolności choć zależnie od przyjętego rozwiązania
> nie musi być to "frywolne powiązanie" bez indeksów. Jeśli przyjęlibyśmy
> koncepcję dublowania wartości pól:
> a) W tabeli wartości pól
Trzymaj się tego, bo innego raczej nie ogarniesz w tej chwili...

> b) W dynamicznie dostawianych polach w tabeli właściwej (tzn.
> zawierającej dane, które rozszerzamy o dodatkowe pola) z narzuceniem
> typu pól i budowaniem na nich indeksów gdzie trzeba.
>
> To wtedy nie ma problemu w tworzeniu relacji. Aczkolwiek dynamiczne
> dostawianie pól to nie jest profesjonalne podejście...
Uzasadnij, bo mam dokładnie odwrotne wyobrażenie.
Tylko jest kilka ALE - nie wyobrażam sobie ręcznego zarządzania tym
bajzlem. to musi być rozwiązane systemowo i automatycznie w taki sposób,
aby raz dodane pole było widoczne dla całego systemu.
Bez rekompilacji systemu (albo zmiany kodów źródłowych w językach
skryptowych - jeżeli ktoś się ma ochotę czepić...).
Ale takie podejście przerasta większość "programistów".
Sorry - taka prawda.

Po drugie, nie każdemu takie podejście potrzebne. W realnym zastosowaniu
okazuje się, że wykorzystanie paradygmatu EAV (doczytaj se w wikipedii
czy gdzie tam chcesz co to, po co i na co) ze wszystkimi jego wadami
daje po prostu radę.
I od tego bym na Twoim miejscu zaczął, skoro dla Ciebie "ogromna" baza
danych ma 100 tabel ;-)

> Na wszelki wypadek zobrazuję co mam na myśli. Jakaś tabela, powiedzmy,
> że to "dokument", ma pola A, B i C. W trakcie pracy aplikacji klient
> zażyczył sobie mieć pole D, które np. ma zawierać ID do innej tabeli.
> Wchodzi w edytor rozszerzeń, dodaje sobie nowe pole i informuje system
> "to pole ma linkować do ID autora dokumentu" przykładowo. I co się wtedy
> dzieje:
>
> 1. W tabeli dodatkowych pól powstaje pole D, jego opisy etc.
W EAV nie dodaje się pola, tylko wiersz do tabeli definicji pola.
Na jego poziomie definiujesz nazwę, typ danych, constraint i link do
relacji/obiektu biznesowego. Ja bym jeszcze dodał flagę określającą, czy
dana wartość jest skalarna czy wektorowa.
A same wartości lecą do innej tabli, która jest połączona z tabelą
definicji pola.
Ot i cała magia.

> 2. W tabeli wartości następuje skojarzenie w/w pola D z rekordem w
> tabeli "dokument" i w uniwersalnym typie text pola "wartość" jest
> przechowywana liczba oznaczająca ID użytkownika w tabeli userów. No ale
> raczej kiepsko byłoby budować indeksowanie na polu tekstowym, które raz
> jest liczbą a innym razem tekstem.
Zależy.
Ale po cholerę Ci indeks na tym polu?

> 3. Z w/w powodu dostawiamy pole danych D do tabeli "dokument" (lub
> tabeli powiązanej poprzez dziedziczenie - inherit)
Dziedziczenie w bazach relacyjnych? Ho, ho... można i tak, ale ja bym
się w to nie bawił.
Oczywiście są bazy post-relacyjne lub obiektowo-relacyjne, które
zapewniają rożne wsparcie do takich zabawek (mam na myśli OOP w ujęciu
bazo-danowym).
Moim zdaniem - nie warto. Więcej z tym kłopotów niż pożytku.
Ale ja tam się na tym nie znam...

> już właściwego typu,
> czyli int4 i tworzymy na nim indeks (dynamicznie również - czyli z
> poziomu działania logiki aplikacji).
No i po co ten indeks?
Indeks należy dodać wtedy kiedy jest NIEZBĘDNY, a nie od razu bo może
się przyda...
To tak jak testować aplikację z pusta bazą danych.
Tragedia...

> Zazwyczaj w polach rozszerzonych bardzo mało danych będzie
> przechowywanych (liczby, krótkie teksty) więc ich dublowanie nie będzie
> bolesne objętościowo. Jednocześnie otrzymujemy łatwy dostęp do tych
> danych poprzez select * from dokument, działają constrainy.
Constrainty (banał) i budowanie SQL (a tu zależy - może to być w miarę
proste lub nie) możesz sobie załatwić po stronie aplikacji.
Napiszesz to raz i będzie działało z dowolnym typem dokumentu.
Tu nie ma co dywagować, tylko doczytać o EAV i zakodować.
Do roboty! ;-)

--
wloochacz

Marek

unread,
Feb 9, 2015, 5:36:10 PM2/9/15
to
W dniu 2015-02-09 o 18:54, wloochacz pisze:

>> b) W dynamicznie dostawianych polach w tabeli właściwej (tzn.
>> zawierającej dane, które rozszerzamy o dodatkowe pola) z narzuceniem
>> typu pól i budowaniem na nich indeksów gdzie trzeba.
>>
>> To wtedy nie ma problemu w tworzeniu relacji. Aczkolwiek dynamiczne
>> dostawianie pól to nie jest profesjonalne podejście...
> Uzasadnij, bo mam dokładnie odwrotne wyobrażenie.

Uzasadnić to, że nie jest profesjonalnym podejściem iż żyjąca aplikacja
modyfikuje sobie sama strukturę bazy danych? Już raz cytowałem kolegę
Cezarego (2ga wypowiedź w wątku). Też mam pewne obiekcje.

> Tylko jest kilka ALE - nie wyobrażam sobie ręcznego zarządzania tym
> bajzlem. to musi być rozwiązane systemowo i automatycznie w taki sposób,
> aby raz dodane pole było widoczne dla całego systemu.

Żaden problem. Wiele lat stosowałem takie rozwiązanie. Ani razu nie
miałem problemów. Sama baza pilnuje siebie na poziomie triggerów i
plpgsql. Jedyna ALE jakie poza nie profesjonalnym podejściem jakie
doświadczyłem, to fakt, że przy dużej liczbie rekordów usuwanie (lub
dodawanie - już nie pamiętam) pól czy indeksów trwało bardzo długo, co
czasem kończyło się timeoutem PHP. Rozwiązałem to również ale tak czy
owak szukam lepszej metody.

> Bez rekompilacji systemu (albo zmiany kodów źródłowych w językach
> skryptowych - jeżeli ktoś się ma ochotę czepić...).
> Ale takie podejście przerasta większość "programistów".
> Sorry - taka prawda.

Niczego w kodach źródłowych nie zmieniałem. Mnie to nie przerosło a nie
jestem jakimś mega programistą :-) Przykładowo (z życia wzięte),
redaktor CMS zażyczył sobie dodać cechę lokalu (ma ogródek) w serwisie
WWW poświęconym deweloperce. Chciał aby dodanie tej opcji stanowiło od
razu kryterium wyszukiwania w części publicznej serwisu. Dodał nowe
pole, nazwał je, zaznaczył iż ma się w publicznej wyszukiwarce pojawić,
ustawił samodzielnie w lokalach, które mają ogródek a które nie i
aplikacja śmiga. Niczego nie musiałem doprogramowywać.

> Po drugie, nie każdemu takie podejście potrzebne. W realnym zastosowaniu
> okazuje się, że wykorzystanie paradygmatu EAV (doczytaj se w wikipedii
> czy gdzie tam chcesz co to, po co i na co) ze wszystkimi jego wadami
> daje po prostu radę.

Chodzi o wirusowe zapalenie tętnic u koni? :-D
Żartuję... ale coś takiego właśnie stosowałem, co miało swoje poważne
ograniczenia. Np. trudno jest budować indeksy i constrainty jeśli
wartości w tym modelu raz są datą, raz są liczbą, raz są tekstem. Stąd
mój były pomysł rozbudowy modelu EAV o dublowanie wartości w tabelach.
Ale o tym dalej bo zaciekawiło mnie co napisałeś.

> I od tego bym na Twoim miejscu zaczął, skoro dla Ciebie "ogromna" baza
> danych ma 100 tabel ;-)

A tak, dla mnie to już ogromna :-)

>> Na wszelki wypadek zobrazuję co mam na myśli. Jakaś tabela, powiedzmy,
>> 1. W tabeli dodatkowych pól powstaje pole D, jego opisy etc.
> W EAV nie dodaje się pola, tylko wiersz do tabeli definicji pola.
> Na jego poziomie definiujesz nazwę, typ danych, constraint i link do
> relacji/obiektu biznesowego. Ja bym jeszcze dodał flagę określającą, czy
> dana wartość jest skalarna czy wektorowa.

... i tu jest to "dalej" o jakim wyżej wspominam.

Też tak kombinuję ale utknąłem właśnie na budowaniu constraintów.

Posłużmy się tabelami jak tu aby łatwiej było rozmawiać:
http://programowanie.opole.pl/archives/1692

słabo się to rozwiązanie nadaje bo entity_id nie określa o jaką tabelę
chodzi. Tabel typu "entities" może być wiele. Tak więc values musi mieć
jedno pole więcej do identyfikacji o jaką tabelę chodzi. Powiedzmy
byłoby to pole typu wyliczeniowego (to mi wystarczy) entity_name. No i
teraz jak zbudować constraint między parą entity_id/entity_name wiążący
którąś z kilku tabel entities1, entities2 ...

Czyli entity_id ma się odnosić do entity1 gdy pole entity_name zawiera
entity1. Ale to samo entity_id może się odnosić do każdej innej tabeli
również.

A po drugie, usprawniłbym tabelę values o różne reprezentacje wartości:
TEXT, INT, DATETIME, FLOAT i być może coś jeszcze. Typ atrybutu
określałby, które z tych pól reprezentuje wartość.Choć z drugiej strony
więcej niż jedno pole wartości atrybutu może strasznie utrudnić
programowanie aplikacji. Obawiam się tego bardzo.

Z kolei potrzebuję zindeksować pole wartości INT po to aby móc budować
na nim klucze obce. Trochę to skomplikowane zaczyna być.

>> 2. W tabeli wartości następuje skojarzenie w/w pola D z rekordem w
>> tabeli "dokument" i w uniwersalnym typie text pola "wartość" jest
>> przechowywana liczba oznaczająca ID użytkownika w tabeli userów. No ale
>> raczej kiepsko byłoby budować indeksowanie na polu tekstowym, które raz
>> jest liczbą a innym razem tekstem.
> Zależy.
> Ale po cholerę Ci indeks na tym polu?

Hmmm.. jeśli pole jest kluczem obcym, to wszędzie czytam, że zawsze
powinien być indeks na nim.

>> 3. Z w/w powodu dostawiamy pole danych D do tabeli "dokument" (lub
>> tabeli powiązanej poprzez dziedziczenie - inherit)
> Dziedziczenie w bazach relacyjnych? Ho, ho... można i tak, ale ja bym
> się w to nie bawił.

Miałem na myśli separację tabeli dynamicznie dostawianych pól od tabeli
"entities" posługując się nomenklaturą z linku. Wtedy możemy grzebać
jedynie w tabeli potomnej a zostawić w spokoju rodzica.

> Oczywiście są bazy post-relacyjne lub obiektowo-relacyjne, które
> zapewniają rożne wsparcie do takich zabawek (mam na myśli OOP w ujęciu
> bazo-danowym).

Mówimy o Postgresie wyłącznie.

> Moim zdaniem - nie warto. Więcej z tym kłopotów niż pożytku.
> Ale ja tam się na tym nie znam...

Bo ja wiem czy to takie zagmatwane? Zamiast robić SELECT * FROM document
robisz SELECT * FROM document_child. Zmieniasz tylko nazwę tabeli przy
SELECTach i nic się nie zmienia w kodzie. Dla porządku możesz też przy
UPDATE'ach, INSERT'ach - jak uznasz za stosowne.

> Constrainty (banał) i budowanie SQL (a tu zależy - może to być w miarę
> proste lub nie) możesz sobie załatwić po stronie aplikacji.
> Napiszesz to raz i będzie działało z dowolnym typem dokumentu.
> Tu nie ma co dywagować, tylko doczytać o EAV i zakodować.
> Do roboty! ;-)

Powoli mnie przekonujesz. Musimy tylko szczegóły dopracować. Mógłbym
oczywiście programowo tworzyć constrainty. Raczej zbudowałbym je w
plpgsql a nie w aplikacji. Baza niech pilnuje swojej integralności sama.

--
Pozdrawiam,
Marek

nk...@toya.net.pl

unread,
Feb 10, 2015, 2:22:56 AM2/10/15
to
Powiem tak.

Powinieneś zrobić coś co już dawno wymyślono i zastosowano w eksploratorze.

User wchodzi w dysk c: pojawiają mu się katalogi w c:,
wchodzi w katalog na c: pojawiają mu się podkatalogi itd., itd...

A ty chcesz zrobić tak, że c: pokazuje od razu wszystko co zawiera w sobie.

Aplikacja usera powinna od razu tworzyć zapytanie, które pozwoli userowi
dodawać i wybierać, czyli tworzyć gotowe inserty/selekty do każdego zagłębienia.

Czemu uparłeś się na obsługę różnych typów danych. Moja sugestia
to ogranicz się do tekstów dobijanych do prawej strony co umożliwia
alfabetyczne porządkowanie, jeśli ci na tym zależy.

Andrzej.

Marek

unread,
Feb 10, 2015, 7:04:25 AM2/10/15
to
W dniu 2015-02-10 o 08:22, nk...@toya.net.pl pisze:
> Powiem tak.
>
> Powinieneś zrobić coś co już dawno wymyślono i zastosowano w eksploratorze.
>
> User wchodzi w dysk c: pojawiają mu się katalogi w c:,
> wchodzi w katalog na c: pojawiają mu się podkatalogi itd., itd...
>
> A ty chcesz zrobić tak, że c: pokazuje od razu wszystko co zawiera w sobie.

Nie, chyba się nie zrozumieliśmy, Ja tylko nie chcę komplikować wątku.
Tak naprawdę to właściwości tworzą strukturę hierarchiczną a elementem
nadrzędnym jest panel kontrolek (albo właściwości jak kto woli). Ja chcę
jedynie tą nadrzędną kontrolkę "panel" przypisywać do rożnych innych
obiektów typu dokument, user, kategoria etc. Jest odrębna tabela
informująca gdzie dany panel ma się wyświetlać w sekcji redakcyjnej CMS.

> Czemu uparłeś się na obsługę różnych typów danych. Moja sugestia
> to ogranicz się do tekstów dobijanych do prawej strony co umożliwia
> alfabetyczne porządkowanie, jeśli ci na tym zależy.

Już wyjaśniam. Odpowiem może pytaniem. W jaki sposób zrealizowałbyś w
swojej koncepcji klucze obce? Załóżmy, że 10-ta para "zmienna=wartość" w
tym łańcuchu będzie zawierać ID rekordu w innej tabeli. Usuwasz rekord w
tejże innej tabeli, i co? I nic! Wartość przypisana do niczego wisi w
powietrzu.

--
Pozdrawiam,
Marek

M.M.

unread,
Feb 10, 2015, 9:21:12 AM2/10/15
to
On Tuesday, February 10, 2015 at 1:04:25 PM UTC+1, Marek wrote:
> Już wyjaśniam. Odpowiem może pytaniem. W jaki sposób zrealizowałbyś w
> swojej koncepcji klucze obce? Załóżmy, że 10-ta para "zmienna=wartość" w
> tym łańcuchu będzie zawierać ID rekordu w innej tabeli. Usuwasz rekord w
> tejże innej tabeli, i co? I nic! Wartość przypisana do niczego wisi w
> powietrzu.
1) Procedura do usuwania - zawsze pamięta, aby obsłużyć te niestandardowe
odwołania.
2) Projekt bazy taki, aby w ogóle nie usuwać, tylko dodać wpis 'usunięto' -
niestety skomplikują się selecty. Za to w ogóle nie ma niebezpieczeństwa
że coś będzie wisiało w powietrzu. Jest jeszcze inna zaleta: zawsze
mamy kopie tego co zostało usunięte.

nk...@toya.net.pl

unread,
Feb 11, 2015, 3:19:16 AM2/11/15
to
W dniu wtorek, 10 lutego 2015 13:04:25 UTC+1 użytkownik Marek napisał:

>
> Już wyjaśniam. Odpowiem może pytaniem. W jaki sposób zrealizowałbyś w
> swojej koncepcji klucze obce? Załóżmy, że 10-ta para "zmienna=wartość" w
> tym łańcuchu będzie zawierać ID rekordu w innej tabeli. Usuwasz rekord w
> tejże innej tabeli, i co? I nic! Wartość przypisana do niczego wisi w
> powietrzu.
>

Niechętnie ale niech tam.
No to jest właśnie zadanie dla ciebie programisty.

t1:
id ptaszek1 p1 ptaszek2 p2 ptaszek3 p3
----------------------------------------
1 v a b v c

t10:
id ptaszek1 p1 ptaszek2 p2 ptaszek3 p3
----------------------------------------
1 a v b c



po optaszkowaniu rekordów pól co tam sobie wymyśliłeś
w while generujesz ciągi:


$sel.="t1.p1";
$sel.="t1.p1, t1.p3";
$sel.="t1.p1, t1.p3, t10.p2";

$war.="t1.p1 BETWEEN 20 and 11";

$war.="t1.p1 BETWEEN 20 and 11 AND t1.p3 LIKE '%ala%' AND t10.p2 IN (11,27,29)";

q1="SELECT $sel from t1, t10 WHERE $war";

Nie pozwolić usuwać optaszkowanych.
Jak nie pomogłem to już musisz sam.

Andrzej.

nk...@toya.net.pl

unread,
Feb 11, 2015, 3:35:04 AM2/11/15
to
W dniu poniedziałek, 9 lutego 2015 18:54:36 UTC+1 użytkownik wloochacz napisał:

> WTF - jakie kurna pliki?

Dokładnie takie same jak łordzie, plik to plik.
Jak dam SHOW INDEX t1 i dostanę: PRIMARY, ind1, ind2
to dla mnie są to pliki, co mam się wygłupiać i powtarzać
po kimś mniej działające na wyobraźnię określenia.

A tak z ciekawości jak prawidłowo to to nazywać, bo jak zauważyłeś
mało ludzi wie do czego są te indeksy i określenie indeks to za mało,
no i dlaczego to to nazywają indeks.

Andrzej.

PS.
Fajny masz nick ale ta twoja retoryka sugeruje,
że działasz na czyjeś zlecenie.

Czarek Grądys

unread,
Feb 11, 2015, 3:36:12 AM2/11/15
to
W dniu 11.02.2015 o 09:19, nk...@toya.net.pl pisze:

>
> Niechętnie ale niech tam.
> No to jest właśnie zadanie dla ciebie programisty.
>
> t1:
> id ptaszek1 p1 ptaszek2 p2 ptaszek3 p3
> ----------------------------------------
> 1 v a b v c
>
> t10:
> id ptaszek1 p1 ptaszek2 p2 ptaszek3 p3
> ----------------------------------------
> 1 a v b c
>
>
>

Mam rozumieć. że ptaszek1 związany jest z polem p1, a ptaszek2 z polem p2 ?
Jeśli tak, to do d... takie rozwiązanie. Powinien być 1 ptaszek
dotyczący całego wiersza. To owszem może działać, ale do czasu. Po
jakimś czasie nikt nad tym nie zapanuje.
Pisanie zapytań będzie udręką, nawet proste SELECT * żeby popatrzyć co w
tej tabeli jest będzie mylące.




--
Cezary Grądys
czar...@wa.onet.pl

Czarek Grądys

unread,
Feb 11, 2015, 3:52:42 AM2/11/15
to
W dniu 11.02.2015 o 09:36, Czarek Grądys pisze:

>
> Mam rozumieć. że ptaszek1 związany jest z polem p1, a ptaszek2 z polem p2 ?
> Jeśli tak, to do d... takie rozwiązanie. Powinien być 1 ptaszek
> dotyczący całego wiersza. To owszem może działać, ale do czasu. Po
> jakimś czasie nikt nad tym nie zapanuje.
> Pisanie zapytań będzie udręką, nawet proste SELECT * żeby popatrzyć co w
> tej tabeli jest będzie mylące.
>
>
A jeszcze jedno, czy jeśli pole p1 i ptaszek p1 zostanie wypełnione, to
p2..p150 pozostaną puste lub NULL?


--
Cezary Grądys
czar...@wa.onet.pl

wloochacz

unread,
Feb 11, 2015, 3:54:03 AM2/11/15
to
W dniu 2015-02-11 o 09:35, nk...@toya.net.pl pisze:
> W dniu poniedziałek, 9 lutego 2015 18:54:36 UTC+1 użytkownik wloochacz napisał:
>
>> WTF - jakie kurna pliki?
>
> Dokładnie takie same jak łordzie, plik to plik.
W kontekście bazy danych?
Jesteś trochę jak firr - nie do końca wiesz co i jak, ale wygłaszasz
swoje teorie z miną guru.
Śmieszne to trochę... Ale to twoje małpy i twój cyrk, mnie tam za jedno.

> Jak dam SHOW INDEX t1 i dostanę: PRIMARY, ind1, ind2
> to dla mnie są to pliki,
To nie są pliki, tylko indeksy z punktu widzenia DBMS. Primary nie
oznacza pierwszego pliku, tylko klucz główny dla tabeli (primary key).
A czy ów DBMS fizycznie trzyma je w plikach (pewnie MySQL dla MyISAM
trzyma - wcale by mnie to nie zdziwiło) dla nas jest tak samo istotne
jak fizyczna organizacja danych w pliku (lub plikach) bazy danych.

A tak poza tym, poważnie?
Nie wiesz takich podstaw a pozwalasz sobie doradzać innym?
Ciekawe...

> co mam się wygłupiać i powtarzać
> po kimś mniej działające na wyobraźnię określenia.
No więc właśnie... czas poszerzyć horyzonty i nie pisać pierdół na
publicznej grupie.

> A tak z ciekawości jak prawidłowo to to nazywać, bo jak zauważyłeś
> mało ludzi wie do czego są te indeksy i określenie indeks to za mało,
> no i dlaczego to to nazywają indeks.
Jest pewna nomenklatura, prawda?
To zacznij jej używać - jeżeli wszyscy będą mówili o tym samym przy
użyciu innych słów/określeń, to na pewno się nie zrozumieją.

> Andrzej.
>
> PS.
> Fajny masz nick ale ta twoja retoryka sugeruje,
> że działasz na czyjeś zlecenie.
Generalnie mam gdzieś co sobie myślisz na temat mojego nicku i mnie samego.
Rozumiem, że i ty węszysz wszędzie jakiś spisek - nawet w moim nicku?

--
wloochacz

nk...@toya.net.pl

unread,
Feb 11, 2015, 4:05:06 AM2/11/15
to
W dniu środa, 11 lutego 2015 09:36:12 UTC+1 użytkownik Czarek Grądys napisał:

> Mam rozumieć. że ptaszek1 związany jest z polem p1, a ptaszek2 z polem p2 ?
> Jeśli tak, to do d... takie rozwiązanie. Powinien być 1 ptaszek
> dotyczący całego wiersza. To owszem może działać, ale do czasu. Po
> jakimś czasie nikt nad tym nie zapanuje.
> Pisanie zapytań będzie udręką, nawet proste SELECT * żeby popatrzyć co w
> tej tabeli jest będzie mylące.
>

No ale Marek chce aby były dodawane pola.
To tylko sugestia a nie gotowe rozwiązanie
bo powinno być jeszcze pole warunek ale to już
naprawdę zostawiam inwencji Marka.

W moich rozwiązaniach działa świetnie ale u mnie
nie jest to aż tak zagmatwane.
Ja generalnie mam generatory skryptów dlatego terminy
dla prostych zleceń to max kilka dni a zajęte głównie przez
CSS i JS czyli obsługę/komunikację, musi być prosta, logiczna.

Andrzej.

R.e.m.e.K

unread,
Feb 11, 2015, 4:35:15 AM2/11/15
to
Dnia Wed, 11 Feb 2015 00:35:03 -0800 (PST), nk...@toya.net.pl napisał(a):


> mało ludzi wie do czego są te indeksy i określenie indeks to za mało,
> no i dlaczego to to nazywają indeks.

Co to za brednie? Dlaczego robisz projekcje swojej niewiedzy na wiekszosc? Jestem gotow
sie zalozyc, ze 90% uzytkownikow tej grupy wie co to indeks i czemu on sluzy. A jewsli Ty
nie wiesz lub wiesz o tym malo to moze warto doczytac?

http://en.wikipedia.org/wiki/Database_index

> PS.
> Fajny masz nick ale ta twoja retoryka sugeruje,
> że działasz na czyjeś zlecenie.

Tak, ruscy go kupili i ma za zadanie zniszczyc hamerykanskie sily zbrojne zakladajaxc
bledne indeksy na tabeli ze wspolrzednymi ataku rakietowego typu ziemia-ziemia. Przez taki
zabieg po pierwszej salwie od ruskich hamerykanski system odpali zapytanie, ktore wykona
sie zbyt wolno i bedzie po ptokach.

--
pozdro
R.e.m.e.K

nk...@toya.net.pl

unread,
Feb 11, 2015, 4:39:11 AM2/11/15
to
W dniu środa, 11 lutego 2015 09:54:03 UTC+1 użytkownik wloochacz napisał:



> Generalnie mam gdzieś co sobie myślisz na temat mojego nicku i mnie samego.
> Rozumiem, że i ty węszysz wszędzie jakiś spisek - nawet w moim nicku?

Ale mnie się naprawdę podoba, robi mi się tak jakoś wesoło
nie bierz tego aż tak do siebie.




No tak, ale wszyscy grupowicze widzą, że nie chcesz odpowiadać
rzeczowo na pytania a jedynie rzucasz potworami słownymi,
które nie przydają się praktycznie programiście korzystającym
z gotowego produktu.
No bo co obchodzi panią Basię, że jej pismo jest zapisane na dysku
nie w postaci ciągłej tylko jest potwornie poszatkowane.
Dla Basi to jej pismo a dla informatyka plik w formacie worda
poszatkowany na dysku.

> > A tak z ciekawości jak prawidłowo to to nazywać, bo jak zauważyłeś
> > mało ludzi wie do czego są te indeksy i określenie indeks to za mało,
> > no i dlaczego to to nazywają indeks.

> Jest pewna nomenklatura, prawda?
> To zacznij jej używać - jeżeli wszyscy będą mówili o tym samym przy


No to jak ty się wymigujesz to ja wyjaśnię.

tab{10) to zwykła tablica pamięciowa ma 10 elementów.
Do każdego elementu można się dostać natychmiast np.: tab[6]="abc";
W tabeli bazodanowej SQL nie ma takiej możliwości do czasu
stworzenia pliku, PLIKU!!! który będzie miał poszeregowane
alfabetycznie rekordy.

Obrazowo...

(bo aby wiedzieć jak jest w rzeczywistości trzeba
byłoby znaleźć kogoś kto robi takie rzeczy i się temu poświęcić)

...rekord zawierający nazwisko KOWALSKI o nieznanym w SQL numerze
(id to sztuczny numer udający numer rekordu ale spełnia swoje zadanie)
a obok jest konkretny adres na dysku gdzie znajduje się ten rekord - i to
jest właśnie ten indeks.

Mimo, że ten opis nie oddaje prawdy absolutnej od razu wiecie jak to
działa - skacze od razu do rekordu z KOWALSKIM.

Powtarzam, chcecie wiedzieć jak jest naprawdę musicie kogoś znaleźć
kto programuje pliki indeksowe.

Włochacz, krytykuj sobie ten tekst, ważne aby mniej więcej ludzie
wiedzieli o co chodzi z tymi indeksami.

Andrzej.

M.M.

unread,
Feb 11, 2015, 8:09:14 AM2/11/15
to
On Wednesday, February 11, 2015 at 10:39:11 AM UTC+1, nk...@toya.net.pl wrote:
> W dniu środa, 11 lutego 2015 09:54:03 UTC+1 użytkownik wloochacz napisał:
>
>
>
> > Generalnie mam gdzieś co sobie myślisz na temat mojego nicku i mnie samego.
> > Rozumiem, że i ty węszysz wszędzie jakiś spisek - nawet w moim nicku?
>
> Ale mnie się naprawdę podoba, robi mi się tak jakoś wesoło
> nie bierz tego aż tak do siebie.
>
>
>
>
> No tak, ale wszyscy grupowicze widzą, że nie chcesz odpowiadać
> rzeczowo na pytania a jedynie rzucasz potworami słownymi,
> które nie przydają się praktycznie programiście korzystającym
> z gotowego produktu.
> No bo co obchodzi panią Basię, że jej pismo jest zapisane na dysku
> nie w postaci ciągłej tylko jest potwornie poszatkowane.
> Dla Basi to jej pismo a dla informatyka plik w formacie worda
> poszatkowany na dysku.
>
> > > A tak z ciekawości jak prawidłowo to to nazywać, bo jak zauważyłeś
> > > mało ludzi wie do czego są te indeksy i określenie indeks to za mało,
> > > no i dlaczego to to nazywają indeks.
>
> > Jest pewna nomenklatura, prawda?
> > To zacznij jej używać - jeżeli wszyscy będą mówili o tym samym przy
>
>
> No to jak ty się wymigujesz to ja wyjaśnię.
>
> tab{10) to zwykła tablica pamięciowa ma 10 elementów.
> Do każdego elementu można się dostać natychmiast np.: tab[6]="abc";
> W tabeli bazodanowej SQL nie ma takiej możliwości

A to nie jest taka możliwość?
update tab set name='abc' where id = select id from tab order by id offset 6 limit 1;

> do czasu
> stworzenia pliku, PLIKU!!! który będzie miał poszeregowane
> alfabetycznie rekordy.
Chyba zaindeksowane rekordy po id.


> ...rekord zawierający nazwisko KOWALSKI o nieznanym w SQL numerze
> (id to sztuczny numer udający numer rekordu ale spełnia swoje zadanie)
> a obok jest konkretny adres na dysku gdzie znajduje się ten rekord - i to
> jest właśnie ten indeks.
Obrazowo to ja bym podał analogię do książki telefonicznej. Chyba lepiej
już nie można wytłumaczyć.

> Mimo, że ten opis nie oddaje prawdy absolutnej od razu wiecie jak to
> działa - skacze od razu do rekordu z KOWALSKIM.
Nie skacze od razu, właśnie trochę szuka, w przybliżeniu tyle szuka, co
w książce telefonicznej. Nie znajduje od razu, ale na pewno nie trzeba
czytać całej.

nk...@toya.net.pl

unread,
Feb 12, 2015, 4:34:19 AM2/12/15
to
W dniu środa, 11 lutego 2015 14:09:14 UTC+1 użytkownik M.M. napisał:

> > tab{10) to zwykła tablica pamięciowa ma 10 elementów.
> > Do każdego elementu można się dostać natychmiast np.: tab[6]="abc";
> > W tabeli bazodanowej SQL nie ma takiej możliwości
>

> A to nie jest taka możliwość?
> update tab set name='abc' where id = select id from tab order by id offset 6 limit 1;


Nie, id to sztuczny numer rekordu a indeks w pliku indeksowym
to fizyczny adres na dysku. Dyskowy system operacyjny (DOS) wie,
którą głowicę czytającą dysk uruchomić, na którym krążku magnetycznym,
na który sektor się ma ustawić głowica...

Indeksy są dla zawodowców amatorom wystarczy order by.







>
> > do czasu
> > stworzenia pliku, PLIKU!!! który będzie miał poszeregowane
> > alfabetycznie rekordy.

> Chyba zaindeksowane rekordy po id.
>
>


Musisz mieć więcej czasu aby załapać, ale w którymś momencie
doznasz olśnienia i uznasz to jako swoje wielkie odkrycie.


Programista baz danych nie używa id, dla zawodowca id nie istnieje.
Id jest dla administratora bazy danych, daje informacje, że były
usuwane rekordy.

id nick
--------------
1 R.E.M.E.K
2 nkab
3 MM
4 MAREK

i teraz ktoś bez twojej wiedzy usunął nkab, co zrobisz
gdy w drugiej tabeli masz posty do tych ników połączonych
poprzez id, no co zrobisz?

Andrzej.

wloochacz

unread,
Feb 12, 2015, 6:47:40 AM2/12/15
to
W dniu 2015-02-12 o 10:34, nk...@toya.net.pl pisze:
> W dniu środa, 11 lutego 2015 14:09:14 UTC+1 użytkownik M.M. napisał:
>
>>> tab{10) to zwykła tablica pamięciowa ma 10 elementów.
>>> Do każdego elementu można się dostać natychmiast np.: tab[6]="abc";
>>> W tabeli bazodanowej SQL nie ma takiej możliwości
>>
>
>> A to nie jest taka możliwość?
>> update tab set name='abc' where id = select id from tab order by id offset 6 limit 1;
>
>
> Nie, id to sztuczny numer rekordu a indeks w pliku indeksowym
Numer rekordu?
A jak indeksów na tabeli jest więcej, to rozumiem że każdy ma inny
"fizyczny" numer rekordu?

> to fizyczny adres na dysku. Dyskowy system operacyjny (DOS) wie,
> którą głowicę czytającą dysk uruchomić, na którym krążku magnetycznym,
> na który sektor się ma ustawić głowica...
Jaaasne...
A w NTFS?
To co piszesz to jest taka półprawda - coś tam słyszałeś, np. o
indeksach klastrowych (zwanych grupującymi), ale reszty nie załapałeś bo
to nie jest dla "zawodowców"?

> Indeksy są dla zawodowców amatorom wystarczy order by.
Zdajesz sobie sprawę, że w bazach relacyjnych to właśnie order by
wymusza kolejność a nie indeks sensu stricte? To nie jest płaska baza
danych (ISAM), jak DBF.
A to że "order by" (podobnie jak where, join, itd.) może użyć danego
indeksu - to zupełnie inna sprawa.

>>> do czasu
>>> stworzenia pliku, PLIKU!!! który będzie miał poszeregowane
>>> alfabetycznie rekordy.
>
>> Chyba zaindeksowane rekordy po id.
>>
>>
> Musisz mieć więcej czasu aby załapać, ale w którymś momencie
> doznasz olśnienia i uznasz to jako swoje wielkie odkrycie.
On ma doznać olśnienia? A co z tobą?

> Programista baz danych nie używa id, dla zawodowca id nie istnieje.
Znaczy - programista do złączeń i selekcji konkretnego rekordu ma nie
używać ID (które jest tożsame z primary key, który to PK najczęściej
jest specjalnym typem indeksu tzw. klastrowym)?

Większej bzdury nie słyszałem...

> Id jest dla administratora bazy danych, daje informacje, że były
> usuwane rekordy.
Że co??

> id nick
> --------------
> 1 R.E.M.E.K
> 2 nkab
> 3 MM
> 4 MAREK
>
> i teraz ktoś bez twojej wiedzy usunął nkab, co zrobisz
> gdy w drugiej tabeli masz posty do tych ników połączonych
> poprzez id, no co zrobisz?
Doczytaj sobie o ograniczeniach w RDBMS, a konkretnie o kluczach obcych.
Masz tam takie cuda jak:
NO ACTION
CASCADE
SET NULL
dla akcji UPDATE i DELETE z osobna.

Rozumiem, że możesz tego nie wiedzieć. OK (chociaż nie OK, bo to
przedszkole jest).
Ale zupełnie nie rozumiem, na jakiej podstawie dajesz "rady", które są
totalnie od czapy?

--
wloochacz

nk...@toya.net.pl

unread,
Feb 12, 2015, 7:16:05 AM2/12/15
to
No właśnie, tu widać jak lubisz niszczyć ludzi.
Kreujesz się na wszystkowiedzącego specjalistę w IT
ale twój cel to totalnie zdyskredytować kogoś,
kto komuś, kto dopiero zaczyna przygodę z bazami
i chce prostymi opisami przybliżyć mu te sprawy
mieszasz w głowie tak aby go zniechęcić.

Napisałem wyraźnie D O S, bo jest prostszy
a ty wciskasz NTFS, który też opiera się na DOS.

Proszę cię, przestań bawić się w niszczenie
konkurencji, bo na grupie są nie tylko zawodowcy
ale głownie amatorzy i zacznij im pomagać.

Jak nie umiesz pomagać to nie pisz.

Andrzej.

Wojciech Cieplak

unread,
Feb 12, 2015, 7:47:35 AM2/12/15
to
W dniu 2015-02-12 o 13:16, nk...@toya.net.pl pisze:
>
[ciach]
> No właśnie, tu widać jak lubisz niszczyć ludzi.
> Kreujesz się na wszystkowiedzącego specjalistę w IT
> ale twój cel to totalnie zdyskredytować kogoś,
> kto komuś, kto dopiero zaczyna przygodę z bazami
> i chce prostymi opisami przybliżyć mu te sprawy
> mieszasz w głowie tak aby go zniechęcić.
>
> Napisałem wyraźnie D O S, bo jest prostszy
> a ty wciskasz NTFS, który też opiera się na DOS.
>
> Proszę cię, przestań bawić się w niszczenie
> konkurencji, bo na grupie są nie tylko zawodowcy
> ale głownie amatorzy i zacznij im pomagać.
>
> Jak nie umiesz pomagać to nie pisz.
>
> Andrzej.
>
Świetnie , ale właśnie skompromitowałeś się totalnie.
Czy wiesz co to DOS ?
Czy znasz rozróżnienie pomiędzy systemem operacyjnym
i systemem plików ?
NTFS - jak powstał i jaką ma strukturę ?
Gdzie leżą granice pomiędzy systemem operacyjnym,
systemem bazy danych i programem użytkownika ?

Powyższe to absolutne podstawy i bez ich
choćby pobieżnego zrozumienia
nie da się zacząć przygody z bazą danych.

Wojtek

Wojciech Cieplak

unread,
Feb 12, 2015, 7:58:35 AM2/12/15
to
PS. Chętnie pomagam, ale żeby pomóc
trzeba aby druga strona też znała podstawy
i język w którym opiszę mu rozwiązanie
jego problemu.

nk...@toya.net.pl

unread,
Feb 12, 2015, 9:02:15 AM2/12/15
to
W dniu czwartek, 12 lutego 2015 13:47:35 UTC+1 użytkownik Wojciech Cieplak napisał:

> Świetnie , ale właśnie skompromitowałeś się totalnie.
> Czy wiesz co to DOS ?

Wiesz, bo ja jestem stary zgred i mój piewszy komputer
to Z-8 ser Siclera, a w firmie był IBM z dwoma stacjami
jednostronnych dyskietek 360kb.

> Czy znasz rozróżnienie pomiędzy systemem operacyjnym
> i systemem plików ?
> NTFS - jak powstał i jaką ma strukturę ?
> Gdzie leżą granice pomiędzy systemem operacyjnym,
> systemem bazy danych i programem użytkownika ?
> Powyższe to absolutne podstawy i bez ich
> choćby pobieżnego zrozumienia
> nie da się zacząć przygody z bazą danych.
>

Do baz danych szczegółowa wiedza na ten temat
przydaje się ale jej brak nie ogranicza w robieniu
dobrych programów bazodanowych.

Twój tekst sugeruje jakoby sekretarka musiała
znać dokładnie co mieści się w pliku worda
ale wszystkie sekretarki nie mają o tym pojęcia
a jednak piszą pisma.

Napisz koledze M.M. o indeksach tak aby on to
zrozumiał, żeby się połapał, że jak da:

SELECT nick from t1 (bez indeksów) to da mu:

R.E.M.E.K
nkab
MM
MAREK

a po dodaniu indeksu dla pola nick

SELECT nick from t1 (z indeksami) da mu:

MAREK
nkab
MM
R.E.M.E.K

i nie ma tu ORDER BY a jednak są w kolejności
alfabetycznej

a jak da:

SELECT * from t1

to znów ma nie posortowane mimo, że są już indeksy
na polu nick.


Po prostu pomagaj tak aby MM załapał bez potrzeby
znajomości NTFS.

Andrzej.

PS.
Ja mam tabele na penie, na której jest FAT32
i co ty na to. Skompromitowałeś się.

Lesiok

unread,
Feb 12, 2015, 9:14:20 AM2/12/15
to
W dniu 2015-02-12 o 15:02, nk...@toya.net.pl pisze:
> Napisz koledze M.M. o indeksach tak aby on to
> zrozumiał, żeby się połapał, że jak da:
>
> SELECT nick from t1 (bez indeksów) to da mu:
>
> R.E.M.E.K
> nkab
> MM
> MAREK
>
> a po dodaniu indeksu dla pola nick
>
> SELECT nick from t1 (z indeksami) da mu:
>
> MAREK
> nkab
> MM
> R.E.M.E.K
>
> i nie ma tu ORDER BY a jednak są w kolejności
> alfabetycznej

Gdzie w dokumentacji PostgreSQL jest to napisane ? Bo ja znalazłem tylko
coś innego :

After a query has produced an output table (after the select list has
been processed) it can optionally be sorted. If sorting is not chosen,
the rows will be returned in an unspecified order. The actual order in
that case will depend on the scan and join plan types and the order on
disk, but it must not be relied on. A particular output ordering can
only be guaranteed if the sort step is explicitly chosen.

Inaczej mówiąc jak nie użyjesz jawnie ORDER BY to porządek danych jest
losowy, gdzie LOSOWY oznacza również "przypadkowo zgodny z
oczekiwaniami". I zgodnie z moją wiedzą dotyczy to również innych
motorów SQL.

--
Pozdrawiam,

Leszek KUBRAK

nk...@toya.net.pl

unread,
Feb 12, 2015, 9:33:36 AM2/12/15
to
W dniu czwartek, 12 lutego 2015 15:14:20 UTC+1 użytkownik Lesiok napisał:

>
> Inaczej mówiąc jak nie użyjesz jawnie ORDER BY to porządek danych jest
> losowy, gdzie LOSOWY oznacza również "przypadkowo zgodny z
> oczekiwaniami". I zgodnie z moją wiedzą dotyczy to również innych
> motorów SQL.
>

ORDER BY jest do sortowania bez potrzeby stosowania indeksów.

Jak to działa w rzeczywistości to ja ci nie powiem ale podejrzewam,
że system na potrzeby tego ORDER BY robi sobie indeksy w RAM,
które są usuwane po ukończeniu wykonywania instrukcji.

Andrzej.

Lesiok

unread,
Feb 12, 2015, 9:44:37 AM2/12/15
to
W dniu 2015-02-12 o 15:33, nk...@toya.net.pl pisze:
Chłop swoje baba swoje. Przecież zacytowałem dokumentację, która mówi
wyraźnie, że bez użycia ORDER BY dostajesz dane NIEPOSORTOWANE. A jeżeli
są posortowane to jest to czysty przypadek (i np. w następnej wersji
silnika bazy możesz dostać całkowicie inną kolejność danych w wyniku
zapytania). I indeksy nic do tego nie mają. Tak więc przestań wciskać
ludziom bzdurne teorie.

Również do sortowania danych w pamięci żadne indeksy nie są potrzebne.
Odpowiednie algorytmy są znane i opisane od dawna.

--
Pozdrawiam,

Leszek KUBRAK

nk...@toya.net.pl

unread,
Feb 12, 2015, 10:03:36 AM2/12/15
to
W dniu czwartek, 12 lutego 2015 15:44:37 UTC+1 użytkownik Lesiok napisał:

> Chłop swoje baba swoje. Przecież zacytowałem dokumentację, która mówi
> wyraźnie, że bez użycia ORDER BY dostajesz dane NIEPOSORTOWANE. A jeżeli
> są posortowane to jest to czysty przypadek (i np. w następnej wersji
> silnika bazy możesz dostać całkowicie inną kolejność danych w wyniku
> zapytania). I indeksy nic do tego nie mają. Tak więc przestań wciskać
> ludziom bzdurne teorie.
>
> Również do sortowania danych w pamięci żadne indeksy nie są potrzebne.
> Odpowiednie algorytmy są znane i opisane od dawna.

No ale o co ci chodzi o to, ze bez ORDER BY dane są nieposortowane
przecież to oczywiste. A nawet jak są w kolejności to widocznie tak
były wprowadzane do bazy ale ta kolejność jest przypadkowa i np.
do zagmatwanych selektów musisz zastosować ORDER BY.

Następny przystąpił do ataku.
A mnie to lata.

Aj polaczki, polaczki głupiście strasznie.

Andrzej.

Lesiok

unread,
Feb 12, 2015, 10:14:42 AM2/12/15
to
W dniu 2015-02-12 o 16:03, nk...@toya.net.pl pisze:
Kilka postów wyżej napisałeś dokładnie coś odwrotnego - jak mamy indeks
to dostaniemy z SELECTa dane posortowane. Zapomniałeś tylko dodać, że
jest to czysty przypadek i o to dokładnie chodzi. Jeżeli masz wiedzę i
chcesz ją przekazać to rób to rzetelnie albo wcale.

Nie wypisuj bzdur to nikt nie będzie Cię atakował.
--
Pozdrawiam,

Leszek KUBRAK

IDKrzych

unread,
Feb 12, 2015, 10:22:16 AM2/12/15
to
> No ale o co ci chodzi o to, ze bez ORDER BY dane są nieposortowane
> przecież to oczywiste. A nawet jak są w kolejności to widocznie tak
> były wprowadzane do bazy ale ta kolejność jest przypadkowa i np.
> do zagmatwanych selektów musisz zastosować ORDER BY.

Sam napisałeś: "ORDER BY jest do sortowania bez potrzeby stosowania
indeksów.", co jest niestety bzdurą.

W SQL by mieć posortowane dane TRZEBA dodać klauzulę ORDER BY.
I koniec - nie ma wyjątków.
Indeksy też nic do tego nie mają. I nie do tego służą.
Indeksy nie służą do sortowania tylko do wyszukiwania i wyszczególniania
podzbiorów na podstawie zadanych warunków (a precyzyjniej do
usprawnienia tych czynności - bez indeksów działa to dużo wolniej).


> Następny przystąpił do ataku.
> A mnie to lata.
>
> Aj polaczki, polaczki głupiście strasznie.

ehh ...
szkoda słów

--
IDKrzych

"Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
- ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
wielowymiarowym,
w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
(S. Lem 1999)

nk...@toya.net.pl

unread,
Feb 12, 2015, 10:30:41 AM2/12/15
to
W dniu czwartek, 12 lutego 2015 16:14:42 UTC+1 użytkownik Lesiok napisał:

> Kilka postów wyżej napisałeś dokładnie coś odwrotnego - jak mamy indeks
> to dostaniemy z SELECTa dane posortowane. Zapomniałeś tylko dodać, że
> jest to czysty przypadek i o to dokładnie chodzi. Jeżeli masz wiedzę i
> chcesz ją przekazać to rób to rzetelnie albo wcale.
>
> Nie wypisuj bzdur to nikt nie będzie Cię atakował.

Jak masz indeksy to dane są posortowane i to nie jest przypadek!

Przypadek w tym cytacie to dane wyglądające jak posortowane
przy braku indeksów lub ORDER BY.

Andrzej.

nk...@toya.net.pl

unread,
Feb 12, 2015, 10:49:27 AM2/12/15
to
W dniu czwartek, 12 lutego 2015 16:22:16 UTC+1 użytkownik IDKrzych napisał:

>
> W SQL by mieć posortowane dane TRZEBA dodać klauzulę ORDER BY.
> I koniec - nie ma wyjątków.
> Indeksy też nic do tego nie mają. I nie do tego służą.
> Indeksy nie służą do sortowania tylko do wyszukiwania i wyszczególniania
> podzbiorów na podstawie zadanych warunków (a precyzyjniej do
> usprawnienia tych czynności - bez indeksów działa to dużo wolniej).
>

A wyobraź sobie, że ja nie stosuję ORDER BY , stosuję indeksy
i mam posortowane dane jak to wyjaśnisz, mam zliczanie wielu tabel
powiązanych indeksami.

Jeśli JOIN bez indeksów potwornie przymula to znaczy, że indeksy
tu są konieczne. Wyciągnij wnioski.



Tak na marginesie ja nie zniechęcam do stosowania ORDER BY.
Temat indeksów poruszył Marek w swojej koncepcji wyszukiwarki
i tu do ewentualnego sortowania ORDER BY byłoby lepsze niż indeksy,
bardziej elastyczne.

Andrzej.

IDKrzych

unread,
Feb 12, 2015, 11:50:19 AM2/12/15
to
W dniu 2015-02-12 o 16:49, nk...@toya.net.pl pisze:
> W dniu czwartek, 12 lutego 2015 16:22:16 UTC+1 użytkownik IDKrzych napisał:
>
>>
>> W SQL by mieć posortowane dane TRZEBA dodać klauzulę ORDER BY.
>> I koniec - nie ma wyjątków.
>> Indeksy też nic do tego nie mają. I nie do tego służą.
>> Indeksy nie służą do sortowania tylko do wyszukiwania i wyszczególniania
>> podzbiorów na podstawie zadanych warunków (a precyzyjniej do
>> usprawnienia tych czynności - bez indeksów działa to dużo wolniej).
>>
>
> A wyobraź sobie, że ja nie stosuję ORDER BY , stosuję indeksy
> i mam posortowane dane jak to wyjaśnisz, mam zliczanie wielu tabel
> powiązanych indeksami.

Nic nie muszę sobie wyobrażać, bo to już pisałeś kilka razy ...
Cały czas nie rozumiesz, że silnik bazy danych bez ORDER BY podaje dane
w kolejności jak mu wyjdzie (nazywa się to "przypadkową").
TYLKO ORDER BY daje GWARANCJE założonej kolejności .

I rób sobie jak chcesz, zasad SQL nie zmienisz nawet gdy uzyskujesz
zadowalający Ciebie rezultat.

> Jeśli JOIN bez indeksów potwornie przymula to znaczy, że indeksy
> tu są konieczne. Wyciągnij wnioski.

Jakiś dziwny jesteś. Przecież to właśnie napisałem.
Powtarzasz po mnie innymi słowami i jeszcze każesz mi wyciągać wnioski z
moich własnych słów? ...
No i kto tu jakieś ataki stosuje?

> Tak na marginesie ja nie zniechęcam do stosowania ORDER BY.
> Temat indeksów poruszył Marek w swojej koncepcji wyszukiwarki
> i tu do ewentualnego sortowania ORDER BY byłoby lepsze niż indeksy,
> bardziej elastyczne.

Nie lepsze, a jedyne możliwe. Przestać mieszać ludziom na publicznej
grupie w głowach.
DO SORTOWANIA SŁUŻY "ORDER BY". KONIEC.

Żyjesz w swoim ciasnym pudełku z czasów DOSa, Clipera, DBFó,
pozycjonowania głowic i innych niskopoziomowych rozwiązań jakie wtedy
były - i nie możesz się wyzwolić z takiego myślenia.

Dzisiejsze architektury klient-serwer rządzą się już innymi prawami.

Sam napisałeś trochę wyżej:
"...Twój tekst sugeruje jakoby sekretarka musiała
znać dokładnie co mieści się w pliku worda
ale wszystkie sekretarki nie mają o tym pojęcia
a jednak piszą pisma..."

I powinieneś sam się zacząć stosować do tej idei.
Przestać interpretować (co gorsza tłumaczyć innym swoje wymysły) co robi
aparat bazy danych.
Chcesz posortowane dane - powiedz to w SQL klauzulą ORDER BY ... i nie
wymyślaj co wtedy robi silnik ... po prostu ciesz się z posortowanego
wyniku jaki otrzymasz. Nie musisz wiedzieć co robił silnik by to uzyskać.

PaSkol

unread,
Feb 12, 2015, 2:04:57 PM2/12/15
to
W dniu 2015-02-12 o 10:34, nk...@toya.net.pl pisze:
> Nie, id to sztuczny numer rekordu a indeks w pliku indeksowym
> to fizyczny adres na dysku. Dyskowy system operacyjny (DOS) wie,
> którą głowicę czytającą dysk uruchomić, na którym krążku magnetycznym,
> na który sektor się ma ustawić głowica...

Na dysku? Już nawet w DOS-ie w pewnym momencie przestało to być prawdą,
bo dyski fizycznie były inaczej skonstruowane, a BIOS dostawał ich
wirtualną adresację (bo nie był w stanie zaadresować takiej ilości
sektorów). Więc choćby z tego powodu to nieprawda.

A jeśli już mówić o adresie, to nawet w DBF był to numer rekordu (lub
przesunięcie w ramach danej tabeli - pliku DBF), a nie adres na dysku.

> Indeksy są dla zawodowców amatorom wystarczy order by.

Doznałem olśnienia - już wiem czemu jest tylu amatorów na świecie :>.

> Programista baz danych nie używa id, dla zawodowca id nie istnieje.
> Id jest dla administratora bazy danych, daje informacje, że były
> usuwane rekordy.

Czy zawodowiec to taki gość, który doznaje zawodu, bo (jak rozpatruję
sprawę niżej) ktoś mu usunął rekord/wiersz/krotkę, a on biedny nie wie
co teraz z tym zrobić?

> id nick
> --------------
> 1 R.E.M.E.K
> 2 nkab
> 3 MM
> 4 MAREK
>
> i teraz ktoś bez twojej wiedzy usunął nkab, co zrobisz
> gdy w drugiej tabeli masz posty do tych ników połączonych
> poprzez id, no co zrobisz?

Widzisz, takie rzeczy to były możliwe tylko w DBF i podobnych systemach
(gdzie pojęcie "system" jest nadużyciem w ich wypadku) obsługi baz
danych. Obecnie RDBMS (Relationa DataBase Managament System - czyli po
naszemu system zarządzania relacyjną bazą danych), jeśli tylko
zdefiniuje mu się więzy integralności danych nie dopuści do takiej
sytuacji. Owe więzy integralności (chyba od naszej ostatniej dyskusji
nie doczytałeś nic na ten temat) polegają w uproszczeniu na tym, że
RDBMS posiada informację, że rekordy z Twojej przykładowej tabeli są
powiązane z inną tabelą i można je usunąć jedynie wspólnie (jeden z
przypadków) albo tzw. nadrzędny rekord można usunąć jedynie, kiedy
wszystkie powiązane z nim rekordy w dodatkowej tabeli zostaną usunięte
wcześniej (oczywiście nie dotyczy to tylko usuwania i nie jest to jedyny
sposób zapewnienia integralności, ale nie chcę komplikować).

> Napisz koledze M.M. o indeksach tak aby on to
> zrozumiał, żeby się połapał, że jak da:
>
> SELECT nick from t1 (bez indeksów) to da mu:
>
> R.E.M.E.K
> nkab
> MM
> MAREK
>
> a po dodaniu indeksu dla pola nick
>
> SELECT nick from t1 (z indeksami) da mu:
>
> MAREK
> nkab
> MM
> R.E.M.E.K
>
> i nie ma tu ORDER BY a jednak są w kolejności
> alfabetycznej

To ja ostrożnie zapytam - w jakim RDBMS? Nie znam PostgreSQL, ale w dość
dobrze znanym mi MSSQL (lub SQL Server - jak kto woli) dodanie
poleceniem *insert* zgodnie z powyższą, przypadkową kolejnością może ale
nie musi dla *select* zwrócić w kolejności dodawania. Bo ta kolejność
jest z definicji przypadkowa, co obejmuje też przypadek, że będzie
akurat kolejnością dodawania.

Co więcej - w MSSQL nie trzeba podawać w zapytaniu indeksów, bo jeśli
takowe są założone dla tabeli, to optymalizator silnika serwera SQL je
wykorzysta (o ile będzie to opłacalne). Co więcej - potrafi też sobie
poradzić z wykorzystaniem indeksu złożonego (czyli p1 + p2) dla
zaprezentowania w kolejności zgodnej z jednym z pól wchodzących w jego
skład. Pomijam już fakt, że w jego przypadku indeksy tylko w jednym
przypadku wskazują na położenie wiersza, a w pozostałych, gdy jest
indeks klastrowy na tabeli, wskazują na wartość tego indeksu.

Indeksy to już od dłuższego czasu nie pliki (bo baza danych jest
plikiem). To po prostu zbiory danych (danymi są indeksy), zazwyczaj
(zależy do RDBMS) niezajmujące spójnego obszaru.

--
PaSkol (paskol.robi.to)

Krzysztof Jodłowski

unread,
Feb 12, 2015, 2:07:06 PM2/12/15
to
> A wyobraź sobie, że ja nie stosuję ORDER BY , stosuję indeksy
> i mam posortowane dane jak to wyjaśnisz, mam zliczanie wielu tabel
> powiązanych indeksami.

To ja się już zaczynam bać, że twoje bazy maja gdzieś użytek publiczny.
Może podaj gdzie, to na wszelki ograniczę kontakty z tą firmą...

--
pozdrawiam
Krzysztof Jodłowski

wloochacz

unread,
Feb 12, 2015, 2:13:28 PM2/12/15
to
W dniu 2015-02-12 o 16:21, IDKrzych pisze:
>> No ale o co ci chodzi o to, ze bez ORDER BY dane są nieposortowane
>> przecież to oczywiste. A nawet jak są w kolejności to widocznie tak
>> były wprowadzane do bazy ale ta kolejność jest przypadkowa i np.
>> do zagmatwanych selektów musisz zastosować ORDER BY.
>
> Sam napisałeś: "ORDER BY jest do sortowania bez potrzeby stosowania
> indeksów.", co jest niestety bzdurą.
Oczywiście, że nie jest bzdurą ;-)
Zapytam - czy klauzula "order by" zadziała poprawnie kiedy tabela nie ma
założonego indeksu na polach, które sortujesz? Załóżmy, że tabela w
ogóle nie ma żadnego indeksu.
...
Oczywiście, że zadziała poprawnie :)
A że przy okazji zrobi skan tabeli, to inna sprawa..

> W SQL by mieć posortowane dane TRZEBA dodać klauzulę ORDER BY.
True.

> I koniec - nie ma wyjątków.
True, ale... wyjątkiem jest clusterd index, ale i on de-facto nie daje
100% pewności porządku danych.

Dla niskopoziomowców:
http://sqlwithmanoj.com/2013/06/02/clustered-index-do-not-guarantee-physically-ordering-or-sorting-of-rows/

> Indeksy też nic do tego nie mają. I nie do tego służą.
> Indeksy nie służą do sortowania tylko do wyszukiwania i wyszczególniania
> podzbiorów na podstawie zadanych warunków (a precyzyjniej do
> usprawnienia tych czynności - bez indeksów działa to dużo wolniej).
To wszystko prawda, tylko aby efektywnie szukać konkretnej danej w
zbiorze, najpierw trzeba ów zbiór posortować. A dokładnie - należy go
posortować, jeśli zakładamy, że to wyszukiwanie będzie używane częściej
niż raz. Baza danych przyjmuje takie założenie z definicji.
Innymi słowy - indeks służy tez do sortowania i jest to jego, że tak
powiem, wartość dodana.

Dlatego w tym miejscu się chyba (na pewno) ciut zagalopowałeś.
Skoro w temacie jest PostgreSQL to wyjaśnij mi jedną rzecz; skoro indeks
nie służy do "sortowania", to po co (jak nie do sortowania) w jego
deklaracji jest coś takiego jak:
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ] ON table [ USING method ]
( { column | ( expression ) } [ COLLATE collation ] [ opclass ] [
*ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )*

I dalej czytamy:
"
ASC
Specifies ascending *sort order* (which is the default).
DESC
Specifies descending *sort order*.
NULLS FIRST
Specifies that nulls *sort before non-nulls*. This is the default
when DESC is specified.
NULLS LAST
Specifies that nulls *sort after non-nulls*. This is the default
when DESC is not specified.
"

Źródło:
http://www.postgresql.org/docs/9.1/static/sql-createindex.html

Bo wg mnie to (powyżej) jasno określa, że właśnie indeks determinuje
sortowanie wg kolumn, na których indeks został założony.
I to jeszcze z kierunkiem sortowania (rosnąco/malejąco) i określeniem
czy wartości NULL mają być na końcu lub początku uporządkowanego zbioru.

Insza, inszość, że nkab nie rozumie, że założony indeks na tabeli bez
użycia "order by" tak naprawdę nie determinuje żadnego uporządkowania
wierszy w tej tabeli. Oczywiście w odniesieniu do baz SQL.
Period.

/ciach/

--
wloochacz

IDKrzych

unread,
Feb 12, 2015, 2:57:56 PM2/12/15
to
>> Sam napisałeś: "ORDER BY jest do sortowania bez potrzeby stosowania
>> indeksów.", co jest niestety bzdurą.
>
> Oczywiście, że nie jest bzdurą ;-)
> Zapytam - czy klauzula "order by" zadziała poprawnie kiedy tabela nie ma
> założonego indeksu na polach, które sortujesz? Załóżmy, że tabela w
> ogóle nie ma żadnego indeksu.
> ...
> Oczywiście, że zadziała poprawnie :)
> A że przy okazji zrobi skan tabeli, to inna sprawa..

Ale nie zrozumiałeś. To wyrwany cytat który przypominał mu co kilka
postów wcześniej twierdził.

On napisał, że gdy nie ma indeksów musi stosować ORDER BY, jak są
indeksy nie musi - i w tym znaczeniu jest to bzdurą!
Też nie o to chodzi. Mówimy o ogólnych zasadach SQL.
Konkretne rozwiązania, konkretnych indeksów w konkretnych silnikach nie
mają nic do rzeczy.
Indeks ogólnie nie służy do sortowania wyniku, a to że dane są przez
niego w oczywisty sposób jakoś uporządkowane jest naturalne.
Optymalizator oczywiście skorzysta prawdopodobnie z takiego indeksu by
spełnić klauzulę ORDER BY - ale to jego wybór. W innym silniku nie
będzie miał takiej możliwości i też będzie działać.
W jeszcze innym wypadku pomimo posiadania takiego indeksu może go nie
użyć, bo uzna że sortowanie w inny sposób będzie korzystniejsze.

Ogólnie chodzi o to, że wykorzystanie indeksu do różnych czynności nie
jest z góry znane. Zależy od silnika, optymalizatora i konkretnego
zapytania (i tuzina innych czynników).
Dlatego

> Insza, inszość, że nkab nie rozumie, że założony indeks na tabeli bez
> użycia "order by" tak naprawdę nie determinuje żadnego uporządkowania
> wierszy w tej tabeli. Oczywiście w odniesieniu do baz SQL.
> Period.

No dokładnie tylko o to chodziło w moim pod-wątku ;)

Każda insza rozmowa o indeksach musi być z konieczności mało ogólna -
musi dotyczyć konkretnej bazy, silnika i zapytania.
A w sumie od tego się zaczęło:
nkab na podstawie konkretnego (mało reprezentatywnego) przykładu
wykładał publicznie o zasadach SQLa.

Pozdrawiam

irq

unread,
Feb 12, 2015, 3:29:08 PM2/12/15
to
W dniu czwartek, 12 lutego 2015 20:13:28 UTC+1 użytkownik wloochacz napisał:
> Skoro w temacie jest PostgreSQL to wyjaśnij mi jedną rzecz; skoro indeks
> nie służy do "sortowania",

indeks służy do przyspieszenia wyszukiwania.
Żródło:
http://www.postgresql.org/docs/9.1/static/indexes.html
i to już na samym wstępie.

> to po co (jak nie do sortowania) w jego
> deklaracji jest coś takiego jak:
> CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ] ON table [ USING method ]
> ( { column | ( expression ) } [ COLLATE collation ] [ opclass ] [
> *ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )*
>
> I dalej czytamy:
> "
> ASC
> Specifies ascending *sort order* (which is the default).
> DESC
> Specifies descending *sort order*.
> NULLS FIRST
> Specifies that nulls *sort before non-nulls*. This is the default
> when DESC is specified.
> NULLS LAST
> Specifies that nulls *sort after non-nulls*. This is the default
> when DESC is not specified.
> "
>
> Źródło:
> http://www.postgresql.org/docs/9.1/static/sql-createindex.html
>
> Bo wg mnie to (powyżej) jasno określa, że właśnie indeks determinuje
> sortowanie wg kolumn, na których indeks został założony.
> I to jeszcze z kierunkiem sortowania (rosnąco/malejąco) i określeniem
> czy wartości NULL mają być na końcu lub początku uporządkowanego zbioru.

Te klauzule określają sposób uporządkowania samego indeksu, a nie tabeli. Bo jeszcze dalej czytamy:

For index methods that support ordered scans (currently, only B-tree), the optional clauses ASC, DESC, NULLS FIRST, and/or NULLS LAST can be specified to modify the sort ordering of the index.

Żródło:
http://www.postgresql.org/docs/9.1/static/sql-createindex.html

Zwróć też uwagę, że klauzule ASC, DESC, ... w CREATE INDEX pojawiły się stosunkowo niedawno (na tyle na ile rok 2008 to niedawno i na ile skala czasu istnienia relacyjnych baz danych jest wystarczająco długa):

Allow per-column ascending/descending (ASC/DESC) ordering options for indexes (Teodor, Tom)

Previously a query using ORDER BY with mixed ASC/DESC specifiers could not fully use an index. Now an index can be fully used in such cases if the index was created with matching ASC/DESC specifications. NULL sort order within an index can be controlled, too.

Żródło:
http://www.postgresql.org/docs/8.3/static/release-8-3.html

Pozdrawiam
Irek

wloochacz

unread,
Feb 12, 2015, 5:06:43 PM2/12/15
to
W dniu 2015-02-12 o 21:29, irq pisze:
> W dniu czwartek, 12 lutego 2015 20:13:28 UTC+1 użytkownik wloochacz napisał:
>> Skoro w temacie jest PostgreSQL to wyjaśnij mi jedną rzecz; skoro indeks
>> nie służy do "sortowania",
>
> indeks służy do przyspieszenia wyszukiwania.
Nie zrozumiałeś kontekstu... Jak chcesz efektywnie wyszukiwać bez
sortowania?
Nie chodzi o to, że MUSISZ sortować aby wyszukiwać, a o to, że w
posortowanych danych szuka się szybciej.
Ergo - indeks wymusza porządek.
Oczywiście, że indeksu i nie napisałem inaczej.

> Bo jeszcze dalej czytamy:
>
> For index methods that support ordered scans (currently, only B-tree), the optional clauses ASC, DESC, NULLS FIRST, and/or NULLS LAST can be specified to modify the sort ordering of the index.
>
> Żródło:
> http://www.postgresql.org/docs/9.1/static/sql-createindex.html
>
> Zwróć też uwagę, że klauzule ASC, DESC, ... w CREATE INDEX pojawiły się stosunkowo niedawno (na tyle na ile rok 2008 to niedawno i na ile skala czasu istnienia relacyjnych baz danych jest wystarczająco długa):
Nie wyznaję się na PostgreSQL, ale zakład że wcześniej po prostu
domyślnie było ASC.

> Allow per-column ascending/descending (ASC/DESC) ordering options for indexes (Teodor, Tom)
>
> Previously a query using ORDER BY with mixed ASC/DESC specifiers could not fully use an index. Now an index can be fully used in such cases if the index was created with matching ASC/DESC specifications. NULL sort order within an index can be controlled, too.
Tutaj słowem kluczem do zrozumienia jest "MIXED".

> Żródło:
> http://www.postgresql.org/docs/8.3/static/release-8-3.html
>
> Pozdrawiam
> Irek
>


--
wloochacz

M.M.

unread,
Feb 13, 2015, 6:46:29 AM2/13/15
to
On Thursday, February 12, 2015 at 11:06:43 PM UTC+1, wloochacz wrote:
> W dniu 2015-02-12 o 21:29, irq pisze:
> > W dniu czwartek, 12 lutego 2015 20:13:28 UTC+1 użytkownik wloochacz napisał:
> >> Skoro w temacie jest PostgreSQL to wyjaśnij mi jedną rzecz; skoro indeks
> >> nie służy do "sortowania",
> >
> > indeks służy do przyspieszenia wyszukiwania.
> Nie zrozumiałeś kontekstu... Jak chcesz efektywnie wyszukiwać bez
> sortowania?
> Nie chodzi o to, że MUSISZ sortować aby wyszukiwać, a o to, że w
> posortowanych danych szuka się szybciej.
Dla bezpieczeństwa bym dodał, że w przypadku DUŻYCH ilości
danych indeks umożliwia szybsze wyszukiwanie. Bo jeszcze
ktoś doda do bazy 4 rekordy i zobaczy że indeks nie
przyspiesza ;-)

Czarek Grądys

unread,
Feb 13, 2015, 7:47:50 AM2/13/15
to
W dniu 13.02.2015 o 12:46, M.M. pisze:

> Dla bezpieczeństwa bym dodał, że w przypadku DUŻYCH ilości
> danych indeks umożliwia szybsze wyszukiwanie. Bo jeszcze
> ktoś doda do bazy 4 rekordy i zobaczy że indeks nie
> przyspiesza ;-)
>

Ja bym dodał, że w przypadku przeszukiwania dużych ilości, a zwracania
małych ilości. Bo jak SELECT zwraca 90% wierszy z tabeli, to
przyspieszenia nie będzie.

--
Cezary Grądys
czar...@wa.onet.pl

nk...@toya.net.pl

unread,
Feb 13, 2015, 8:32:47 AM2/13/15
to
Nareszcie dyskusja nabrała poważniejszego charakteru.

Uporządkujmy:

w moim systemie MySQL do wszelkich plików dot danych jest taka ściezka:

C:\wamp\bin\mysql\mysql5.5.24\data\tbl

to "tbl" na końcu to nazwa bazy danych o tej nazwie katalogu,
która ma taką oto listę plików:

t1.frm // nałowki tabeli t1
t1.MYD // dane (rekordy) tabeli
t1.MYI // indeksy (ten plik zawiera wszystkie pliki indeksowe)

t2.frm
t2.MYD
t2.MYI

Czyli jak widzicie namacalnie - indeksy są osobnymi plikami dyskowymi
ale tutaj (widocznie tak jest lepiej) scalonymi w jednym pliku.

I teraz jeśli mamy utworzone indeksy dala pól "p1,p2"
i te pola pojawią się za słowem SELECT:

SELECT p1,p2 FROM t1;

system wącha czy w t1.MYI jest taka kombinacja,
jeśli jest to system już nie zajmuje się tabelą
a operuje wyłącznie na pliku indeksowym - efekt?
selekt pokaże uporządkowane według p1,p2 dane.
Jeśli dacie gwiazdkę to system nie wywącha indeksów.

Indeksy nic nie robią z tabelą (rekordami).
Indeksy pokazują rekordy na podstawie fizycznych
adresów dyskowych.

Indeksy są osobnymi plikami bo dla każdego z nich można
założyć CASCH'a.

Więcej o wykorzystaniu indeksów możecie poczytać w google po hasłem:

Index Hint Syntax

I to jest wkurzające, bo to tak za bardzo nie działa.
Dajmy np.:

SELECT * FROM t1 USE INDEX (ind1);

powinien wymusić użycie ind1 i pokazać wszystko uporządkowane
według p1,p2 a tu - dupa blada.

Andrzej.

Cezary Grądys

unread,
Feb 14, 2015, 2:01:54 AM2/14/15
to
W dniu 12.02.2015 o 16:21, IDKrzych pisze:

> W SQL by mieć posortowane dane TRZEBA dodać klauzulę ORDER BY.
> I koniec - nie ma wyjątków.
> Indeksy też nic do tego nie mają. I nie do tego służą.
> Indeksy nie służą do sortowania tylko do wyszukiwania i wyszczególniania
> podzbiorów na podstawie zadanych warunków (a precyzyjniej do
> usprawnienia tych czynności - bez indeksów działa to dużo wolniej).
>

Oczywista sprawa, w modelu relacyjnym kolejność wierszy, a nawet pól nie
jest ważna!!! To, że baza zwraca w kolejności wprowadzenia, czy czasem
posortuje (bo DISTINCT czy GROUP BY tego wymaga, żeby go zrobić) to jest
efekt uboczny!
Zwykły UPDATE zaburzy kolejność danych zwracanych przez select * FROM
tabela.


Prosty test (PostgreSQL):




test=> select * from test;
id | opis
----+------
1 | 2
2 | 2
3 | 2
4 | 2
5 | 2
6 | 2
7 | 2
8 | 2
9 | 2
10 | 2
11 | 2
12 | 2
13 | 2
14 | 2
15 | 2
16 | 2
17 | 2
18 | 2
19 | 2
20 | 2
(20 rows)

test=> update test set opis=3 where id=6;
UPDATE 1
test=> select * from test;
id | opis
----+------
1 | 2
2 | 2
3 | 2
4 | 2
5 | 2
7 | 2
8 | 2
9 | 2
10 | 2
11 | 2
12 | 2
13 | 2
14 | 2
15 | 2
16 | 2
17 | 2
18 | 2
19 | 2
20 | 2
6 | 3
(20 rows)





--
Cezary Grądys
czar...@wa.onet.pl

Lesiok

unread,
Feb 14, 2015, 4:39:59 AM2/14/15
to
W dniu 2015-02-13 o 14:32, nk...@toya.net.pl pisze:
> Nareszcie dyskusja nabrała poważniejszego charakteru.
>
> Uporządkujmy:
>
> w moim systemie MySQL do wszelkich plików dot danych jest taka ściezka:
>
> C:\wamp\bin\mysql\mysql5.5.24\data\tbl
>
> to "tbl" na końcu to nazwa bazy danych o tej nazwie katalogu,
> która ma taką oto listę plików:
>
> t1.frm // nałowki tabeli t1
> t1.MYD // dane (rekordy) tabeli
> t1.MYI // indeksy (ten plik zawiera wszystkie pliki indeksowe)
>
> t2.frm
> t2.MYD
> t2.MYI
>
> Czyli jak widzicie namacalnie - indeksy są osobnymi plikami dyskowymi
> ale tutaj (widocznie tak jest lepiej) scalonymi w jednym pliku.

No i co w związku z tym ? Jest to prywatna sprawa konkretnego silnika
bazy danych i nie ma żadnego związku z wykorzystywaniem indeksów w
zapytaniach.

>
> I teraz jeśli mamy utworzone indeksy dala pól "p1,p2"
> i te pola pojawią się za słowem SELECT:
>
> SELECT p1,p2 FROM t1;
>
> system wącha czy w t1.MYI jest taka kombinacja,
> jeśli jest to system już nie zajmuje się tabelą
> a operuje wyłącznie na pliku indeksowym - efekt?
> selekt pokaże uporządkowane według p1,p2 dane.
> Jeśli dacie gwiazdkę to system nie wywącha indeksów.

To nie tak. Po prostu optymalizator stwierdza, że ma plik indeksowy
zawierający dokładnie te wartości, które chcesz odczytać. Ponieważ plik
indeksowy zazwyczaj jest fizycznie mniejszy niż plik z danymi całej
tabeli więc wartości są odczytywane z niego - mniejsza ilość operacji
dyskowych do wykonania. Uzyskany dzięki temu porządek danych w wyniku
zapytania jest przypadkowym efektem ubocznym. Oparcie na takim efekcie
ubocznym logiki aplikacji jest karygodnym błędem.

>
> Indeksy nic nie robią z tabelą (rekordami).
> Indeksy pokazują rekordy na podstawie fizycznych
> adresów dyskowych.
>
> Indeksy są osobnymi plikami bo dla każdego z nich można
> założyć CASCH'a.
>
> Więcej o wykorzystaniu indeksów możecie poczytać w google po hasłem:
>
> Index Hint Syntax
>
> I to jest wkurzające, bo to tak za bardzo nie działa.
> Dajmy np.:
>
> SELECT * FROM t1 USE INDEX (ind1);
>
> powinien wymusić użycie ind1 i pokazać wszystko uporządkowane
> według p1,p2 a tu - dupa blada.
>
> Andrzej.

Ao to już jest dowód na to, że indeksy same z siebie nie są używane do
porządkowania danych w wyniku zapytania tylko do szybszego wyszukiwania
podzbioru danych a powtarzalny porządek danych w wyniku zapytania SELECT
uzyskujesz tylko i wyłącznie dzięki opcji ORDER BY a nie dzięki
istnieniu indeksu.

Zresztą w dokumentacji MySQL jest napisane wyraźnie (cytat z rozdziału
13.2.9.3 Index Hint Syntax) :

To influence index usage for sorting or grouping rows, use FOR ORDER BY
or FOR GROUP BY. (However, if there is a covering index for the table
and it is used to access the table, the optimizer will ignore IGNORE
INDEX FOR {ORDER BY|GROUP BY} hints that disable that index.)

Czyli nie ma ORDER BY to nie ma sortowania danych w wyniku zapytania.

Po co używać indeksu (dodatkowe operacje dyskowe) skoro i tak
odczytujemy całą tabelę ?

Po za tym wątek dotyczy PostgreSQL więc podpieranie się w dyskusji
obserwacjami z bazy MySQL nie bardzo ma sens.


--
Pozdrawiam,

Leszek KUBRAK

nk...@toya.net.pl

unread,
Feb 16, 2015, 3:18:10 AM2/16/15
to
W dniu sobota, 14 lutego 2015 10:39:59 UTC+1 użytkownik Lesiok napisał:


> > Uporządkujmy:
> >
> > w moim systemie MySQL do wszelkich plików dot danych jest taka ściezka:
> >
> > C:\wamp\bin\mysql\mysql5.5.24\data\tbl
> >
> > to "tbl" na końcu to nazwa bazy danych o tej nazwie katalogu,
> > która ma taką oto listę plików:
> >
> > t1.frm // nałowki tabeli t1
> > t1.MYD // dane (rekordy) tabeli
> > t1.MYI // indeksy (ten plik zawiera wszystkie pliki indeksowe)
> >
> > t2.frm
> > t2.MYD
> > t2.MYI
> >
> > Czyli jak widzicie namacalnie - indeksy są osobnymi plikami dyskowymi
> > ale tutaj (widocznie tak jest lepiej) scalonymi w jednym pliku.
>


> No i co w związku z tym ? Jest to prywatna sprawa konkretnego silnika
> bazy danych i nie ma żadnego związku z wykorzystywaniem indeksów w
> zapytaniach.
>

Śmiem podejrzewać, że wszystkie systemy mają podobną organizację tylko,
że wam nie chce się tego szukać.


> >
> > I teraz jeśli mamy utworzone indeksy dala pól "p1,p2"
> > i te pola pojawią się za słowem SELECT:
> >
> > SELECT p1,p2 FROM t1;
> >
> > system wącha czy w t1.MYI jest taka kombinacja,
> > jeśli jest to system już nie zajmuje się tabelą
> > a operuje wyłącznie na pliku indeksowym - efekt?
> > selekt pokaże uporządkowane według p1,p2 dane.
> > Jeśli dacie gwiazdkę to system nie wywącha indeksów.
>
> To nie tak. Po prostu optymalizator stwierdza, że ma plik indeksowy
> zawierający dokładnie te wartości, które chcesz odczytać. Ponieważ plik
> indeksowy zazwyczaj jest fizycznie mniejszy niż plik z danymi całej
> tabeli więc wartości są odczytywane z niego - mniejsza ilość operacji
> dyskowych do wykonania. Uzyskany dzięki temu porządek danych w wyniku
> zapytania jest przypadkowym efektem ubocznym. Oparcie na takim efekcie
> ubocznym logiki aplikacji jest karygodnym błędem.
>

Nie jest efektem ubocznym tylko logicznym i jedynym słusznym
bo najsprawniejszym. Nie wymyślono sprawniejszego.
Inaczej ten tekst zrozumiałem, chociaż nie znam angielskiego:

...jeśli użyłeś ORDER BY to system ignoruje indeksy...




tłumaczenie tego fragmentu przez Google:

>Aby wpłynąć wykorzystanie indeksu do sortowania i grupowania wierszy, użyj DLA >ORDER BY
> Lub DLA GROUP BY. (Jednak jeżeli istnieje indeks przykrycie tabeli
> I jest używany do dostępu do tabeli, optymalizator będzie ignorować IGNORUJ
> INDEKS DO {ORDER BY | GROUP BY}. Podpowiedzi, które wyłączają tego indeksu)




Według ciebie co powinno pokazać zapytanie ze strony manuala:

SELECT * FROM t1 USE INDEX (ind1);

Według mnie to jest ewidentny bug. Gdybym znał angielski na pewno
zgłosiłbym go.

Andrzej.

nk...@toya.net.pl

unread,
Feb 16, 2015, 3:23:39 AM2/16/15
to
W dniu sobota, 14 lutego 2015 08:01:54 UTC+1 użytkownik Cezary Grądys napisał:

Nadal nie wiesz o co chodzi z indeksami.
Te twoje listingi pokazują, że zapytanie nie używa indeksu!
Uaktywnij indeks i dopiero zobaczysz efekt .

Andrzej.

nk...@toya.net.pl

unread,
Feb 16, 2015, 4:04:41 AM2/16/15
to
Sorry, się pośpieszyłem.
Po prostu w MySQL ten numer z gwiazdką nie przechodzi.
Jeśli w postgre tak to działa ja na twoim rysunku no to rzeczywiście
to działa tak jak powinno! Czyli postgre jest lepszym systemem.

Jeszcze raz sorry.

Andrzej.

Lesiok

unread,
Feb 16, 2015, 6:26:11 AM2/16/15
to
W dniu 2015-02-16 o 09:18, nk...@toya.net.pl pisze:
> W dniu sobota, 14 lutego 2015 10:39:59 UTC+1 użytkownik Lesiok napisał:
>
>
>>> Uporządkujmy:
>>>
>>> w moim systemie MySQL do wszelkich plików dot danych jest taka ściezka:
>>>
>>> C:\wamp\bin\mysql\mysql5.5.24\data\tbl
>>>
>>> to "tbl" na końcu to nazwa bazy danych o tej nazwie katalogu,
>>> która ma taką oto listę plików:
>>>
>>> t1.frm // nałowki tabeli t1
>>> t1.MYD // dane (rekordy) tabeli
>>> t1.MYI // indeksy (ten plik zawiera wszystkie pliki indeksowe)
>>>
>>> t2.frm
>>> t2.MYD
>>> t2.MYI
>>>
>>> Czyli jak widzicie namacalnie - indeksy są osobnymi plikami dyskowymi
>>> ale tutaj (widocznie tak jest lepiej) scalonymi w jednym pliku.
>>
>
>
>> No i co w związku z tym ? Jest to prywatna sprawa konkretnego silnika
>> bazy danych i nie ma żadnego związku z wykorzystywaniem indeksów w
>> zapytaniach.
>>
>
> Śmiem podejrzewać, że wszystkie systemy mają podobną organizację tylko,
> że wam nie chce się tego szukać.

No to sam sobie sprawdź i się nie zdziw jak zobaczysz coś całkiem innego.

>
>
>>>
>>> I teraz jeśli mamy utworzone indeksy dala pól "p1,p2"
>>> i te pola pojawią się za słowem SELECT:
>>>
>>> SELECT p1,p2 FROM t1;
>>>
>>> system wącha czy w t1.MYI jest taka kombinacja,
>>> jeśli jest to system już nie zajmuje się tabelą
>>> a operuje wyłącznie na pliku indeksowym - efekt?
>>> selekt pokaże uporządkowane według p1,p2 dane.
>>> Jeśli dacie gwiazdkę to system nie wywącha indeksów.
>>
>> To nie tak. Po prostu optymalizator stwierdza, że ma plik indeksowy
>> zawierający dokładnie te wartości, które chcesz odczytać. Ponieważ plik
>> indeksowy zazwyczaj jest fizycznie mniejszy niż plik z danymi całej
>> tabeli więc wartości są odczytywane z niego - mniejsza ilość operacji
>> dyskowych do wykonania. Uzyskany dzięki temu porządek danych w wyniku
>> zapytania jest przypadkowym efektem ubocznym. Oparcie na takim efekcie
>> ubocznym logiki aplikacji jest karygodnym błędem.
>>
>
> Nie jest efektem ubocznym tylko logicznym i jedynym słusznym
> bo najsprawniejszym. Nie wymyślono sprawniejszego.

Ty wiesz lepiej - w moim zespole twoja kariera byłaby krótka.
Tłumaczenia Google są zazwyczaj tak dobre jak wiedza czerpana tylko z
Wikipedii - czyli takie sobie. Zgodnie z moją wiedzą to zapytanie zwróci
wszystkie dane z bazy w losowej kolejności. I tyle.

Niestety, ale nie da się dobrze programować (pojęcie użyte bardzo
ogólnie) bez znajomości języka angielskiego. Taki mamy klimat.


--
Pozdrawiam,

Leszek KUBRAK

PaSkol

unread,
Feb 16, 2015, 3:23:59 PM2/16/15
to
W dniu 2015-02-16 o 09:18, nk...@toya.net.pl pisze:
> W dniu sobota, 14 lutego 2015 10:39:59 UTC+1 użytkownik Lesiok napisał:
>> No i co w związku z tym ? Jest to prywatna sprawa konkretnego silnika
>> bazy danych i nie ma żadnego związku z wykorzystywaniem indeksów w
>> zapytaniach.
>>
>
> Śmiem podejrzewać, że wszystkie systemy mają podobną organizację tylko,
> że wam nie chce się tego szukać.

Ależ my nie musimy tego szukać, my to wiemy, bo czytamy literaturę. Nie
przypuszczałem, że pliki indeksowe nie odeszły wraz z DBF-ami, ale są
jeszcze używane w jakimś RDBMS. Jest to rozwiązanie mniej wydajne, niż
trzymanie struktury bazy w pojedynczym pliku (lub kilku - jeśli użyto
partycjonowania) ponieważ wymaga zasobów systemowych (uchwytów do
plików) w celu obsługi bazy danych. Kolejna kwestia to defragmentacja
każdego pliku z osobna. W przypadku bazy w pojedynczym pliku można już
na wstępie zarezerwować dla niego spójny obszar i nie martwić się
problemami pochodzącymi od systemu plików (defragmentację danych w owym
pliku załatwiając wydajnymi mechanizmami bazodanowymi). A jeśli taki
obszar nie zostanie zarezerwowany, to i tak pozostaje uporządkowanie
jednego pliku a nie kilkuset (bo tyle może być tabel, ich nagłówków,
indeksów, LOB-ów).

>> To nie tak. Po prostu optymalizator stwierdza, że ma plik indeksowy
>> zawierający dokładnie te wartości, które chcesz odczytać. Ponieważ plik
>> indeksowy zazwyczaj jest fizycznie mniejszy niż plik z danymi całej
>> tabeli więc wartości są odczytywane z niego - mniejsza ilość operacji
>> dyskowych do wykonania. Uzyskany dzięki temu porządek danych w wyniku
>> zapytania jest przypadkowym efektem ubocznym. Oparcie na takim efekcie
>> ubocznym logiki aplikacji jest karygodnym błędem.
>>
>
> Nie jest efektem ubocznym tylko logicznym i jedynym słusznym
> bo najsprawniejszym. Nie wymyślono sprawniejszego.

Doprawdy? A wiesz, że optymalizator serwera SQL może stwierdzić, że ma
gdzieś indeks? Bo dane, które ma zwrócić posiada już w pamięci, jest ich
niewiele i koszt ich posortowania w pamięci w stosunku do kosztu
pobrania indeksu, który pozwoli je ustawić w oczekiwanym porządku jest
mniejszy? I nie tknie indeksu, bo liczy się ostateczny koszt - jak
szybko dane uda się dostarczyć.

>> To influence index usage for sorting or grouping rows, use FOR ORDER BY
>> or FOR GROUP BY. (However, if there is a covering index for the table
>> and it is used to access the table, the optimizer will ignore IGNORE
>> INDEX FOR {ORDER BY|GROUP BY} hints that disable that index.)
>>
>> Czyli nie ma ORDER BY to nie ma sortowania danych w wyniku zapytania.
>>
>
> Inaczej ten tekst zrozumiałem, chociaż nie znam angielskiego:
> ...jeśli użyłeś ORDER BY to system ignoruje indeksy...
>
> tłumaczenie tego fragmentu przez Google:
>
>> Aby wpłynąć wykorzystanie indeksu do sortowania i grupowania wierszy, użyj DLA >ORDER BY
>> Lub DLA GROUP BY. (Jednak jeżeli istnieje indeks przykrycie tabeli
>> I jest używany do dostępu do tabeli, optymalizator będzie ignorować IGNORUJ
>> INDEKS DO {ORDER BY | GROUP BY}. Podpowiedzi, które wyłączają tego indeksu)

Wg mnie ten tekst brzmi:
Aby spowodować użycie indeksu do sortowania i grupowania wierszy, należy
użyć klauzul FOR ORDER BY lub FOR GROUP BY. (Jednakże, jeżeli dla tabeli
istnieje indeks pokrywający i jest on używany w dostępie do niej,
optymalizator zignoruje wskazówkę (hint) IGNORE INDEX FOR {ORDER
BY|GROUP BY}, mającą wymusić pominięcie indeksu.)

--
PaSkol (paskol.robi.to)

nk...@toya.net.pl

unread,
Feb 17, 2015, 2:37:36 AM2/17/15
to
W dniu poniedziałek, 16 lutego 2015 21:23:59 UTC+1 użytkownik PaSkol napisał:
>
> Ależ my nie musimy tego szukać, my to wiemy, bo czytamy literaturę. Nie
> przypuszczałem, że pliki indeksowe nie odeszły wraz z DBF-ami, ale są
> jeszcze używane w jakimś RDBMS. Jest to rozwiązanie mniej wydajne, niż
> trzymanie struktury bazy w pojedynczym pliku (lub kilku - jeśli użyto
> partycjonowania) ponieważ wymaga zasobów systemowych (uchwytów do
> plików) w celu obsługi bazy danych. Kolejna kwestia to defragmentacja
> każdego pliku z osobna. W przypadku bazy w pojedynczym pliku można już
> na wstępie zarezerwować dla niego spójny obszar i nie martwić się
> problemami pochodzącymi od systemu plików (defragmentację danych w owym
> pliku załatwiając wydajnymi mechanizmami bazodanowymi). A jeśli taki
> obszar nie zostanie zarezerwowany, to i tak pozostaje uporządkowanie
> jednego pliku a nie kilkuset (bo tyle może być tabel, ich nagłówków,
> indeksów, LOB-ów).
>

Zgodzę się w pełni, że mogą być wdrożone koncepcje, że wszystkie pliki
dotyczące danej bazy danych (tabele, indeksy, funkcje...) można
upakować w jednym pliku, ale to i tak są osobne pliki wpakowane
do jednego, nazwijmy go, kontenera. Fragmentacja w takim kontenerze
nadal występuje, tego nie da się uniknąć bo dane są dopisywane, usuwane
itd. Tu jest tylko zysk, że wgląda to jak jeden plik.


> >> To nie tak. Po prostu optymalizator stwierdza, że ma plik indeksowy
> >> zawierający dokładnie te wartości, które chcesz odczytać. Ponieważ plik
> >> indeksowy zazwyczaj jest fizycznie mniejszy niż plik z danymi całej
> >> tabeli więc wartości są odczytywane z niego - mniejsza ilość operacji
> >> dyskowych do wykonania. Uzyskany dzięki temu porządek danych w wyniku
> >> zapytania jest przypadkowym efektem ubocznym. Oparcie na takim efekcie
> >> ubocznym logiki aplikacji jest karygodnym błędem.
> >>


> >
> > Nie jest efektem ubocznym tylko logicznym i jedynym słusznym
> > bo najsprawniejszym. Nie wymyślono sprawniejszego.
>

> Doprawdy? A wiesz, że optymalizator serwera SQL może stwierdzić, że ma
> gdzieś indeks? Bo dane, które ma zwrócić posiada już w pamięci, jest ich
> niewiele i koszt ich posortowania w pamięci w stosunku do kosztu
> pobrania indeksu, który pozwoli je ustawić w oczekiwanym porządku jest
> mniejszy? I nie tknie indeksu, bo liczy się ostateczny koszt - jak
> szybko dane uda się dostarczyć.
>

Może, tylko o jakie czasy walczyłby ten optymalizator.
W tym zakresie jestem niedowiarkiem.


> >> To influence index usage for sorting or grouping rows, use FOR ORDER BY
> >> or FOR GROUP BY. (However, if there is a covering index for the table
> >> and it is used to access the table, the optimizer will ignore IGNORE
> >> INDEX FOR {ORDER BY|GROUP BY} hints that disable that index.)
> >>
> >> Czyli nie ma ORDER BY to nie ma sortowania danych w wyniku zapytania.
> >>
> >
> > Inaczej ten tekst zrozumiałem, chociaż nie znam angielskiego:
> > ...jeśli użyłeś ORDER BY to system ignoruje indeksy...
> >
> > tłumaczenie tego fragmentu przez Google:
> >
> >> Aby wpłynąć wykorzystanie indeksu do sortowania i grupowania wierszy, użyj DLA >ORDER BY
> >> Lub DLA GROUP BY. (Jednak jeżeli istnieje indeks przykrycie tabeli
> >> I jest używany do dostępu do tabeli, optymalizator będzie ignorować IGNORUJ
> >> INDEKS DO {ORDER BY | GROUP BY}. Podpowiedzi, które wyłączają tego indeksu)
>
> Wg mnie ten tekst brzmi:
> Aby spowodować użycie indeksu do sortowania i grupowania wierszy, należy
> użyć klauzul FOR ORDER BY lub FOR GROUP BY. (Jednakże, jeżeli dla tabeli
> istnieje indeks pokrywający i jest on używany w dostępie do niej,
> optymalizator zignoruje wskazówkę (hint) IGNORE INDEX FOR {ORDER
> BY|GROUP BY}, mającą wymusić pominięcie indeksu.)
>

Dzięki za przetłumaczenie tego fragmentu.
Wynika z tego, że można wyspecyfikować pliki indeksowe,
które przy używaniu klauzuli ORDER BY|GROUP BY zostały
celowo dezaktywowane przez programistę.




Tak na marginesie, wygenerowałem sobie w tabelach 1 milion rekordów
z losowymi danymi i założyłem dla dwóch pól indeksy. Czas tworzenia
indeksów ok 3 sekund. Następnie w selekcie użyłem klauzuli ORDER BY
też dla tych samych pól i zanim selekt pokazał rekordy upłynęło ok 3 sekund.
Wniosek - ORDER BY robi indeksy w locie i jak mówili koledzy - koniec kropka.

To tylko potwierdza moją opinię - indeksy są dla profesjonalistów.

Andrzej.

wloochacz

unread,
Feb 17, 2015, 2:44:32 AM2/17/15
to
W dniu 2015-02-16 o 21:23, PaSkol pisze:
/ciach/
Że też chce Ci się uprawiać tą spaloną bzdurami i życzeniowym podejściem
ziemię...

Przecież gość udowdnił po raz kolejny swoją totalną ignorancję i olewa
wszystko co się do niego pisze. On wie lepiej.

Tylko tu kaganek (oświaty) nie wystarczy, tu trzeba napalm spuścić aby
wypalić do cna ten chory sen pijanego idioty.

A teraz zgodnie z podejściem nkaba; ja tam nie wiem, ale jestem
przekonany, że inaczej się nie da, bo tak jak mi sie wydaje jest
najlepiej na świecie!

--
wloochacz

PaSkol

unread,
Feb 17, 2015, 11:52:52 AM2/17/15
to
W dniu 2015-02-17 o 08:37, nk...@toya.net.pl pisze:
> Zgodzę się w pełni, że mogą być wdrożone koncepcje, że wszystkie pliki
> dotyczące danej bazy danych (tabele, indeksy, funkcje...) można
> upakować w jednym pliku, ale to i tak są osobne pliki wpakowane
> do jednego, nazwijmy go, kontenera. Fragmentacja w takim kontenerze
> nadal występuje, tego nie da się uniknąć bo dane są dopisywane, usuwane
> itd. Tu jest tylko zysk, że wgląda to jak jeden plik.

Mogą? One są wdrożone. Sprawdź sobie inne RDBMS oprócz tego, którego
używasz. I zapoznaj się z organizacją takiego pliku bazy danych, bo z
pewnością nie jest taka, jak sobie wyobrażasz. Nic w takim pliku nie
jest ciągłym, spójnym obszarem (który mógłby być analogią od pliku
tabeli czy indeksu). Wręcz przeciwnie i dzięki temu defragmentacja nie
jest problemem, co więcej nie jest to defragmentacja w sensie
defragmentacji pliku na dysku. A w pewnych logicznych jednostkach
defragmentacja jest wręcz pożądana.

> Może, tylko o jakie czasy walczyłby ten optymalizator.
> W tym zakresie jestem niedowiarkiem.

Walczy o konkretne czasy, co więcej jest skonstruowany zgodnie z
regułami jakie rządzą dużymi zbiorami danych, tj. gromadzi ich
statystyki i na nich opiera swoje decyzje.

> Wynika z tego, że można wyspecyfikować pliki indeksowe,
> które przy używaniu klauzuli ORDER BY|GROUP BY zostały
> celowo dezaktywowane przez programistę.

To nie wiedziałeś, że istnieją tzw. wskazówki dla zapytań SQL? Nie wiem
jak w MySQL czy PostgreSQL, ale można za ich pomocą sterować wieloma
zachowaniami, jak choćby użytą metodą łączenia ze sobą wierszy dwóch tabel.

> Tak na marginesie, wygenerowałem sobie w tabelach 1 milion rekordów
> z losowymi danymi i założyłem dla dwóch pól indeksy. Czas tworzenia
> indeksów ok 3 sekund. Następnie w selekcie użyłem klauzuli ORDER BY
> też dla tych samych pól i zanim selekt pokazał rekordy upłynęło ok 3 sekund.
> Wniosek - ORDER BY robi indeksy w locie i jak mówili koledzy - koniec kropka.

Wiesz, przypominasz mi radzieckiego naukowca, który przeprowadził
następujący eksperyment: wziął pająka, powiedział do niego "idź" i
położył na stole. Pająk oczywiście zaczął się poruszać. Następnie
naukowiec urwał jedną nogę pająkowi i powtórzył polecenie. Pająk je
wykonał. Następnie sukcesywnie postępował tak z kolejnymi odnóżami
pająka. Przy ostatnim pająk nadal, choć już wyjątkowo nieudolnie
próbował oddalić się od swego oprawcy. Wówczas przyszła kolej na
ostatnią nogę. W tym wypadku jednak, po wydaniu polecenia "idź", pająk
ani myślał się ruszyć. Wówczas radziecki naukowiec zanotował następujący
wniosek z eksperymentu: "po urwaniu wszystkich odnóży pająk stracił słuch".

Zastanów się czym się różni posortowanie danych od ich pobrania i
prezentacji w ustalonej kolejności. Czy w obu przypadkach zakres
przeprowadzanych działań jest taki sam? Jeśli nadal twierdzisz swoje -
obejrzyj sobie plan wykonania obu poleceń (indeksacja i pobranie
danych). Zobacz czasy poszczególnych operacji.

> To tylko potwierdza moją opinię - indeksy są dla profesjonalistów.

Jest to chyba jedyny punkt, w którym się z Tobą całkowicie zgadzam. A
to, co na ten temat napisałeś wręcz utwierdza mnie w prawdziwości tego
twierdzenia. Ze swojej strony dodam tylko, że profesjonalistą można się
stać - więc wszystko przed Tobą.

--
PaSkol (paskol.robi.to)

PaSkol

unread,
Feb 17, 2015, 12:18:08 PM2/17/15
to
W dniu 2015-02-17 o 08:44, wloochacz pisze:
> W dniu 2015-02-16 o 21:23, PaSkol pisze:
> /ciach/
> Że też chce Ci się uprawiać tą spaloną bzdurami i życzeniowym podejściem
> ziemię...
>
> Przecież gość udowdnił po raz kolejny swoją totalną ignorancję i olewa
> wszystko co się do niego pisze. On wie lepiej.

Ja tam go nawracać nie chcę, natomiast mam na uwadze postronnych. Tych
co są tu obecnie i tych przyszłych co to przypadkiem natrafią na ten
wątek i przyswoją nieprawdziwe informacje.

Podobno cały ruch antyszczepionkowy wziął się z takiego przypadku, gdy
jakiś niespełniony naukowiec spreparował badania i napisał esej, który
udowadniał, ze szczepionki to ZUO. To chyba nawet w jakimś
profesjonalnym periodyku medycznym wyszło i dopiero potem okazało się,
że to ściema i periodyk dementował. Ale fakt, że opublikował jest
faktem, który jest z kolei argumentem, że coś tu jest na rzeczy. O tym,
że było dementi już niekoniecznie się wspomina. I tak sobie żyje ta
urban legend narażając świat na wybuch epidemii.

> A teraz zgodnie z podejściem nkaba; ja tam nie wiem, ale jestem
> przekonany, że inaczej się nie da, bo tak jak mi sie wydaje jest
> najlepiej na świecie!

Ja mam na to zawsze dobrą odpowiedź: masz rację - wydaje Ci się ;).

--
PaSkol (paskol.robi.to)

artiun

unread,
Feb 17, 2015, 1:35:28 PM2/17/15
to
W dniu 2015-02-17 o 17:52, PaSkol pisze:

>> To tylko potwierdza moją opinię - indeksy są dla profesjonalistów.
>
> Jest to chyba jedyny punkt, w którym się z Tobą całkowicie zgadzam. A to, co
> na ten temat napisałeś wręcz utwierdza mnie w prawdziwości tego twierdzenia.
> Ze swojej strony dodam tylko, że profesjonalistą można się stać - więc
> wszystko przed Tobą.
>
Indeksy dla profesjonalistów?
Przesada, bardzo duża przesada. Toż dzieci w przedszkolu rozpoznają szuflady
z bucikami, czapkami itp.
Inaczej:) jeśli napiszę pończoszki, skarpetki, buciki - to w jakiej
kolejności dziecko to założy, przypadkowej?

create index... imie asc, nazwisko asc ..

select imie, nazwisko from cosik;

I teraz
Imie Nazwisko Ile
Jan Kowalski 21
Jan Kowalski 22
Jan Kowalski 2
Jan Kowalski 32
Jan Kowalski 12

.. tu zmiany ...

jest prawidłowe ( tak jak i)

Imie Nazwisko Ile
Jan Kowalski 32
Jan Kowalski 2
Jan Kowalski 41
Jan Kowalski 7

A to ta sama baza

Nie trzeba wiedzieć jak to jest realizowane w samym silniku bazy, wystarczy
wiedzieć jak i czemu to służy. Nie muszę wiedzieć co pija posłowie idąc po
piwo do sklepu. (Obowiązują nas teoretycznie :) te same prawa).


--
Artur
0 weeks 5 days 0 hours 46 minutes 12 seconds and 185 milliseconds.
"pl.comp.bazy-danych"

R.e.m.e.K

unread,
Feb 17, 2015, 2:08:36 PM2/17/15
to
Dnia Tue, 17 Feb 2015 19:22:17 +0100, artiun napisał(a):

>>> To tylko potwierdza moją opinię - indeksy są dla profesjonalistów.
>>
>> Jest to chyba jedyny punkt, w którym się z Tobą całkowicie zgadzam. A to, co
>> na ten temat napisałeś wręcz utwierdza mnie w prawdziwości tego twierdzenia.
>> Ze swojej strony dodam tylko, że profesjonalistą można się stać - więc
>> wszystko przed Tobą.
>>
> Indeksy dla profesjonalistów?
> Przesada, bardzo duża przesada. Toż dzieci w przedszkolu rozpoznają szuflady
> z bucikami, czapkami itp.

Przechodzila obok i kopnela Cie w dupa, mimo to nie zauwazyles - na imie miala Ironia
(zdrobnienie od Ireny?)

--
pozdro
R.e.m.e.K

PaSkol

unread,
Feb 17, 2015, 2:51:23 PM2/17/15
to
W dniu 2015-02-17 o 19:22, artiun pisze:
> W dniu 2015-02-17 o 17:52, PaSkol pisze:
>
>>> To tylko potwierdza moją opinię - indeksy są dla profesjonalistów.
>>
>> Jest to chyba jedyny punkt, w którym się z Tobą całkowicie zgadzam. A
>> to, co
>> na ten temat napisałeś wręcz utwierdza mnie w prawdziwości tego
>> twierdzenia.
>> Ze swojej strony dodam tylko, że profesjonalistą można się stać - więc
>> wszystko przed Tobą.
>>
> Indeksy dla profesjonalistów?
> Przesada, bardzo duża przesada. Toż dzieci w przedszkolu rozpoznają
> szuflady z bucikami, czapkami itp.

No rozpoznają, ale każde dziecko tylko swój, więc właściwie można
powiedzieć, że są w stanie zarządzać jedynie własną relacją z szafką (ta
szafka jest moja, bo ja mam muchomorek).

> Inaczej:) jeśli napiszę pończoszki, skarpetki, buciki - to w jakiej
> kolejności dziecko to założy, przypadkowej?

Chyba nie masz dzieci. Może nie założyć skarpetek, może nie założyć
pończoszek. Nawet takie, które umie czytać. Po prostu się zamyśli.

> Nie trzeba wiedzieć jak to jest realizowane w samym silniku bazy,
> wystarczy wiedzieć jak i czemu to służy.

Jeśli chce się jedynie korzystać z indeksu nie wnikając w kwestie
wydajnościowe - owszem. Ale brak chociażby takiej świadomości jak "co to
jest indeks klastrowy" (grupujący, jak podaje czasami literatura) i
jakie rządzą nim prawa może spowodować szybki spadek wydajności bazy
przy niewłaściwym dobraniu wartości klucza (chyba, że klucz musi taki
być i zakładamy odpowiednie operacje na utrzymanie właściwej wydajności
tabeli z takim kluczem). Bo trzeba zdawać sobie sprawę, jaki jest koszt
utrzymywania indeksów, że czasami przy dużym przyroście danych lepiej
usunąć indeks, a potem ponownie go założyć (lub - jeśli RDBMS daje taką
możliwość - zawiesić aktualizację indeksu aż do pobrania wszystkich danych).

Do tego dochodzą różne typy indeksów, jak wspomniany już klastrowy, czy
chociażby te: z załączoną kolumną danych, filtrowany, dotyczący
specyficznych danych, np. geometrycznych, XML lub tekstowych na poziomie
tokenów. W indeksach należy też uwzględnić aspekty związane z
partycjonowaniem bazy danych, itd.

--
PaSkol (paskol.robi.to)

PaSkol

unread,
Feb 17, 2015, 2:53:55 PM2/17/15
to
W dniu 2015-02-17 o 20:08, R.e.m.e.K pisze:
No, owszem - jestem w tym ostatnim akapicie sarkastyczny, ale nie w
kwestii samego twierdzenia. Może nie trzeba być jakimś wybitnym
profesjonalistą, ale trochę wiedzy trzeba mieć, jeśli się chce panować
nad wydajnością bazy danych.

--
PaSkol (paskol.robi.to)

M.M.

unread,
Feb 17, 2015, 3:46:03 PM2/17/15
to
On Saturday, February 14, 2015 at 8:01:54 AM UTC+1, Cezary Grądys wrote:
> W dniu 12.02.2015 o 16:21, IDKrzych pisze:
>
> > W SQL by mieć posortowane dane TRZEBA dodać klauzulę ORDER BY.
> > I koniec - nie ma wyjątków.
> > Indeksy też nic do tego nie mają. I nie do tego służą.
> > Indeksy nie służą do sortowania tylko do wyszukiwania i wyszczególniania
> > podzbiorów na podstawie zadanych warunków (a precyzyjniej do
> > usprawnienia tych czynności - bez indeksów działa to dużo wolniej).
> >
>
> Oczywista sprawa, w modelu relacyjnym kolejność wierszy, a nawet pól nie
> jest ważna!!!
Jak to nie jest ważna? Jest ważna dla wydajności w przypadku gdy
zbiory danych są przechowywane na dyskach talerzowych. Choćby z
tego powodu został wprowadzony indeks klastrowy. Kolejność jest
na tyle ważna, że czasami trzyma się 2-3 kopie danych, tylko po to
aby w każdej kopii zachować określony porządek sortowania.


> To, że baza zwraca w kolejności wprowadzenia, czy czasem
> posortuje (bo DISTINCT czy GROUP BY tego wymaga, żeby go zrobić) to jest
> efekt uboczny!
> Zwykły UPDATE zaburzy kolejność danych zwracanych przez select * FROM
> tabela.
Ten przykład dowodzi tylko tego, ze pozwoliłeś bazie na zwrócenie danych
w dowolnym porządku i w dowolnym porządku Ci zwróciła. TO nie ma nic
wspólnego z porządkiem na dysku.

Pozdrawiam

PaSkol

unread,
Feb 18, 2015, 2:34:12 AM2/18/15
to
W dniu 2015-02-17 o 21:46, M.M. pisze:
> On Saturday, February 14, 2015 at 8:01:54 AM UTC+1, Cezary Grądys wrote:
>> Oczywista sprawa, w modelu relacyjnym kolejność wierszy, a nawet pól nie
>> jest ważna!!!
> Jak to nie jest ważna? Jest ważna dla wydajności w przypadku gdy
> zbiory danych są przechowywane na dyskach talerzowych. Choćby z
> tego powodu został wprowadzony indeks klastrowy. Kolejność jest
> na tyle ważna, że czasami trzyma się 2-3 kopie danych, tylko po to
> aby w każdej kopii zachować określony porządek sortowania.

Czy można prosić o jakiś link na poparcie tych informacji.

--
PaSkol (paskol.robi.to)

M.M.

unread,
Feb 18, 2015, 5:50:14 AM2/18/15
to
To ogólnie dostępna wiedza. Wpisz w google.

PaSkol

unread,
Feb 18, 2015, 1:36:13 PM2/18/15
to
W dniu 2015-02-18 o 11:50, M.M. pisze:
> To ogólnie dostępna wiedza. Wpisz w google.

_Co_ takiego mam wpisać w Google, aby dostać materiał potwierdzający, że
indeks klastrowy został wprowadzony ponieważ zbiory danych są
przechowywane na dyskach talerzowych.

--
PaSkol (paskol.robi.to)

M.M.

unread,
Feb 19, 2015, 8:05:55 AM2/19/15
to
Właściwie to się nie tylko dysków talerzowych tyczy... Zawsze, gdy
wyszukanie danych spod 'losowego' adresu jest znacznie wolniejsze od
odczytu sekwencyjnego, warto zastanowić się nad reorganizacją
danych w tabelach.

Ja wpisałem tak w google: sql indeks klastrowy

Fragment z pierwszej strony w googlu:

Clustered Index swoją strukturą najbardziej przypomina książkę telefoniczną z ułożonymi alfabetycznie wpisami. Indeks ten nie jest odrębnym obiektem składowanym na dysku twardym. Jego podstawowym zadaniem jest narzucanie tabelom, w jaki sposób mają zapisywać wiersze na kolejnych stronach. Istotną informacją jest fakt, iż po utworzeniu indeksu grupującego, struktura stron tabeli podlega reorganizacji wg wskazań indeksu.

Pozdrawiam

PaSkol

unread,
Feb 19, 2015, 4:28:54 PM2/19/15
to
W dniu 2015-02-19 o 14:05, M.M. pisze:
> Właściwie to się nie tylko dysków talerzowych tyczy... Zawsze, gdy
> wyszukanie danych spod 'losowego' adresu jest znacznie wolniejsze od
> odczytu sekwencyjnego, warto zastanowić się nad reorganizacją
> danych w tabelach.

Rzecz w tym, że wybór jest zawsze pomiędzy stertą i uporządkowanym
ułożeniem danych. Zauważ jednak, że o ile indeks klastrowy przyspiesza
wyszukiwanie, to koszt jego utrzymania jest duży - wymaga bowiem
relokacji i to całego wiersza, ponieważ jest de facto porządkiem tabeli,
a nie "adresów" wierszy w tabeli.

Dlatego najczęściej jest zakładany na narastającej wartości, dzięki
czemu praktycznie znika problem relokacji (i ów koszt). Każdy kolejny
wiersz jest dodawany na końcu i pozostaje w zgodzie z indeksem. A
ponieważ owa narastająca wartość jest zazwyczaj także sztucznym kluczem
głównym tabeli więc zysk się powiększa - wszelkie złączenia są
najbardziej wydajne jak to tylko możliwe, bo po dokonaniu złączenia jest
się właśnie w miejscu, z którego można pobrać dane.

Bywa jednak i tak, że klucz nie jest sztuczny, ale naturalny (np. kod
paskowy albo jakiś symbol zrozumiały dla człowieka). Wówczas konieczne
są dodatkowe zabiegi, które pozwolą zachować dużą wydajność wyszukiwania
po takim indeksie, bo następuje jego defragmentacja oraz rosną puste
przestrzenie w stronach danych (tych o których mowa w przytoczonym przez
Ciebie fragmencie).

W temacie indeksu klastrowego należy także nadmienić, że ewentualna
potrzeba jego relokacji wymusza niepełność stron danych w pliku bazy. W
każdej musi bowiem zostać trochę miejsca na relokowane wiersze (jeśli
relokacja jest niewielka, bo czasem kończy się to powstaniem nowej
strony, a oddaniem dotychczasowej do ponownego użycia).

--
PaSkol (paskol.robi.to)
It is loading more messages.
0 new messages