Do czego służą klucze ujemne?

12

Nieco nowość w korzystaniu ze standardowych baz danych SQL (obecnie głównie w MySQL). Do tej pory nie spotkałem się z wieloma zastosowaniami tego typu.

Kiedy i dlaczego warto indeksować tabelę za pomocą kluczy ujemnych (a raczej podpisanych)?

Garet Claborn
źródło
5
po pierwsze, ktokolwiek oddala głosowanie bez pozostawiania opinii, robisz krzywdę. Następnie odpowiedź na to doskonałe pytanie.
jcolebrand
1
Ten temat jest intrygujący. Osobiście nigdy nie słyszałem o tej koncepcji. To pytanie nigdy nie powinno zostać odrzucone. +1 ode mnie za wprowadzenie tej koncepcji.
RolandoMySQLDBA

Odpowiedzi:

13

Wszystko, co jest kluczem podstawowym, to wartość, którą ustaliliśmy, która ma ogromne znaczenie w rekordzie. Niezależnie od tego, czy ten klucz jest int podpisany, int podpisany, ciąg, obiekt blob (w rzeczywistości istnieją ograniczenia) lub UUID (lub jakakolwiek inna nazwa, jaką dziś przyjmuje), faktem jest, że jest to klucz i że jest sprawa najwyższej wagi.

Ponieważ nie jesteśmy zmuszeni do używania tylko dodatnich liczb zorientowanych dla naszych kluczy, warto wziąć pod uwagę, że int podpisany pójdzie tylko do ~ 2 miliardów, podczas gdy niepodpisany int pójdzie do ~ 4 miliardów. Ale nie ma nic złego w używaniu podpisanego int, ustawieniu wartości początkowej na ~ -2 miliard i ustawieniu przyrostu o jeden. Po ~ 2 miliardach rekordów osiągniesz „zero”, a następnie będziesz kontynuować do ~ 2 miliardów.

To, dlaczego warto mieć w tabeli „klucze ujemne”, to to samo pytanie, co „dlaczego warto mieć klucze w tabeli”. „Wartość” klucza nie ma wpływu na jego status jako klucza. Klucz jest kluczem jest kluczem.

Ważne jest, czy klucz jest ważny.

Jeśli chodzi o to, dlaczego warto zezwolić na klucze, które były ujemne, mogę zasugerować kilka powodów:

Co jeśli chcesz wskazać zwroty w systemie sprzedaży jako ujemne numery zamówień sprzedaży, które pasują do dodatniego numeru zamówienia sprzedaży, ułatwiając w ten sposób korelację (jest to naiwne i źle zaprojektowane, ale działałoby w sensie „arkusza kalkulacyjnego”).

Co jeśli chciałbyś mieć tabelę użytkowników i wskazać, że te z liczbami ujemnymi były kontrolowane przez system (SO robi to samo, dla użytkowników kanału czatu).

Mógłbym kontynuować, ale tak naprawdę jedynym powodem, dla którego liczba jest ujemna, jest to, że ty lub ja przypisuję jej wagę. Poza tym nie ma wielkiego powodu, aby wartość klucza miała jakikolwiek wpływ na sam klucz.

jcolebrand
źródło
Zredagowano fragment „wystąpienia niszowego”, ponieważ jest to bardziej niż prawdopodobne nieporozumienie z powodu braku doświadczenia. Ciekawa lektura. W pewnym sensie wyobrażałem sobie, że będzie sytuacja, w której ujemna wartość klucza była w jakiś sposób przydatna w kodowaniu (tj. Bez decydowania, że ​​to oznacza określoną rzecz), ale jest to bardzo przydatne myślenie, gdy masz silny podział na dwie grupy i nie nie chcę użyć dodatkowego bool: p
Garet Claborn
1
@Garet ~ Więc masz rację: „wartość klucza była w jakiś sposób przydatna w kodowaniu” i od czasu do czasu używam swoich kluczy tylko w ten sposób, ale to nie ma nic wspólnego z aspektem bazy danych. Baza danych jest magazynem. Z drugiej strony aplikacja, która zużywa dane, dba o wartości . Ale tak, ten +/- boolean to fajna sztuczka, widziałem, że wielokrotnie używał tego właśnie efektu.
jcolebrand
2
-1 za sugerowanie, że takie podwójne wartości celu są czymś innym niż złym pomysłem. Potrzebujesz int i bool? Użyj int i bool.
Jack mówi, że spróbuj topanswers.xyz
1
@JackPDouglas Nie przypominam sobie zachęcania ludzi do tego, ściśle pamiętam, sugerując, że pole i jego dane to dwie różne rzeczy. Dziękuję za co najmniej konstruktywną informację zwrotną na temat opinii, ale nie mogę powiedzieć, że ta obserwacja nic nie znaczy w świetle pojęcia „do czego są używane klucze negatywne”, ponieważ jest to problem logiki aplikacji, a nie problem warstwy bazy danych . Chciałem podkreślić, jak te rzeczy są używane w warstwie aplikacji, ale w warstwie bazy danych nie mają one żadnego znaczenia.
jcolebrand
1
@JackPDouglas ~ Użyłem tego konkretnego przykładu, ponieważ istnieje bardzo dobrze znana strona (sieć witryn), o której słyszeliście, że robi to samo, więc nie chcę jej lekceważyć, ponieważ jest ona ważna "sztuczka". Sprawdź tego użytkownika dba.stackexchange.com/users/-1/community i powiedz mi, jaki jest jego identyfikator. Mogę niemal zapewnić, że identyfikator użytkownika jest kluczem podstawowym (aw wielu innych tabelach jest kluczem obcym). Tylko dlatego, że jest to zły projekt aplikacji, nie oznacza, że ​​jest nieważna. Ale jeszcze raz, to nie jest projekt db, to projekt domeny. To prawda, logika db obsługuje to
jcolebrand
10

Jeśli zajmujemy się kolumnami tożsamości lub autonumerowania, sama wartość nie powinna mieć znaczenia. (czasami tak jest, jak na użytkowników czatu SO wspomnianych przez drachenstern, co zrobiłem wcześniej)

Jednak na ogół stracisz połowę swojego zakresu, jeśli używasz liczb całkowitych ze znakiem.
Zobacz: Co zrobić, gdy pole w tabeli zbliża się do maksymalnej 32-bitowej liczby całkowitej ze znakiem lub bez znaku?

Kolejny przykład: w małych scenariuszach replikacji użycie wartości ujemnych dla jednej witryny i dodatnich dla innej daje pewną niejawną wiedzę o źródle dowolnego wiersza.

gbn
źródło
i upewnij się, że w jakiś sposób ograniczasz wartości wprowadzane w każdej witrynie, inaczej skończysz w okropnym bałaganie, gdy Twoja „domniemana wiedza” okaże się błędna.
Jack mówi, że spróbuj topanswers.xyz
@JackPDouglas: użyjesz NIE DO REPLIKACJI, aby uniknąć generowania wartości na niewłaściwej stronie
gbn
wraz z ograniczeniami kontroli ? Ponadto, NOT FOR REPLICATIONczy znasz MySQL (lub inny) analog , który znasz?
Jack mówi, że spróbuj topanswers.xyz
@JackPDouglas: przepraszam, nie jestem pewien co do SQL Server
gbn
8

Nie wszystkie systemy baz danych obsługują nawet typy całkowite bez znaku, a MSSQL jest jednym z nich. W takich przypadkach ujemne wartości są możliwe w polach liczb całkowitych po prostu dlatego, że są one możliwe w danym typie (możesz użyć reguł lub wyzwalaczy, aby je zablokować, jak pokazano w tym przykładzie , ale prawdopodobnie nie ma potrzeby dodawania narzutu związanego z egzekwowaniem takich reguł do każda inters / aktualizacja).

Jeśli chodzi o bazę danych, rzeczywista wartość klucza podstawowego nie ma znaczenia, o ile jest unikalna w tabeli. Do tego -42 i 42 są tylko dwiema różnymi liczbami w taki sam sposób, jak 42 i 69 - oznacza to, że kod będzie nadawał tylko negatywność lub nie wartość.

Nieobsługiwanie niepodpisanych typów liczb całkowitych jest prawdopodobnie decyzją projektową opartą na zmniejszeniu złożoności - tj. Nie chcę, aby dwa różne 32-bitowe typy liczb całkowitych martwiły się o sprawdzenie zakresów podczas przypisywania wartości między nimi. Ogranicza to liczbę indeksów możliwych w polu automatycznego przyrostu, rozpoczynając od 0 lub 1 do połowy, co byłoby możliwe w typie bez znaku (~ 2e9 zamiast ~ 4e9), ale rzadko jest to istotny problem (jeśli prawdopodobnie będziesz potrzebować pewną liczbę kluczowych wartości tej wielkości prawdopodobnie wybrałeś dla typu 64-bitowego, szczególnie jeśli używasz architektury 64-bitowej, w której takie wartości są przetwarzane nie mniej wydajnie niż wartości 32-bitowe), chociaż jeśli chcesz mieć pełny zakres i potrzebujesz aby trzymać się wersji 32-bitowej ze względu na miejsce, możesz rozpocząć przyrost od -2 147 483 647.

David Spillett
źródło
Tak, myślę, że już poradziliśmy
jcolebrand
tinyint jest niepodpisany (0 .. 255). Zazwyczaj tworzę ograniczenie sprawdzania w kolumnach liczb całkowitych, aby upewnić się, że wartości nie są ujemne, ponieważ nieuchronnie zostanie napisany kod, który domyślnie to zakłada, i pojawią się dziwne błędy, jeśli w jakiś sposób wkradnie się wartość ujemna.
Ed Avis