SQL Server w logistyce

Tabela _refno w bazie danych SQL Server

Generator numerów referencyjnych — jedno źródło identyfikatorów wiążących rekordy między tabelami całego systemu.

sql.server.net.pl/sql/
Uśmiechnięty analityk w garniturze przy szerokim monitorze
Uśmiechnięty analityk w garniturze przy szerokim monitorze
W skrócie
  • Tabela ma jedną kolumnę i jedno zadanie: wydawać numery unikalne w skali całej bazy, nie pojedynczej tabeli.
  • Numer referencyjny wiąże rekord z jego historią, blokadami, potwierdzeniami i danymi mapowymi bez oglądania się na tabelę źródłową.
  • Typ bigint daje zakres ponad dziewięciu trylionów wartości — wyczerpanie go nie jest realnym zagrożeniem.
  • Klucz główny na jedynej kolumnie wyklucza wydanie tego samego numeru dwa razy.

Do czego służy tabela [dbo].[_refno]

Większość tabel w bazie ma własny klucz — ID_HISTORIA, ID_ERROR, ID_JOBS. Są to numery lokalne: pierwszy wiersz każdej z nich ma identyfikator 1. Dopóki rekordy nie muszą wskazywać na siebie nawzajem, wystarcza to w zupełności. Problem pojawia się, gdy jedna tabela ma odwoływać się do rekordu z dowolnej innej.

Tak działają w StudioSystem rejestry pomocnicze. Historia zmian, blokady edycyjne, potwierdzenia przeczytania i współrzędne geograficzne odwołują się do rekordu przez numer referencyjny — i muszą to robić niezależnie od tego, czy rekord jest dokumentem magazynowym, kontrahentem czy zleceniem. Numer lokalny by tu nie wystarczył, bo wartość 1 oznaczałaby coś innego w każdej tabeli.

Tabela [dbo].[_refno] rozwiązuje to najprościej, jak można: jest centralnym rejestrem wydanych numerów. Nowy rekord pobiera z niej kolejną wartość, która od tej chwili identyfikuje go w całej bazie. Klucz główny na jedynej kolumnie gwarantuje, że ten sam numer nie zostanie wydany dwukrotnie — i to jest właściwie cała mechanika.

Jeden numer wiążący rekord z rejestrami pomocniczymi
Wydanie WydanieNowy rekord pobiera kolejny numer z centralnego rejestru
Powiązanie PowiązanieHistoria, blokady i potwierdzenia odwołują się do tej wartości
Odtworzenie OdtworzenieJedno zapytanie po REFNO zbiera wszystko, co dotyczy rekordu
Trwałość TrwałośćNumer pozostaje niezmienny przez cały cykl życia rekordu

Wartość tego rozwiązania polega na tym, że rejestr pomocniczy nie musi wiedzieć, z jakiej tabeli pochodzi opisywany rekord.

Budowa tabeli — wykaz kolumn

Struktura obejmuje jedną kolumnę — i nie potrzebuje więcej, bo całe zadanie tabeli sprowadza się do wydawania niepowtarzalnych wartości.

Wykaz kolumn tabeli
KolumnaTypWymaganaZnaczenie
REFNObigint
liczba całkowita 64-bitowa
takUnikalny numer referencyjny wykorzystany w systemie

Typ bigint obejmuje zakres do 9 223 372 036 854 775 807. Przy milionie nowych rekordów dziennie wyczerpanie tej puli zajęłoby ponad dwadzieścia pięć miliardów lat, więc jest to problem czysto teoretyczny.

Indeksy i wydajność zapytań

Jedyny indeks pełni tu funkcję wykraczającą poza przyspieszenie odczytu.

Indeksy zdefiniowane na tabeli
IndeksKolumnyRodzaj
PK__refnoREFNOklucz główny

Klucz główny na kolumnie REFNO jest mechanizmem, na którym opiera się cała gwarancja niepowtarzalności. Próba wstawienia istniejącej już wartości kończy się błędem po stronie serwera — a więc ochrona działa także wtedy, gdy dwa procesy sięgną po numer w tej samej chwili, czego sprawdzenie w kodzie aplikacji nie zapewnia.

Centralny rejestr a inne sposoby nadawania identyfikatorów

SQL Server oferuje kilka mechanizmów generowania unikalnych wartości. Każdy z nich sprawdza się w innym zastosowaniu, a różnice mają praktyczne konsekwencje dla wydajności i wielkości bazy.

Porównanie mechanizmów nadawania identyfikatorów
MechanizmZakres unikalnościRozmiarKolejność zapisu
Centralny rejestr (_refno)Cała baza danych8 bajtówRosnąca — zapisy trafiają na koniec indeksu
Kolumna IDENTITYPojedyncza tabela4 lub 8 bajtówRosnąca
Obiekt SEQUENCECała baza, z możliwością współdzielenia8 bajtówRosnąca
NEWID() — identyfikator GUIDPraktycznie globalny16 bajtówLosowa — powoduje fragmentację indeksu
NEWSEQUENTIALID()Praktycznie globalny16 bajtówRosnąca w obrębie sesji serwera

Kolumna „kolejność zapisu” ma znaczenie praktyczne: wartości losowe rozrzucają wstawiane wiersze po całym indeksie, co przy dużych tabelach zauważalnie spowalnia zapis.

Wybór centralnego rejestru zamiast identyfikatora GUID ma dwa uzasadnienia. Pierwsze to rozmiar: osiem bajtów zamiast szesnastu, przy setkach milionów wierszy w rejestrach pomocniczych daje różnicę liczoną w gigabajtach. Drugie to kolejność — wartości rosnące trafiają zawsze na koniec indeksu, podczas gdy losowe rozrzucają zapisy po całej strukturze, wymuszając jej ciągłą reorganizację.

Jak korzystać z tabeli w praktyce

Praca z numerami referencyjnymi sprowadza się do kilku zasad, których naruszenie bywa kosztowne:

  • Nie zmieniaj numeru przypisanego rekordowi — odwołują się do niego wpisy w historii, blokadach i potwierdzeniach, a żadne z tych powiązań nie jest chronione kluczem obcym.
  • Nie ponawiaj wydanych numerów, nawet po usunięciu rekordu; wpisy w rejestrach pomocniczych mogły pozostać i przypisałyby się do nowego obiektu.
  • Pobieraj numer w tej samej transakcji, w której powstaje rekord — inaczej przy błędzie zostaje wydana wartość bez właściciela.
  • Traktuj luki w numeracji jako normalne; wynikają z wycofanych transakcji i nie wymagają naprawy.
  • Nie interpretuj numeru jako informacji biznesowej — nie mówi nic o rodzaju rekordu ani o dacie jego powstania.
  • Przy odtwarzaniu bazy z kopii sprawdź stan rejestru, zanim dopuścisz użytkowników do pracy.

Sprawdzenie stanu rejestru: najwyższy wydany numer, liczba wydanych wartości i skala luk w numeracji:

SELECT  MAX(REFNO)                       AS NAJWYZSZY,
        MIN(REFNO)                       AS NAJNIZSZY,
        COUNT(*)                         AS WYDANYCH,
        MAX(REFNO) - MIN(REFNO) + 1
          - COUNT(*)                     AS LUK_W_NUMERACJI
FROM    dbo._refno;

Luki są zjawiskiem normalnym — powstają przy transakcjach wycofanych po pobraniu numeru. Ich obecność nie świadczy o błędzie i nie wymaga uzupełniania.

Tabela o jednej kolumnie rzadko trafia do dokumentacji, a bywa jednym z ważniejszych elementów bazy. To od niej zależy, czy da się jednym zapytaniem zebrać wszystko, co dotyczy danego dokumentu — jego historię, kto go blokował, kto potwierdził zapoznanie się z nim i gdzie znajduje się powiązany punkt na mapie.

Powiązane tabele i dokumentacja

Numer referencyjny jest wspólnym mianownikiem rejestrów pomocniczych opisanych poniżej:

FAQ

Najczęściej zadawane pytania o tabelę _refno

01

Czym numer referencyjny różni się od numeru dokumentu?

Numer dokumentu jest identyfikatorem używanym poza systemem — na wydruku i w rozmowie z kontrahentem — i powstaje z licznika prowadzonego osobno dla każdego rodzaju i roku. Numer referencyjny jest identyfikatorem wewnętrznym, unikalnym w skali całej bazy, którym rejestry pomocnicze wskazują rekord niezależnie od jego rodzaju.

02

Dlaczego nie użyto identyfikatora GUID?

Z dwóch powodów. Rozmiar: osiem bajtów zamiast szesnastu, co przy setkach milionów wierszy w rejestrach pomocniczych daje różnicę liczoną w gigabajtach. Oraz kolejność: wartości rosnące trafiają zawsze na koniec indeksu, podczas gdy losowe rozrzucają zapisy po całej strukturze i wymuszają jej ciągłą reorganizację.

03

Czy luki w numeracji oznaczają błąd?

Nie. Powstają, gdy numer został pobrany, a transakcja tworząca rekord została następnie wycofana. Jest to zjawisko normalne przy każdym mechanizmie wydającym wartości poza transakcją i nie wymaga uzupełniania — numer referencyjny nie musi tworzyć ciągu bez przerw.

04

Co się stanie, gdy zmienię numer przypisany rekordowi?

Rekord straci powiązanie ze swoją historią, blokadami i potwierdzeniami, a wpisy w rejestrach pomocniczych zostaną osierocone. Żadne z tych powiązań nie jest chronione kluczem obcym, więc operacja nie zgłosi błędu — skutki ujawnią się dopiero przy próbie odtworzenia przebiegu sprawy.

Słownik pojęć

Słownik pojęć

Pojęcia związane z identyfikacją rekordów w bazie danych.

MMicrosoft SQL Server
Serwer relacyjnej bazy danych, na którym pracują aplikacje SoftwareStudio. Odpowiada za spójność danych, uprawnienia dostępu, kopie zapasowe i wydajność zapytań.
IIndeks bazodanowy
Struktura przyspieszająca wyszukiwanie wierszy w tabeli. Dobrze dobrane indeksy skracają czas zapytań, ale spowalniają zapisy i zajmują miejsce na dysku.
WWydajność zapytań
Czas, w jakim baza danych zwraca wynik. Zależy od indeksów, planu wykonania i objętości przetwarzanych danych.
ŚŚlad rewizyjny
Nieusuwalny zapis, kto i kiedy zmienił dane w systemie. Podstawa wiarygodności ewidencji podczas audytu i kontroli.
KKopia zapasowa
Zabezpieczona kopia bazy danych pozwalająca odtworzyć stan systemu po awarii. W SQL Server wykonuje się ją w trybie pełnym, różnicowym lub jako kopię dziennika transakcji.
IIdentyfikowalność
Zdolność odtworzenia drogi towaru — od dostawcy, przez magazyn, po odbiorcę. Wymagana prawem w branży spożywczej i farmaceutycznej.

Zobacz to w praktyce

Sprawdź, jak systemy SoftwareStudio oparte na MS SQL Server wspierają ten obszar Twojej firmy.