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

Co wybrac - Identity czy sekwencje

143 views
Skip to first unread message

Pancio

unread,
Feb 13, 2018, 6:24:43 AM2/13/18
to
Witam,
Zaczynam bawic sie w pisane aplikacji w srodowisku Delphi XE7 i silniku MS SQL w wersji Express 2014 (taka wersja jest w firmie) lub 2016 (byc moze bedzie).
Chodzi mi o to, ze w kilku tabelach uzytkownicy powinni widziec numeracje rekordow ID. O ile do wersji MS SQLa 2008 R2 mozna bylo zastosowac IDENTITY to po wersji 2012 jest juz nieco bardziej problematyczne.
Otoz po restarcie silnika numeracja ID przeskakuje o 1000 rekordow. Nie jest to oczywiscie koniec swiata, ale tez nie wyglada najlepiej.
Poczytalem nieco o sekwencjach i znalazlem taki oto przykad:
CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL)

Problem w tym, ze spada troche wydajnosc bazy danych przy wprowadzaniu wiekszej liczby rekordow. Dlatego mam pytanie do Was?
Jakiego rozwiazania uzywacie w swoich projektach - z natury rzeczy Identity odpada, pozostaja sekwencje, a moze po prostu przed dodaniem rekordu powinienem wywolac SELECT Count(*) i sprawdzic ile rekordow jest w tabeli, po czym dodac +1.
Kazde rozwiazanie poprawnie dzialajace jest dobre, ale wiadomo, ze sa dobre i lepsze. Dlatego tez postanowilem zapytac sie bardziej doswiadczonych kolegow.

--
Pancio

wloochacz

unread,
Feb 13, 2018, 8:41:40 AM2/13/18
to
W dniu 2018-02-13 o 12:24, Pancio pisze:
/ciach/

Sekwencje.

--
wloochacz

mmm

unread,
Feb 13, 2018, 8:54:35 AM2/13/18
to
W dniu 2018-02-13 o 12:24, Pancio pisze:
> Otoz po restarcie silnika numeracja ID przeskakuje o 1000 rekordow. Nie jest to oczywiscie koniec swiata, ale tez nie wyglada najlepiej.
> --
> Pancio
>
Chciałbym miec takie problemy ;)
Koncepcja z SELECT Count(*) wydaje mi sie szalona. KOncepcja wymyślanie
własnych metod rozwiązywania problemu wydaje mi sie śmiała. Na pewno nie
będziesz się nudził w przyszłości jak ci się to posypie jak domek z kart.
Uzyj SEQUENCE

M

Pancio

unread,
Feb 13, 2018, 4:31:37 PM2/13/18
to
No i wszystko w temacie.
Czyli zamiast wymyslac tony wlasnych mniej lub bardziej szalnych pomyslow lepiej skorzystac ze sprawdzonych rozwiazan.
A tak juz zupelnie na marginesie, bez zbednej kokieterii - dlaczego rozwiazanie z SELECT (*) Count jest szalone i mialoby sie w przyszlosci posypac? Pytam zupelnie z ciekawosci. Bo moze nie jest to metoda, ktora moznaby polecic, ale dlaczego mialaby sie "sypnac"?

--
Pancio

MKi

unread,
Feb 14, 2018, 3:36:28 AM2/14/18
to
> No i wszystko w temacie.
> Czyli zamiast wymyslac tony wlasnych mniej lub bardziej szalnych pomyslow lepiej skorzystac ze sprawdzonych rozwiazan.
> A tak juz zupelnie na marginesie, bez zbednej kokieterii - dlaczego rozwiazanie z SELECT (*) Count jest szalone i mialoby sie w przyszlosci posypac? Pytam zupelnie z ciekawosci. Bo moze nie jest to metoda, ktora moznaby polecic, ale dlaczego mialaby sie "sypnac"?

Bo po skasowaniu rekordu z środka ilość nie będzie odpowiadała
liczbie maksymalnej?

To już lepiej SELECT MAX(s1).

Pozdrowienia,
MKi





Pancio

unread,
Feb 14, 2018, 4:36:50 AM2/14/18
to
> Bo po skasowaniu rekordu z środka ilość nie będzie odpowiadała
> liczbie maksymalnej?
>
> To już lepiej SELECT MAX(s1).

No fakt, nie wzialem tego pod uwage.
Tyle, ze nawet tutaj na grupie naczytalem sie, zeby starac sie unikac MAX(col).
Tak czy owak przejde na sekwencje, bo to chyba jest najprostsze (i najbardziej praktyczne) rozwiazanie.
Dzieki za szybka pomoc.

--
Pancio

Roman Tyczka

unread,
Feb 14, 2018, 6:02:02 AM2/14/18
to
I jedno i drugie jest du bani, nie z tych powodów co napisałeś.
Chodzi o atomowość operacji. Jeśli tego selecta zawołają jednocześnie die
końcówki i zaczną na wyniku działać to ...?
No właśnie.

--
pozdrawiam
Roman Tyczka

zpksoft

unread,
Feb 15, 2018, 3:09:30 AM2/15/18
to
W ogóle nie używam identyfikatorów liczbowych. Wyłącznie łańcuchowe. Zero problemów. Jeśli masz wybór to zastanów się nad tym. Bardzo duże bazy są oparte tylko na takich identyfikatorach. Zobacz np. filmiki na Youtube: https://youtu.be/jOqktpxdGxg <- tu ID=jOqktpxdGxg. Nie muszą martwić się że gdzieś w sieci ktoś podwójnie zlicza ID. Dodatkowym atutem jest to że taki identyfikator tworzy klient więc może posłużyć się nim zanim wpisze rekord do bazy (!).

Paweł

wloochacz

unread,
Feb 15, 2018, 5:32:40 AM2/15/18
to
W dniu 2018-02-15 o 09:09, zpksoft pisze:
> W dniu wtorek, 13 lutego 2018 12:24:43 UTC+1 użytkownik Pancio napisał:
/ciach/

> W ogóle nie używam identyfikatorów liczbowych. Wyłącznie łańcuchowe. Zero problemów. Jeśli masz wybór to zastanów się nad tym. Bardzo duże bazy są oparte tylko na takich identyfikatorach. Zobacz np. filmiki na Youtube: https://youtu.be/jOqktpxdGxg <- tu ID=jOqktpxdGxg. Nie muszą martwić się że gdzieś w sieci ktoś podwójnie zlicza ID. Dodatkowym atutem jest to że taki identyfikator tworzy klient więc może posłużyć się nim zanim wpisze rekord do bazy (!).

Jeżeli wartość takiego identyfikatora jest generowana jako rosnąca
funkcja monotoniczna, to jest najgorsze z możliwych rozwiązań, jeśli
idzie o wydajność.

Powoduje to poważne problemy z sortowaniem i fragmentacją indeksów.
Chcesz mieć pofragmentowany indeks Primary Key - używaj takich
identyfikatorów.

I właśnie dlatego np. w MS SQL jest specjalna funkcja do kreowania
GUIDów sekwencyjnych:
https://docs.microsoft.com/en-us/sql/t-sql/functions/newsequentialid-transact-sql

--
wloochacz

zpksoft

unread,
Feb 16, 2018, 2:58:40 AM2/16/18
to
Lata temu stosowałem GUID do tego celu, ale już od dawna stosuję inne rozwiązanie. U mnie identyfikatory łańcuchowe można by rzec są sekwencyjne, można nawet wyliczyć z nich czas powstania.
Niedawno jedna z baz które obsługuję przekroczyła 1TB i można by rzec że chodzi jak młódka. Ogólnie trudno jest przekonać programistów do tego typu identyfikatorów (bojaźń?). Niedawno miałem za zadanie zsynchronizować dwie bazy, ale w pewnym zakresie. Kilka tabel miało identyfikatory liczbowe. Niesamowitą jazdę z tym miałem bo właśnie liczbowe identyfikatory się powtarzały. Nie obeszło się bez zmian logiki w pluginie którego te tabele dotyczyły.

Paweł

zpksoft

unread,
Feb 16, 2018, 4:59:59 AM2/16/18
to
Dodam jeszcze że identyfikator tego wątku ma wartość "t9dNA03cFhc" :)

Paweł

wloochacz

unread,
Feb 16, 2018, 6:04:51 AM2/16/18
to
W dniu 2018-02-16 o 10:59, zpksoft pisze:
> Dodam jeszcze że identyfikator tego wątku ma wartość "t9dNA03cFhc" :)

Miałem podobne wymagania co do synchronizacji danych lata temu, zatem
powstał pomysł na identyfikator typu:
xxxx.yyyy

Gdzie:
xxxx - wartość z sekwencji
yyyy - identyfikator licencji/oddziału/etc.

Niby klucz złożony, a jednak prosty.
Poza tym, mega-prosto można wyekstrahować dane z odziały. Co w przypadku
hasha wcale nie jest takie oczywiste.

Nie twierdzę, że to jest lepsze czy gorsze rozwiązanie.
Jest jakieś i też się sprawdza.

--
wloochacz

goo-...@ciach.net

unread,
Feb 16, 2018, 5:07:08 PM2/16/18
to
W dniu piątek, 16 lutego 2018 10:59:59 UTC+1 użytkownik zpksoft napisał:
> Dodam jeszcze że identyfikator tego wątku ma wartość "t9dNA03cFhc" :)
>
> Paweł

ale się czepiasz...

zpksoft

unread,
Feb 17, 2018, 3:00:56 AM2/17/18
to
Ani mi w głowie czepianie się. Tylko podaję alternatywę. Docelowo... jedynie słuszną. Takie jest moje przekonanie.
Nie mam najmniejszego zamiaru walczyć z innymi przekonaniami.
Popróbuj identyfikatorów łańcuchowych to już się nie cofniesz.
Zauważyłem już dawno, że bardzo trudno jest programistów na to rozwiązanie namówić. Może dlatego, że podręczniki uczą tylko o liczbowych?
W każdym razie po zastosowaniu identyfikatorów łańcuchowych znika wiele problemów, m. in. z synchronizacją. Na przykład można pracować na oderwanej bazie a potem dane po prostu wrzucić do bazy głównej... Nie spotkamy się z takimi samymi identyfikatorami więc powinno pójść łatwo.
Kolejny przykład: można posłużyć się linkiem w postaci takiego identyfikatora żeby jednoznacznie dotrzeć do właściwego rekordu, nawet jeśli nie wiemy z jakiej tabeli pochodzi. A jak posłużysz się liczbą to nic to nie da...
Przykładów można by mnożyć. Zachęcam.

Paweł

wloochacz

unread,
Feb 17, 2018, 4:33:22 AM2/17/18
to
W dniu 2018-02-17 o 09:00, zpksoft pisze:
> Ani mi w głowie czepianie się. Tylko podaję alternatywę. Docelowo... jedynie słuszną.
No to pojechałeś, jedynie słuszną...
Ciekawym, co jeszcze jest wg Ciebie jedynie słuszne?

A w sumie nie jestem ciekawy.

> Takie jest moje przekonanie.
> Nie mam najmniejszego zamiaru walczyć z innymi przekonaniami.
Ale podajesz "jedynie słuszne" rozwiązania?

> Popróbuj identyfikatorów łańcuchowych to już się nie cofniesz.
No nie wiem, ten id jest dłuższy (znaczy więcej miejsca zajmuje) niż
numeryczny i kropka.

I pytanie - jaki ma typ zmienna na to ID w Twoim programie?

Poza tym, trudniej się go wpisuje z palca - ale to akurat żaden
argument... tylko jakiś.

> Zauważyłem już dawno, że bardzo trudno jest programistów na to rozwiązanie namówić. Może dlatego, że podręczniki uczą tylko o liczbowych?
A może dlatego, że to jedyne słuszne rozwiązanie? :)

> W każdym razie po zastosowaniu identyfikatorów łańcuchowych znika wiele problemów, m. in. z synchronizacją. Na przykład można pracować na oderwanej bazie a potem dane po prostu wrzucić do bazy głównej... Nie spotkamy się z takimi samymi identyfikatorami więc powinno pójść łatwo.
Jak się ą synchronizację robi na kolanie to może i tak :D
Poza tym, podałem inne rozwiązanie na ten problem, z wykorzystaniem
"jedynie" słusznego typu numerycznego.

> Kolejny przykład: można posłużyć się linkiem w postaci takiego identyfikatora żeby jednoznacznie dotrzeć do właściwego rekordu, nawet jeśli nie wiemy z jakiej tabeli pochodzi. A jak posłużysz się liczbą to nic to nie da...
Czytaj wyżej, bo to nieprawda.
A poza tym - link bezpośredni do rekordu w bazie danych?
Hmm... jakoś zestawienie tego pomysłu ze słowem "słuszne" budzi we mnie
nieokreślony, a wyraźny sprzeciw.

> Przykładów można by mnożyć. Zachęcam.
Ja również zachęcam, ale do myślenia i kwestionowania "jedynie
słusznych" rozwiązań.
Ponieważ w ten sposób może, ale nie musi, urodzić się coś ciekawego.

No i na koniec, inne pytanie; jak generujesz te identyfikatory?

--
wloochacz

zpksoft

unread,
Feb 17, 2018, 8:34:17 AM2/17/18
to
W dniu sobota, 17 lutego 2018 10:33:22 UTC+1 użytkownik wloochacz napisał:
> W dniu 2018-02-17 o 09:00, zpksoft pisze:
> > Ani mi w głowie czepianie się. Tylko podaję alternatywę. Docelowo... jedynie słuszną.
> No to pojechałeś, jedynie słuszną...
> Ciekawym, co jeszcze jest wg Ciebie jedynie słuszne?

To był żart.

>
> A w sumie nie jestem ciekawy.
>
> > Takie jest moje przekonanie.

A tu jego uzasadnienie.

> > Nie mam najmniejszego zamiaru walczyć z innymi przekonaniami.
> Ale podajesz "jedynie słuszne" rozwiązania?
>
> > Popróbuj identyfikatorów łańcuchowych to już się nie cofniesz.
> No nie wiem, ten id jest dłuższy (znaczy więcej miejsca zajmuje) niż
> numeryczny i kropka.
>
> I pytanie - jaki ma typ zmienna na to ID w Twoim programie?

char()

>
> Poza tym, trudniej się go wpisuje z palca - ale to akurat żaden
> argument... tylko jakiś.

W systemie który prowadzę można na tabeli wskazać rekord i z menu kontekstowego wybrać opcję "Kopiuj łącze"

Następnie po wklejeniu tego łącza np. do pola tekstowego działa to tak, że samo najechanie myszą na to łącze pojawia się hint z informacją co ono zawiera. Ctrl+klik na tym łączu otwiera odpowiedni moduł, inicjuje dane i wskazuje cel.

>
> > Zauważyłem już dawno, że bardzo trudno jest programistów na to rozwiązanie namówić. Może dlatego, że podręczniki uczą tylko o liczbowych?
> A może dlatego, że to jedyne słuszne rozwiązanie? :)
>

Zobacz gdzie idzie świat. Podałem dwa przykłady: ID na Youtube, ID tego wątku, możesz sobie obejrzeć np. moją partię szachów:
https://lichess.org/3FAcy8OcZxyu gdzie łatwo zauważyć że ID tej partii to "3FAcy8OcZxyu" itd.

> > W każdym razie po zastosowaniu identyfikatorów łańcuchowych znika wiele problemów, m. in. z synchronizacją. Na przykład można pracować na oderwanej bazie a potem dane po prostu wrzucić do bazy głównej... Nie spotkamy się z takimi samymi identyfikatorami więc powinno pójść łatwo.
> Jak się ą synchronizację robi na kolanie to może i tak :D
> Poza tym, podałem inne rozwiązanie na ten problem, z wykorzystaniem
> "jedynie" słusznego typu numerycznego.

Wybacz, ale moim zdaniem Twoje rozwiązanie jest słabe. Nie zsynchronizujesz tym sposobem dwóch baz które się nie widziały jakiś czas.

>
> > Kolejny przykład: można posłużyć się linkiem w postaci takiego identyfikatora żeby jednoznacznie dotrzeć do właściwego rekordu, nawet jeśli nie wiemy z jakiej tabeli pochodzi. A jak posłużysz się liczbą to nic to nie da...
> Czytaj wyżej, bo to nieprawda.
> A poza tym - link bezpośredni do rekordu w bazie danych?
> Hmm... jakoś zestawienie tego pomysłu ze słowem "słuszne" budzi we mnie
> nieokreślony, a wyraźny sprzeciw.
>
> > Przykładów można by mnożyć. Zachęcam.
> Ja również zachęcam, ale do myślenia i kwestionowania "jedynie
> słusznych" rozwiązań.
> Ponieważ w ten sposób może, ale nie musi, urodzić się coś ciekawego.
>
> No i na koniec, inne pytanie; jak generujesz te identyfikatory?

Początkowo, właściwie dla prób wykorzystywałem GUID. Ten brak sekwencyjności nie bardzo mi przeszkadzał bo user pyta zwykle o różną kolejność danych.
Chciałem zbudować uniwersalny ID łańcuchowy w którym zakodowany byłby czas i losowość. Udało mi się opracować identyfikator 12 znakowy np. wygenerowany w tym momencie: "1OeS9r2JykUj". Mogę z niego odczytać czas powstania z dokładnością do dwóch milisekund. Czas zawarty jest w członie "1OeS9r". Stosuję te identyfikatory mniej więcej od czerwca 2005 roku i jeszcze nigdy w żadnej bazie nie miałem błędu powstania dwóch takich samych identyfikatorów.

Mam spora doświadczenie w ich stosowaniu więc co jakiś czas próbuję namówić innych do ich stosowania. Ale ciężko. Bojaźń że coś źle pójdzie? Nie wnikam. Jak komuś coś zaświta to OK, plus dla mnie :)

>
> --
> wloochacz

Paweł

Pancio

unread,
Feb 19, 2018, 7:50:44 AM2/19/18
to
A to przy okazji zadam dodatkowe pytanie, zaznacze od razu na poczatku, ze dzialam w srodowisku Delphi XE7 + MS SQL Server 2014 Express.
W jednej z tabel wykorzystywac bede FileStream, a wiec w tej tabeli musi pojawic sie wiersz typu "uniqueidentifier".
W kodzie SQL generuje go w nastepujacy sposob: SELECT NEWID(), ale czy w samym Delphi moge korzystac z wbudowanej funkcji CreateGUID(Guid: TGUID)?
Testowalem to na kilku przykladach i poki co wyniki mnie zadowalaja, jednak nie chcialbym, aby po roku uzywania aplikacji, nagle zdublowaly sie te unikatowe identyfikatory.
Docelowo baza moze bedzie miala 150-200 tysiecy wierszy.
Uogolniajac pytanie - czy identyfikatory generowane przez samo Delphi jak i SQL Server mozna uznac jako jednakowo unikatowe?

--
Pancio

wloochacz

unread,
Feb 19, 2018, 11:22:52 AM2/19/18
to
W dniu 2018-02-19 o 13:50, Pancio pisze:
> Uogolniajac pytanie - czy identyfikatory generowane przez samo Delphi jak i SQL Server mozna uznac jako jednakowo unikatowe?
Jednakowo prawie unikatowe, aby być super precyzyjnym.
I nie generuj tego przez NEWID, tylko NEWSEQUENTIALID po stronie SQLa,
jeśli będzie to PK.
Pisałem o tym...

--
wloochacz

wloochacz

unread,
Feb 19, 2018, 11:36:04 AM2/19/18
to
W dniu 2018-02-17 o 14:34, zpksoft pisze:
/ciach/

>>> Popróbuj identyfikatorów łańcuchowych to już się nie cofniesz.
>> No nie wiem, ten id jest dłuższy (znaczy więcej miejsca zajmuje) niż
>> numeryczny i kropka.
>>
>> I pytanie - jaki ma typ zmienna na to ID w Twoim programie?
>
> char()
To jest typ bazodanowy.
Ja pytałem o typ zmiennej w Delphi.

>> Poza tym, trudniej się go wpisuje z palca - ale to akurat żaden
>> argument... tylko jakiś.
>
> W systemie który prowadzę można na tabeli wskazać rekord i z menu kontekstowego wybrać opcję "Kopiuj łącze"
>
> Następnie po wklejeniu tego łącza np. do pola tekstowego działa to tak, że samo najechanie myszą na to łącze pojawia się hint z informacją co ono zawiera. Ctrl+klik na tym łączu otwiera odpowiedni moduł, inicjuje dane i wskazuje cel.
>
>>
>>> Zauważyłem już dawno, że bardzo trudno jest programistów na to rozwiązanie namówić. Może dlatego, że podręczniki uczą tylko o liczbowych?
>> A może dlatego, że to jedyne słuszne rozwiązanie? :)
>>
>
> Zobacz gdzie idzie świat. Podałem dwa przykłady: ID na Youtube, ID tego wątku, możesz sobie obejrzeć np. moją partię szachów:
> https://lichess.org/3FAcy8OcZxyu gdzie łatwo zauważyć że ID tej partii to "3FAcy8OcZxyu" itd.
I co z tego?
Myślisz że za YT stoi zwykła relacyjna baza danych?
No to stoi, ale nie zwykła.
A wiec to żaden argument.

>>> W każdym razie po zastosowaniu identyfikatorów łańcuchowych znika wiele problemów, m. in. z synchronizacją. Na przykład można pracować na oderwanej bazie a potem dane po prostu wrzucić do bazy głównej... Nie spotkamy się z takimi samymi identyfikatorami więc powinno pójść łatwo.
>> Jak się ą synchronizację robi na kolanie to może i tak :D
>> Poza tym, podałem inne rozwiązanie na ten problem, z wykorzystaniem
>> "jedynie" słusznego typu numerycznego.
>
> Wybacz, ale moim zdaniem Twoje rozwiązanie jest słabe. Nie zsynchronizujesz tym sposobem dwóch baz które się nie widziały jakiś czas.
A dlaczego nie da się ich zsynchronizować?
Przecież ten PK nie jest globalny, ale unikalny w kontekście jego
miejsca powstania.
Nie ma duplikatów w bazie centralnej, ponieważ:
1. PK z bazy A będzie mało wartość: 1.0001
2. PK z bazy B będzie mało wartość: 1.0002

Nie widzę żadnego problemu, a kolejną zaletę - mam sekwencyjną wartość.
Poza tym mogę łatwo wyjąć rekordy, które powstały w bazie A czy B tylko
na podstawie samej wartości PK.

Oczywiście jakimś tam problemem jest nadawanie stałej i unikalnej
wartości po przecinku. Wymaga to centralnego repozytorium i właśnie
dlatego ta wartość idzie z licencją, która jest generowana w centralnym
repo.

A więc, gdzie tu słabość?

>>> Kolejny przykład: można posłużyć się linkiem w postaci takiego identyfikatora żeby jednoznacznie dotrzeć do właściwego rekordu, nawet jeśli nie wiemy z jakiej tabeli pochodzi. A jak posłużysz się liczbą to nic to nie da...
>> Czytaj wyżej, bo to nieprawda.
>> A poza tym - link bezpośredni do rekordu w bazie danych?
>> Hmm... jakoś zestawienie tego pomysłu ze słowem "słuszne" budzi we mnie
>> nieokreślony, a wyraźny sprzeciw.
>>
>>> Przykładów można by mnożyć. Zachęcam.
>> Ja również zachęcam, ale do myślenia i kwestionowania "jedynie
>> słusznych" rozwiązań.
>> Ponieważ w ten sposób może, ale nie musi, urodzić się coś ciekawego.
>>
>> No i na koniec, inne pytanie; jak generujesz te identyfikatory?
>
> Początkowo, właściwie dla prób wykorzystywałem GUID. Ten brak sekwencyjności nie bardzo mi przeszkadzał bo user pyta zwykle o różną kolejność danych.
Skoro tak piszesz, to chyba nie do końca rozumiesz jak działa baza
relacyjna.

> Chciałem zbudować uniwersalny ID łańcuchowy w którym zakodowany byłby czas i losowość. Udało mi się opracować identyfikator 12 znakowy np. wygenerowany w tym momencie: "1OeS9r2JykUj". Mogę z niego odczytać czas powstania z dokładnością do dwóch milisekund. Czas zawarty jest w członie "1OeS9r". Stosuję te identyfikatory mniej więcej od czerwca 2005 roku i jeszcze nigdy w żadnej bazie nie miałem błędu powstania dwóch takich samych identyfikatorów.
Unikalność to nie problem, ale co z sekwencyjnością?

> Mam spora doświadczenie w ich stosowaniu więc co jakiś czas próbuję namówić innych do ich stosowania. Ale ciężko. Bojaźń że coś źle pójdzie? Nie wnikam. Jak komuś coś zaświta to OK, plus dla mnie :)
Tu nie chodzi o bojaźń, tylko o możliwe problemy wydajnościowe z
przyczyn, które można wyeliminować na samym początku.

To, że Ty ich nie masz (problemów wydajnościowych), nie oznacza że np.
ja ich nie będę miał.
Zapewniam Cię, że mamy zupełnie różne wymagania co bazy danych i jej
architektury.

--
wloochacz

Roman Tyczka

unread,
Feb 19, 2018, 12:28:16 PM2/19/18
to
On Mon, 19 Feb 2018 17:36:02 +0100, wloochacz wrote:

>> Początkowo, właściwie dla prób wykorzystywałem GUID. Ten brak sekwencyjności nie bardzo mi przeszkadzał bo user pyta zwykle o różną kolejność danych.
> Skoro tak piszesz, to chyba nie do końca rozumiesz jak działa baza
> relacyjna.
>
>> Chciałem zbudować uniwersalny ID łańcuchowy w którym zakodowany byłby czas i losowość. Udało mi się opracować identyfikator 12 znakowy np. wygenerowany w tym momencie: "1OeS9r2JykUj". Mogę z niego odczytać czas powstania z dokładnością do dwóch milisekund. Czas zawarty jest w członie "1OeS9r". Stosuję te identyfikatory mniej więcej od czerwca 2005 roku i jeszcze nigdy w żadnej bazie nie miałem błędu powstania dwóch takich samych identyfikatorów.
> Unikalność to nie problem, ale co z sekwencyjnością?

Tak z ciekawości... po co sekwencyjność w PK? PK ma za zadanie gwarantować
unikalność i to jest jego fundamentalna cecha. Baza i tak jak potrzeba to
ma jakieś kolumny z timestampem czy innym kluczem trzymającym sekwencyjność
w jakimś kontekście typu data urodzenia, data sprzedaży, numer kolejny
dokumentu sprzedaży itp. Po co więc tak bardzo forsujesz konieczność
posiadania sekwencyjności w PK?

--
pozdrawiam
Roman Tyczka

wloochacz

unread,
Feb 19, 2018, 4:53:39 PM2/19/18
to
W dniu 2018-02-19 o 18:28, Roman Tyczka pisze:
> On Mon, 19 Feb 2018 17:36:02 +0100, wloochacz wrote:
>
>>> Początkowo, właściwie dla prób wykorzystywałem GUID. Ten brak sekwencyjności nie bardzo mi przeszkadzał bo user pyta zwykle o różną kolejność danych.
>> Skoro tak piszesz, to chyba nie do końca rozumiesz jak działa baza
>> relacyjna.
>>
>>> Chciałem zbudować uniwersalny ID łańcuchowy w którym zakodowany byłby czas i losowość. Udało mi się opracować identyfikator 12 znakowy np. wygenerowany w tym momencie: "1OeS9r2JykUj". Mogę z niego odczytać czas powstania z dokładnością do dwóch milisekund. Czas zawarty jest w członie "1OeS9r". Stosuję te identyfikatory mniej więcej od czerwca 2005 roku i jeszcze nigdy w żadnej bazie nie miałem błędu powstania dwóch takich samych identyfikatorów.
>> Unikalność to nie problem, ale co z sekwencyjnością?
>
> Tak z ciekawości... po co sekwencyjność w PK?
Performance!

> PK ma za zadanie gwarantować
> unikalność i to jest jego fundamentalna cecha.
Tak, ale co wyszukiwaniem danych?
A wyszukiwanie to również złączenia.

> Baza i tak jak potrzeba to
> ma jakieś kolumny z timestampem czy innym kluczem trzymającym sekwencyjność
> w jakimś kontekście typu data urodzenia, data sprzedaży, numer kolejny
> dokumentu sprzedaży itp. Po co więc tak bardzo forsujesz konieczność
> posiadania sekwencyjności w PK?
No naprawdę...

Pierwsze z brzegu:
https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439

Krótko: fragmentacja, a to nas prowadzi do kolejnych wniosków:
https://blog.sqlauthority.com/2007/03/30/sql-server-index-seek-vs-index-scan-table-scan/

itd. itp.

W każdej bazie jest mniej więcej podobnie.

Poza tym, Paweł pisze o tym, że taki YT ma coś jak UUID jako klucz. Nie
wydaje mi się. Wydaje mi się, że na zewnątrz jest to UUID, ale wewnątrz
systemu jest to inna wartość (np. Int64), która nie jest eksponowana na
zewnątrz.
Ale w sumie nie mam na moje "wydaje się" dowodów na to i nie chce mi się
szukać.

--
wloochacz

zpksoft

unread,
Feb 20, 2018, 2:52:46 AM2/20/18
to
W dniu poniedziałek, 19 lutego 2018 17:36:04 UTC+1 użytkownik wloochacz napisał:
> W dniu 2018-02-17 o 14:34, zpksoft pisze:
> /ciach/
>
> >>> Popróbuj identyfikatorów łańcuchowych to już się nie cofniesz.
> >> No nie wiem, ten id jest dłuższy (znaczy więcej miejsca zajmuje) niż
> >> numeryczny i kropka.
> >>
> >> I pytanie - jaki ma typ zmienna na to ID w Twoim programie?
> >
> > char()
> To jest typ bazodanowy.
> Ja pytałem o typ zmiennej w Delphi.

string

<ciach>
> > Wybacz, ale moim zdaniem Twoje rozwiązanie jest słabe. Nie zsynchronizujesz tym sposobem dwóch baz które się nie widziały jakiś czas.
> A dlaczego nie da się ich zsynchronizować?
> Przecież ten PK nie jest globalny, ale unikalny w kontekście jego
> miejsca powstania.
> Nie ma duplikatów w bazie centralnej, ponieważ:
> 1. PK z bazy A będzie mało wartość: 1.0001
> 2. PK z bazy B będzie mało wartość: 1.0002
>
> Nie widzę żadnego problemu, a kolejną zaletę - mam sekwencyjną wartość.
> Poza tym mogę łatwo wyjąć rekordy, które powstały w bazie A czy B tylko
> na podstawie samej wartości PK.
>
> Oczywiście jakimś tam problemem jest nadawanie stałej i unikalnej
> wartości po przecinku. Wymaga to centralnego repozytorium i właśnie
> dlatego ta wartość idzie z licencją, która jest generowana w centralnym
> repo.
>
> A więc, gdzie tu słabość?
>

Słabość jest w tym, że musisz pilnować unikalności samej bazy, czyli czynnika A, B...

<ciach>
> --
> wloochacz

Paweł

zpksoft

unread,
Feb 20, 2018, 5:30:41 AM2/20/18
to
Owa sekwencyjność jest moim zdaniem przereklamowana.
Nawet jeśli pole typu integer stanowi indeks unikalny to wcale nie oznacza, że nie możemy wrzucić do bazy dane w kolejności 1, 5, 4, 7, 3.
Najważniejsza jest unikalność.
To nie określone pole jest indeksem tylko dla określonego pola możemy zdefiniować indeks. Oznacza to tyle, że baza oprócz naszej kolumny w tabeli przechowuje oddzielnie również swój porządek.
Najłatwiej przekonać się o tym wywołując select na zwykłej kolumnie łańcuchowej.
Baza będzie szukać długo.
Jeśli nałożymy indeks na tę kolumnę to szukanie będzie błyskawiczne, niezależnie od tego czy dane w tej kolumnie będą sekwencyjne.

Paweł

wloochacz

unread,
Feb 20, 2018, 8:06:04 AM2/20/18
to
W dniu 2018-02-20 o 08:52, zpksoft pisze:
> W dniu poniedziałek, 19 lutego 2018 17:36:04 UTC+1 użytkownik wloochacz napisał:
>> W dniu 2018-02-17 o 14:34, zpksoft pisze:
>> /ciach/
>>
>>>>> Popróbuj identyfikatorów łańcuchowych to już się nie cofniesz.
>>>> No nie wiem, ten id jest dłuższy (znaczy więcej miejsca zajmuje) niż
>>>> numeryczny i kropka.
>>>>
>>>> I pytanie - jaki ma typ zmienna na to ID w Twoim programie?
>>>
>>> char()
>> To jest typ bazodanowy.
>> Ja pytałem o typ zmiennej w Delphi.
>
> string
Skoro to char(12), to powinien być to:
type
TdbPKType = string[12];

ewentualnie ShortString.
Ale ja Cię uczył nie będę, ponieważ przecież wiesz lepiej.

Przesadzam?
Być może.

Poza tym, takie podejście ma sens jeśli programujesz zgodnie z OOP i
używasz np. DTO i serwera aplikacyjnego, a złożyłem że tak jest.
I pewnie się zagalopowałem :/

> <ciach>
>>> Wybacz, ale moim zdaniem Twoje rozwiązanie jest słabe. Nie zsynchronizujesz tym sposobem dwóch baz które się nie widziały jakiś czas.
>> A dlaczego nie da się ich zsynchronizować?
>> Przecież ten PK nie jest globalny, ale unikalny w kontekście jego
>> miejsca powstania.
>> Nie ma duplikatów w bazie centralnej, ponieważ:
>> 1. PK z bazy A będzie mało wartość: 1.0001
>> 2. PK z bazy B będzie mało wartość: 1.0002
>>
>> Nie widzę żadnego problemu, a kolejną zaletę - mam sekwencyjną wartość.
>> Poza tym mogę łatwo wyjąć rekordy, które powstały w bazie A czy B tylko
>> na podstawie samej wartości PK.
>>
>> Oczywiście jakimś tam problemem jest nadawanie stałej i unikalnej
>> wartości po przecinku. Wymaga to centralnego repozytorium i właśnie
>> dlatego ta wartość idzie z licencją, która jest generowana w centralnym
>> repo.
>>
>> A więc, gdzie tu słabość?
>>
>
> Słabość jest w tym, że musisz pilnować unikalności samej bazy, czyli czynnika A, B...
Napisałem Ci jak można sobie z tym poradzić, aby miało to ręce i nogi.
Trzeba było nie ciachać...

A poza tym - nagle uważasz, że da się synchronizować bazy danych, które
się nie widziały od dawna?

--
wloochacz

Roman Tyczka

unread,
Feb 20, 2018, 8:09:20 AM2/20/18
to
On Tue, 20 Feb 2018 02:30:39 -0800 (PST), zpksoft wrote:

>>>> Początkowo, właściwie dla prób wykorzystywałem GUID. Ten brak sekwencyjności nie bardzo mi przeszkadzał bo user pyta zwykle o różną kolejność danych.
>>> Skoro tak piszesz, to chyba nie do końca rozumiesz jak działa baza
>>> relacyjna.
>>>
>>>> Chciałem zbudować uniwersalny ID łańcuchowy w którym zakodowany byłby czas i losowość. Udało mi się opracować identyfikator 12 znakowy np. wygenerowany w tym momencie: "1OeS9r2JykUj". Mogę z niego odczytać czas powstania z dokładnością do dwóch milisekund. Czas zawarty jest w członie "1OeS9r". Stosuję te identyfikatory mniej więcej od czerwca 2005 roku i jeszcze nigdy w żadnej bazie nie miałem błędu powstania dwóch takich samych identyfikatorów.
>>> Unikalność to nie problem, ale co z sekwencyjnością?
>>
>> Tak z ciekawości... po co sekwencyjność w PK? PK ma za zadanie gwarantować
>> unikalność i to jest jego fundamentalna cecha. Baza i tak jak potrzeba to
>> ma jakieś kolumny z timestampem czy innym kluczem trzymającym sekwencyjność
>> w jakimś kontekście typu data urodzenia, data sprzedaży, numer kolejny
>> dokumentu sprzedaży itp. Po co więc tak bardzo forsujesz konieczność
>> posiadania sekwencyjności w PK?
>
> Owa sekwencyjność jest moim zdaniem przereklamowana.
> Nawet jeśli pole typu integer stanowi indeks unikalny to wcale nie oznacza, że nie możemy wrzucić do bazy dane w kolejności 1, 5, 4, 7, 3.
> Najważniejsza jest unikalność.
> To nie określone pole jest indeksem tylko dla określonego pola możemy zdefiniować indeks. Oznacza to tyle, że baza oprócz naszej kolumny w tabeli przechowuje oddzielnie również swój porządek.
> Najłatwiej przekonać się o tym wywołując select na zwykłej kolumnie łańcuchowej.
> Baza będzie szukać długo.
> Jeśli nałożymy indeks na tę kolumnę to szukanie będzie błyskawiczne, niezależnie od tego czy dane w tej kolumnie będą sekwencyjne.

No jednak nie do końca. Poczytaj to co wloochacz zalinkował.
I to ma jednak sens. Jeśli kolumna ma wartości sekwencyjne to indeks będzie
dużo skuteczniej zbudowany i mniej odczytów będzie potrzebnych by go
przeskanować. Nawet użycie algorytmu typu b+tree nie zniweluje zupełnie
konieczności większej liczby odczytów indeksu niż wtedy, gdy jest on
sekwencyjny (tu nawet prostackie wyszukiwanie binarne będzie szybkie).

--
pozdrawiam
Roman Tyczka

wloochacz

unread,
Feb 20, 2018, 8:19:03 AM2/20/18
to
W dniu 2018-02-20 o 11:30, zpksoft pisze:
/ciach/

> Owa sekwencyjność jest moim zdaniem przereklamowana.
A to zdanie opierasz na czym?
Zaklinaniu?

> Nawet jeśli pole typu integer stanowi indeks unikalny to wcale nie oznacza, że nie możemy wrzucić do bazy dane w kolejności 1, 5, 4, 7, 3.
Możemy, a jakże.
Ale po to się buduje AutoNumer, sekwencje czy generatory, aby tak tego
nie robić.
To, ze coś można zrobić, nie oznacza, że tak powinno się robić.
Tłumaczę od wczoraj, dlaczego nie powinno się tak tego robić.
Ale grochem o ścianę - przecież Wam działa błyskawicznie, tzn. jest
super-duper.
Otóż - nie jest.

> Najważniejsza jest unikalność.
Skoro tak uważasz, to mam dla Ciebie propozycję.
Zrezygnuj z Primary Key i załóż tylko ograniczenie na unikalność
wartości pola.

> To nie określone pole jest indeksem tylko dla określonego pola możemy zdefiniować indeks.
Indeks posiada wartości z pola, na podstawie którego jest zbudowany.
Tworzony jest przyrostowe wg dodawanych wartości do tabeli wg pola.
Dlatego tak ważna jest sekwencyjność danych dla wartości pól dla indeksu
Primary Key.

> Oznacza to tyle, że baza oprócz naszej kolumny w tabeli przechowuje oddzielnie również swój porządek.
> Najłatwiej przekonać się o tym wywołując select na zwykłej kolumnie łańcuchowej.
> Baza będzie szukać długo.
> Jeśli nałożymy indeks na tę kolumnę to szukanie będzie błyskawiczne, niezależnie od tego czy dane w tej kolumnie będą sekwencyjne.
Wyszukiwanie będzie szybsze, ponieważ użyty zostanie indeks.
Ale nie zostanie użyte wyszukiwanie w indeksie, tylko skanowanie
indeksu. Taka to drobna różnica...
Oczywiście to i tak lepiej niż full-scan-table, ale gorzej niż index-seek.
A to jest ciut dalej od "błyskawicznie".
A to z kolei oznacza, że nawet nie rzuciłeś okiem na linki, które
podesłałem.

--
wloochacz

wloochacz

unread,
Feb 20, 2018, 8:20:02 AM2/20/18
to
W dniu 2018-02-20 o 14:09, Roman Tyczka pisze:
> No jednak nie do końca. Poczytaj to co wloochacz zalinkował.
> I to ma jednak sens. Jeśli kolumna ma wartości sekwencyjne to indeks będzie
> dużo skuteczniej zbudowany i mniej odczytów będzie potrzebnych by go
> przeskanować. Nawet użycie algorytmu typu b+tree nie zniweluje zupełnie
> konieczności większej liczby odczytów indeksu niż wtedy, gdy jest on
> sekwencyjny (tu nawet prostackie wyszukiwanie binarne będzie szybkie).
Właśnie!
W końcu do kogoś dotarło :D

--
wloochacz

Krzysztof Szyszka

unread,
Feb 20, 2018, 1:59:57 PM2/20/18
to
> > Jeśli nałożymy indeks na tę kolumnę to szukanie będzie błyskawiczne, niezależnie od tego czy
> > dane w tej kolumnie będą sekwencyjne.
> Wyszukiwanie będzie szybsze, ponieważ użyty zostanie indeks.
> Ale nie zostanie użyte wyszukiwanie w indeksie, tylko skanowanie indeksu. Taka to drobna
> różnica...
> Oczywiście to i tak lepiej niż full-scan-table, ale gorzej niż index-seek.

Tak sobie czytam te wasze rozważania i mam kilka uwag:

Dlaczego uważasz, że "nie zostanie użyte wyszukiwanie w indeksie, tylko skanowanie indeksu"?
Przecież po to zakłada się indeks na danym polu, żeby wyszukiwać po indeksie, bo indeks z założenia
jest zawsze sekwencyjny,
a głównym kosztem wyszukiwania po indeksie jest czas porównania indeksowanych wartości, który zawsze
będzie większy dla
stringów, niż dla prostego INT.

Skoro wartości w kolumnie są sekwencyjne, to indeks założony na tej kolumnie będzie powielał
kolejność rekordów w tabeli.
Zyskiem podczas wyszukiwania jest odczyt indeksu o mniejszych rozmiarach, zamiast odczytu pełnych
rekordów z tabeli.
Natomiast aktualizacja takiego indeksu po dodaniu nowych rekordów będzie szybsza, bo jedynie
dopisujemy kolejne wartości
na końcu bez konieczności przebudowywania indeksu na początku, czy w środku i według mnie to jest
jedyny zysk ze stosowania
sekwencyjnego PK, ale to będzie odczuwalne dopiero przy naprawdę dużych tabelach.

I jeszcze jedno osobiste pytanie: dlaczego wybrałeś jako PK typ rzeczywisty, a nie np. BIG INT
(Int64), na którym mógłbyś
dokonać takiego samego podziału na numer z bazy danych i numer z licencji, a przy porównaniach
powinien być szybszy?


--
pozdrowienia
Krzysztof Szyszka, X-Files Software
Developer of X-DBGrid Component
Embarcadero Technology Partner
http://www.x-files.pl/
Join to "Delphi X-DBGrid Component Community"
https://plus.google.com/#communities/100842098152269100547

zpksoft

unread,
Feb 20, 2018, 2:05:42 PM2/20/18
to
Poczytałem. Jednak nie ekscytował bym się zbytnio tymi publikacjami. Szczególnie w jednym autor sprawiał wrażenie że nie bardzo rozumie co się dzieje jeżeli utworzymy indeks na kolumnie tekstowej. Ale to tylko moje zdanie.
Pracuję od lat prawie wyłącznie na indeksach łańcuchowych więc wiem jaka jest sprawność bazy, szybkość złożonych zapytań.
Naprawdę nie ma się czego bać.

Paweł

zpksoft

unread,
Feb 20, 2018, 2:12:32 PM2/20/18
to
W dniu wtorek, 20 lutego 2018 14:19:03 UTC+1 użytkownik wloochacz napisał:
> W dniu 2018-02-20 o 11:30, zpksoft pisze:
> /ciach/
> Oczywiście to i tak lepiej niż full-scan-table, ale gorzej niż index-seek.
> A to jest ciut dalej od "błyskawicznie".
> A to z kolei oznacza, że nawet nie rzuciłeś okiem na linki, które
> podesłałem.
>
> --
> wloochacz

Poczytałem, ale nie są one pisane przez kogoś kto ma doświadczenie w indeksach łańcuchowych.
Generalnie: liczba będzie szybsza do przetworzenia niż łańcuch, chociażby ze względu na ilość zajmowanej pamięci. Jednak uważam, że warto wejść w indeksy łańcuchowe bo są zaskakująco szybkie (!).

Paweł

zpksoft

unread,
Feb 20, 2018, 2:19:34 PM2/20/18
to
W dniu wtorek, 20 lutego 2018 14:06:04 UTC+1 użytkownik wloochacz napisał:
> W dniu 2018-02-20 o 08:52, zpksoft pisze:
> > W dniu poniedziałek, 19 lutego 2018 17:36:04 UTC+1 użytkownik wloochacz napisał:
> >> W dniu 2018-02-17 o 14:34, zpksoft pisze:
> >> /ciach/
> >>
> >>>>> Popróbuj identyfikatorów łańcuchowych to już się nie cofniesz.
> >>>> No nie wiem, ten id jest dłuższy (znaczy więcej miejsca zajmuje) niż
> >>>> numeryczny i kropka.
> >>>>
> >>>> I pytanie - jaki ma typ zmienna na to ID w Twoim programie?
> >>>
> >>> char()
> >> To jest typ bazodanowy.
> >> Ja pytałem o typ zmiennej w Delphi.
> >
> > string
> Skoro to char(12), to powinien być to:
> type
> TdbPKType = string[12];
>
> ewentualnie ShortString.
> Ale ja Cię uczył nie będę, ponieważ przecież wiesz lepiej.
>
> Przesadzam?
> Być może.
>

A po co Ci to było? Żeby mi udowodnić że nie wiem co to ShortString? Cze żeby się popisać? Tylko nie wiem czym.

> > <ciach>
>
> A poza tym - nagle uważasz, że da się synchronizować bazy danych, które
> się nie widziały od dawna?

Moje? Tak.

>
> --
> wloochacz

Paweł

Miroo

unread,
Feb 21, 2018, 2:50:31 AM2/21/18
to
W dniu 2018-02-19 o 18:28, Roman Tyczka pisze:
O ile dobrze pamiętam to np w MSSQL rekordy tabeli są ułożone wg klucza
głównego i wg niego dzielone na strony.
Gdy wstawiasz nowy rekord z PK > max(PK) to się po prostu dopisuje na
końcu, jeśli min(PK) < PK < max(PK) to rekord wstawiany jest w środek i
dane trzeba przesuwać, często wstawiać nowe strony w środek tabeli, a to
mocno wpływa na wydajność i powoduje dużą fragmentację bazy (co też
wpływa na wydajność).

GUID (sekwencyjny czy nie) ma jeszcze jedną dużą wadę - rozmiar. Przez
duży rozmiar w cache mieści znacznie mniej informacji (np o joinach) i
serwer częściej musi sięgać do danych fizycznych na dysku.

Pozdrawiam

wloochacz

unread,
Mar 1, 2018, 6:23:07 AM3/1/18
to
W dniu 2018-02-20 o 19:59, Krzysztof Szyszka pisze:
>> > Jeśli nałożymy indeks na tę kolumnę to szukanie będzie błyskawiczne,
>> niezależnie od tego czy > dane w tej kolumnie będą sekwencyjne.
>> Wyszukiwanie będzie szybsze, ponieważ użyty zostanie indeks.
>> Ale nie zostanie użyte wyszukiwanie w indeksie, tylko skanowanie
>> indeksu. Taka to drobna różnica...
>> Oczywiście to i tak lepiej niż full-scan-table, ale gorzej niż
>> index-seek.
>
> Tak sobie czytam te wasze rozważania i mam kilka uwag:
>
> Dlaczego uważasz, że "nie zostanie użyte wyszukiwanie w indeksie, tylko
> skanowanie indeksu"?
> Przecież po to zakłada się indeks na danym polu, żeby wyszukiwać po
> indeksie, bo indeks z założenia jest zawsze sekwencyjny,
Czepiłem się właśnie wartości *niesekwencyjnych* dla indeksów, zwłaszcza
klastrowych - czyli PK.
A takie założenie zmienia postać rzeczy, prawda?

Naprawdę nie chce mi się tłumaczyć niuansów, zwłaszcza osobom którym
przecież działa.
No i na zdrowie.

> a głównym kosztem wyszukiwania po indeksie jest czas porównania
> indeksowanych wartości, który zawsze będzie większy dla
> stringów, niż dla prostego INT.
Nie chodzi o wielkość danych sensu stricte, ale oczywiście to też ma
znaczenie.

> Skoro wartości w kolumnie są sekwencyjne, to indeks założony na tej
> kolumnie będzie powielał kolejność rekordów w tabeli.
Generalnie tak, ale niekoniecznie.
Poza tym, dlatego na samym początku pisałem o wartościach generowanych
przez rosnącą funkcję monotoniczną - przeoczyłeś?

> Zyskiem podczas wyszukiwania jest odczyt indeksu o mniejszych
> rozmiarach, zamiast odczytu pełnych rekordów z tabeli.
> Natomiast aktualizacja takiego indeksu po dodaniu nowych rekordów będzie
> szybsza, bo jedynie dopisujemy kolejne wartości
> na końcu bez konieczności przebudowywania indeksu na początku, czy w
> środku i według mnie to jest jedyny zysk ze stosowania
> sekwencyjnego PK, ale to będzie odczuwalne dopiero przy naprawdę dużych
> tabelach.
Zakładasz wartości sekwencyjne dla indeksu.
Ja pisałem o przypadku dokładnie odwrotnym bo taki to został podniesiony
jako super-duper rewelacja na wartości dla PK.

A to g...o prawda!

> I jeszcze jedno osobiste pytanie: dlaczego wybrałeś jako PK typ
> rzeczywisty, a nie np. BIG INT (Int64), na którym mógłbyś
> dokonać takiego samego podziału na numer z bazy danych i numer z
> licencji, a przy porównaniach powinien być szybszy?
Dlaczego szybszy, skoro mój typ to nie jakiś tam float, a
stałoprzecinkowy, który jest reprezentowany jako Int64 (e.g. Currency w
Delphi) właśnie?

A poza tym, tak mi się zwyczajnie wydawało wygodniej.

--
wloochacz
0 new messages