Typy danych specjalnych obejmują m.in. ROWVERSION, SQL_VARIANT i HIERARCHYID o niestandardowym zastosowaniu.
ROWVERSION jako znacznik zmian w SQL Server
W SQL Server typ rowversion służy do oznaczania kolejnych zmian wykonywanych w obrębie bazy danych. Kolumna tego typu przechowuje binarną wartość o długości 8 bajtów, generowaną automatycznie przez silnik. Przy każdym wstawieniu lub aktualizacji wiersza zawierającego kolumnę rowversion SQL Server przypisuje jej nową wartość. Jest to znacznik techniczny, a nie data i godzina modyfikacji. Nie należy więc interpretować go jako czasu utworzenia rekordu ani zakładać, że wartość jednoznacznie opisuje moment zmiany.
Najczęstszym zastosowaniem rowversion jest kontrola współbieżności optymistycznej. Aplikacja może odczytać wiersz razem z jego znacznikiem, a następnie podczas zapisu sprawdzić, czy wartość nadal jest taka sama. Warunek aktualizacji może obejmować identyfikator rekordu oraz wcześniej odczytaną wartość rowversion. Jeżeli inny proces zmienił wiersz, warunek nie dopasuje rekordu i aplikacja wykryje konflikt zamiast bezwarunkowo nadpisać nowsze dane. Warto pamiętać, że rowversion nie jest kluczem czasowym, nie służy do sortowania zmian z dokładnością biznesową i nie powinien być używany do wyliczania odstępów czasowych.
SQL_VARIANT i przechowywanie różnych typów wartości
sql_variant jest typem SQL Server przeznaczonym do przechowywania wartości należących do różnych obsługiwanych typów danych. W jednej kolumnie mogą znajdować się na przykład liczby całkowite, wartości dziesiętne, teksty albo daty, ale typ bazowy jest zapisywany razem z konkretną wartością. Dzięki temu SQL Server nie traktuje całej zawartości jako zwykłego ciągu znaków i może zachować informacje potrzebne do późniejszej konwersji lub porównania. Typ ten ma jednak ograniczenia: nie przechowuje między innymi typów takich jak xml, text, ntext, image, timestamp będącego dawną nazwą rowversion, a także typów zdefiniowanych przez użytkownika.
Przy pracy z sql_variant istotne jest rozróżnienie wartości od jej typu bazowego. Do sprawdzania typu można używać funkcji SQL_VARIANT_PROPERTY, która zwraca właściwości takie jak BaseType, Precision, Scale lub MaxLength. Porównywanie dwóch wartości może zależeć zarówno od ich zawartości, jak i od typów bazowych oraz reguł konwersji SQL Server. Z tego powodu sql_variant bywa przydatny w tabelach przechowujących heterogeniczne atrybuty konfiguracyjne, lecz utrudnia kontrolę schematu, indeksowanie i przewidywanie zachowania zapytań. Przed użyciem należy ustalić dozwolone typy, sposób walidacji oraz reguły konwersji po stronie aplikacji.
HIERARCHYID do modelowania relacji nadrzędny–podrzędny
hierarchyid to systemowy typ danych SQL Server przeznaczony do reprezentowania pozycji w hierarchii. Wartość opisuje ścieżkę od korzenia do konkretnego węzła, a nie przechowuje automatycznie całego drzewa ani osobnej listy jego dzieci. Typ udostępnia metody ułatwiające budowanie i analizowanie hierarchii, między innymi GetRoot(), GetAncestor(), GetLevel(), IsDescendantOf() oraz GetDescendant(). Może być używany do danych takich jak struktura organizacyjna, katalog kategorii, drzewo folderów lub zależności pomiędzy elementami.
Przykładowy rekord może zawierać kolumnę NodePath hierarchyid oraz zwykłe kolumny opisujące nazwę i inne atrybuty węzła. Nowy element umieszczony pod określonym rodzicem otrzymuje ścieżkę wyliczoną względem tego rodzica. Metoda GetLevel() zwraca poziom w hierarchii, natomiast IsDescendantOf() pozwala sprawdzić, czy jeden węzeł znajduje się pod innym. hierarchyid nie wymusza samodzielnie unikalności wartości ani istnienia rodzica, dlatego projekt tabeli powinien uwzględniać odpowiednie klucze, indeksy i walidację. Przy przenoszeniu gałęzi drzewa trzeba zaktualizować ścieżki przenoszonego węzła oraz jego potomków.
Dobór typu, indeksowanie i kontrola danych w praktyce
Trzy opisane typy rozwiązują różne problemy i nie powinny być traktowane jako zamienne warianty zwykłych kolumn. rowversion służy do wykrywania zmian w wierszach, sql_variant pozwala przechowywać wartości o różnych typach bazowych, a hierarchyid reprezentuje położenie elementu w strukturze hierarchicznej. Przy projektowaniu tabel SQL Server warto określić, czy potrzebny jest automatyczny znacznik współbieżności, elastyczny atrybut o zmiennym typie, czy też szybkie operacje na relacjach przodków i potomków. Niewłaściwy wybór może prowadzić do niejawnych konwersji, trudniejszych zapytań i błędów podczas migracji danych.
Diagnostyka problemów z tymi typami obejmuje sprawdzenie definicji tabeli, indeksów, ograniczeń oraz zapytań wykonywanych przez aplikację. Dla rowversion należy zweryfikować, czy kod rzeczywiście przekazuje poprzednią wartość w warunku aktualizacji. Dla sql_variant trzeba ustalić faktyczne typy zapisanych wartości i przeanalizować konwersje wykonywane w filtrach. Dla hierarchyid warto sprawdzić poprawność ścieżek, poziomy węzłów oraz kompletność operacji przenoszenia gałęzi. W środowisku SQL Server pomocne jest również porównanie planów zapytań i obciążenia indeksów, ponieważ sam wybór specjalnego typu nie gwarantuje poprawnej wydajności ani spójności modelu danych.