Dlaczego SQL Server nie obsługuje niepodpisanego typu danych?

84

Szczególnie myślę o niepodpisanych int.

Oto praktyczny przykład: co robisz, gdy Twoja kolumna tożsamości osiąga maksimum? Możliwe jest przejście BigInt(pamięć 8 bajtów zamiast 4) lub refaktoryzacja aplikacji do obsługi ujemnych liczb całkowitych, a nawet tworzenie własnych reguł, jak wskazano w tej odpowiedzi ; żadna z tych opcji nie jest optymalna.

UInt byłoby idealnym rozwiązaniem, ale SQL Server go nie oferuje (tak jak MySQL).

Rozumiem, że niepodpisane typy danych nie są częścią standardu SQL (SQL-2003), ale nadal wydaje mi się to marnotrawstwem.

Jaki jest powód ich nieuwzględnienia (w SQL Server lub w standardzie)?

Romhein
źródło
11
Zapytaj zespół projektantów SQL Server ..... także: czy naprawdę zamierzasz maksymalnie przekroczyć nawet 2 MILIARDY wartości INT IDENTITY? NAPRAWDĘ?!?!?! Jeśli masz więcej niż 2 miliardy wierszy czegokolwiek, z czym masz do czynienia, założę się, że możesz zaoszczędzić trochę miejsca na dysku i użyć DUŻEGO jako TOŻSAMOŚCI ....
marc_s
6
Co masz na myśli marc_s? To tylko wstawka co 800 ms przez 50 lat prosto, twoje stoły nie mają takiej aktywności? :)
Mike M.
22
@Mike M: Nie wszyscy z nas pracują nad aplikacjami Myszki Miki… zużyliśmy ponad 3 miliardy bigintów w ciągu mniej niż 2 lat. Szczyt wynosi> 2000 wierszy na sekundę.
gbn
5
@gbn Nie chciałem sugerować, że nikt nie miał takiego obciążenia. Jednak, jak już powiedziano, jeśli masz> 2000 wierszy na sekundę, dodatkowe 2B nie pomoże twojej sprawie.
Mike M.
11
@Mike M i @marc_s, gdybym pracował na systemie z 2 miliardami wierszy tabeli, może zwrócić uwagę na zmarnowane miejsce. Mogę zwrócić uwagę na rozmiar strony indeksu i wydajność skanowania indeksu. W takich warunkach nie chciałbym marnować miejsca.
Romhein

Odpowiedzi:

66

Gdybym miał zgadywać, powiedziałbym, że starają się uniknąć mnożenia się typów. Ogólnie rzecz biorąc, liczba całkowita bez znaku nie może zrobić niczego, czego nie może zrobić liczba całkowita ze znakiem. Jeśli chodzi o przypadek, gdy potrzebujesz liczby między 2147483648 a 4294967296, prawdopodobnie powinieneś przejść do 8-bajtowej liczby całkowitej, ponieważ liczba ta ostatecznie również przekroczy 4294967296.

Jeff Hornby
źródło
3
Myślę, że jest to najbliższa odpowiedź na to pytanie. Dzięki.
Romhein
8
Jeśli „rozprzestrzenianie się typów” mogło zaoszczędzić trochę miejsca / pieniędzy, dlaczego sądzisz, że to mogło być zło.
Samuel
1
Pobieranie wierszy według ich wartości również będzie wolniejsze (tj. ORDER BY ABS(Id)), Zwłaszcza jeśli kolumna jest klastrowym kluczem podstawowym. Na przykład użycie 32-bitowego uniksowego znacznika czasu jest często wygodnym sposobem na zmniejszenie o 4 bajty standardowej daty i godziny SQL.
Groo
57

W tym celu możesz użyć -2 147 483 648 jako wartości początkowej.

Identity(-2147483648, 1)
CFreitas
źródło
1
Ha, bardzo mi się podoba ta odpowiedź. Nie jestem pewien, czy kiedykolwiek to zaimplementowałem, ale zdecydowanie rozwiązało to problem braku wykorzystania połowy identyfikatorów.
Kevin,
46

Znalazłem podobne pytanie w Centrum deweloperów pakietu Microsoft Office.

Odpowiedź od Jima Hogga (menedżera programu) zawiera pewne zalety i wady dotyczące dodawania niepodpisanych int. Główną wadą jest to, że zasady implementacji niejawnych konwersji typów stają się koszmarem.

Żądanie zostało zamknięte z powodu „Nie zostanie naprawione”.

Anthony K.
źródło
Link już nie działa, więc nie mogę przeczytać oryginalnej odpowiedzi. Ale uważam, że problem nie polega na tym, że to koszmar; chodzi o to, że nie ma standardu, który mówi, jak to zrobić. Mogliby zrobić to, co na przykład robi MySQL (nie sądzę, aby inne systemy DBMS obsługują UNSIGNED), ale jeśli inny DBMS dodaje obsługę znaków, mogą używać innych reguł. Projekt konwersji to ważna sprawa. JavaScript jest przykładem tego, co się dzieje, gdy nie jest traktowany poważnie.
Federico Razzoli
Zaktualizowany link - komentarz Jima Hogga na forum deweloperów MSSN Office.
Anthony K
1

Nie obsługują słów kluczowych SIGNED i UNSIGNED, ponieważ nie są standardowe. W standardzie SQL wszystkie typy liczbowe są podpisane.

UNSIGNED (i SIGNED, co jest wartością domyślną) to rozszerzenia MySQL, które mogą być przydatne do przechowywania wyższych liczb bez znaku w tej samej ilości bajtów i nie zezwalają na liczby ujemne.

Federico Razzoli
źródło