wtorek, 15 stycznia 2013

Budowanie wykazów nazw

Ostatnimi czasy dużo się działo w kwestii QAZP2. Ostatnie poprawki błędów, niekiedy dość poważnych, nowe funkcjonalności - na przykład wykonywanie skryptów modyfikujących zawartość bazy danych - co może mieć znaczenie, gdy osoba odpowiadająca za techniczny aspekt bazy połączonej z QAZP2 nie ma do niej bezpośredniego dostępu. W takim wypadku wystarczy spreparować skrypt SQL i wysłać do użytkownika, który za pomocą interfejsu graficznego aplikuje przygotowane zmiany. Rzecz jasna taki mechanizm jest pewnym zagrożeniem dla stanu bazy danych, jednak jest to koszt, który można ponieść, pamiętając, by nie stosować skryptów z niepewnego źródła. Między innymi z tego powodu trudno było mi znaleźć czas i spełnić obietnicę, że nowe artykuły będą wprowadzane conajmniej raz na tydzień.

Ostatnimi czasy na blogu była poruszana kwestia wykazów pojęć archeologicznych, których używa się do klasyfikacji kulturowo-funkcjonalno-historycznej. W QAZP2 wykorzystywane są do tego wykazy przygotowane w Narodowym Instytucie Dziedzictwa i uzupełnione o nazwy, których obecności wymaga praktyka badań archeologicznych. Ich konstrukcję próbowałem opisać w poprzednim artykule, natomiast dzisiaj chciałbym przedstawić inne podejście, które chociaż nie zostało wdrożone, to wydaje się ciekawą alternatywą dla wyżej wspomnianego sposobu budowania wykazów.



1. Rekord z informacją o jednostce kulturowej Z składa się z trzech segmentów:

  • segment E: nazwa epoki, np. “paleolit”, “neolit”, “epoka brązu”, itd,
  •  segment K: nazwa jednostki pierwszego rzędu w ramach typologii jednostek kulturowych, np. “technokompleks oryniacki”, “cykl wiślański”, “kultura pucharów lejkowatych”
  • segment F: nazwa jednostki drugiego rzędu w ramach typologii jednostek kulturowych np. “kultura oryniacka”, “grupa mątewska”, itd.

Informacja zapisana jako liczba w systemie dwójkowym albo dziesiętnym jest oznaczana odpowiednio jako bZ albo dZ

2. Pełna informacja jest zapisywana w polu mieszczącym 32-bitową liczbę całkowitą typu Integer. Ponieważ stosowane są tylko liczby większe od 0, to dwa najbardziej znaczące bity nie są wykorzystywane.

3. Do każdego segmentów przypisywana jest para wartości (n, c), gdzie n określa maksymalną liczbę bitów, które mogą być użyte do zakodowania nazwy z danego segmentu, a c liczbę nazw które mogą być zakodowane za pomocą n bitów i jest wyliczana ze wzoru (2**n). Suma liczby użytych bitów we wszystkich segmentach, gdy stosuje się liczbę 32-bitową powinna być mniejsza lub równa 30.

Przykład 1. 
  • Segment E: (nE = 3, cE = 7),
  • Segment K: (nK = 5, cK = 31),
  • Segment F: (nF = 7, cF = 127) 
4. Generowanie identyfikatorów nazw
  • zbiór identyfikatorów nazw dla segmentu E: Ie = {i | i >= 1 & i < 2**nE}
  •  zbiór identyfikatorów nazw dla segmentu K: Ik = {i | i >=2**nE & i < 2**(nE+nK) & i mod nE = 0}
  • zbiór identyfikatorów nazw dla segmentu F: If = {i | i >=2**(nE+nK) & i < 2**(nE+nK+nF) & i mod (nE+nK) = 0}
5. Tworzenie informacji o fazie zasiedlenia:
  • binarne: przez operację sumy logicznej wybranych identyfikatorów segmentów iF | iK | iF
  • arytmetyczne: przez sumowanie wybranych identyfikatorów segmentów iE + iK + iF
  • Uzyskana w ten sposób liczba jest zbudowana conajwyżej J = nE+nK+nF bitów. Jeżeli dwie informacje różnią się conajmniej jednym identyfikatorem segmentów, to kody informacji są różne.
 
6. Wyszukiwanie informacji
Dla każdego segmentu zdefiniowanego parą liczb (n, c) istnieje liczba nazywana maską M, równa maksymalnemu identyfikatorowi przewidzianemu dla nazw z danego segmentu. Łącząc maskę z bZ albo dZ za pomocą operatora koniunkcji & uzyskuje się identyfikator nazwy z wybranego segmentu.

Przykład:
bZ = 0000000 10101 110
dZ = 174
bM = 0000000 11111 000
dM = 248

bZ & bM = 0000000 10101 000
dZ & dM = 168

Żeby sprawdzić, czy bZ albo dZ zawiera wybrany identyfikator nazwy oblicza się koniunkcję z informacji oraz identyfikatora. Jeżeli wynik jest równy wartości identyfikatora, to znaczy, że informacja ją zawiera

Przykład
dZ = 174
i = 7
w = dZ & i = 6
Wniosek: do utworzenia informacji nie został użyta wartość i = 7, ponieważ i != w.

dZ = 176
i = 168
w = dZ & i = 168
Wniosek: do utworzenia informacji została użyta wartość i = 168  ponieważ i = w.

Polecenie SQL do wyszukania informacji zawierających wybraną nazwę:

Nazwa = ‘technokompleks oryniacki’
Identyfikator = 168

select * from informacje where z & 168 = 168;
LUB
select * from informacje where z & 248 = 168;

select count(*), z & 248 as k_segment where z & 6 = 6 group by k_segment;

Bazy sqlite oraz postgresql umożliwiają stosowanie operatorów bitowych w poleceniach SQL. 




Brak komentarzy:

Prześlij komentarz