2010-09-16 11 views
10

Pracuję z klientem, który chce dodać znaczniki czasu do wielu tabel, aby sortować je w kolejności chronologicznej. Wszystkie tabele mają także pole przyrostowe z automatyczną inkrementacją jako klucz podstawowy (identyfikator).Sprawdzone metody SQL - czy w celu automatycznego sortowania wierszy można polegać na polu automatycznego przyrostu?

Pomysł (prosty) - zapisać narzut/magazyn i polegać na kluczu podstawowym, aby posortować pola chronologicznie. Oczywiście, że to działa, ale nie jestem pewien, czy to podejście jest dopuszczalne w projektowaniu bazy danych dźwięku.

Plusy: mniej przechowywania wymagane za rekordem, prostsze klasy VO itp itd

Con: oznacza to cechę tej dziedzinie, skądinąd prostej identifer, którego definicja nie w żaden sposób zdefiniować lub gwarancji, że powinien/będzie działać jako taki.

Założono dla mojego pytania, że ​​definicje tabel DB są ustawione w kamieniu. Nadal - czy jest to dopuszczalne z punktu widzenia najlepszych praktyk?

Dzięki

+0

Jak myślisz, w jaki sposób osobny, np. "numer sekwencji" byłby bardziej "dźwięk" w twoim projekcie? Myślę, że poleganie na autonumerii jest całkiem dobrą opcją - z pewnością przynajmniej tak solidną i mocną, jak każdy inny "ręczny" proces, który możesz sam wprowadzić. –

+0

Jak zauważyłeś "to oznacza pewną charakterystykę". O ile nie zostało to zdefiniowane, niezależnie od tego, jakie zachowanie "zawsze widzisz", powinno być uważane za przypadkowe i podlegające zmianom zazwyczaj w najgorszym możliwym momencie. Oświadczyłem to szeroko, ponieważ zasada ta ma szerokie zastosowanie w odniesieniu do Państwa problemu, jak również każdej innej. – msw

+0

Auto_increment jest tylko znacznikiem referencyjnym dla rekordu; datetime obsługuje rekordy z poprzedniej wersji, ponieważ identyfikator nie byłby sekwencyjny. –

Odpowiedz

7

Prosiłeś o "najlepsze praktyki", zamiast "nie straszne praktyki", więc: nie, nie powinieneś polegać na automatycznie zwiększanym kluczu podstawowym, aby ustalić chronologię. Któregoś dnia wprowadzisz zmianę w projekcie db, która się załamie. Widziałem, jak to się stało.

kolumna datetime którego domyślna wartość jest GETDATE() ma bardzo niewielki narzut (o ile liczb całkowitych) i (jeszcze lepiej) informuje nie tylko sekwencję ale aktualną datę i godzinę, co często okazuje się być bezcenna. Nawet utrzymanie indeksu na kolumnie jest stosunkowo tanie.

Obecnie zawsze umieszcza obiekty danych kolumn kolumn CreateDate połączone ze zdarzeniami realnymi (takimi jak tworzenie konta).

Edited by dodać:

Jeśli dokładna chronologia jest niezbędne do aplikacji, nie można powoływać się na obu automatycznego przyrostu lub znaczników czasu (ponieważ nie zawsze mogą być identyczne znaczniki czasu, bez względu na to jak wysokie rozdzielczości). Prawdopodobnie będziesz musiał zamiast tego zrobić coś specyficznego dla aplikacji.

+1

Ale jeśli używasz danych SQL Server 200x 'DATETIME' type, możesz skończyć z kilkoma wierszami, które mają tę samą identyczną wartość datetime (ponieważ "rozdzielczość" wynosi 3,33 ms) i nie możesz już określić kolejności chronologicznej, albo ..... –

+0

@ marc_s: true; w rzeczywistości możesz * zawsze * mieć jednoczesne znaczniki czasu (chyba, że ​​twój zegar tyka szybciej niż twoja baza danych). Jeśli sekwencja jest tak ważna, musisz ją zbudować na głębszym poziomie. – egrunin

+0

@marc_s Użyj datetime2 w kolumnie. –

2

Można acheive ten sam cel w perspektywie krótkoterminowej sortując na kolumnie ID. Byłoby to lepsze, gdyby dodać dodatkowe dane, aby osiągnąć ten sam wynik. Nie sądzę, że byłoby nikomu zagmatwać patrzeć na tabelę danych i wiedzieć, że jest chronologiczna, gdy widzą, że jest to kolumna tożsamości.

Jest jednak kilka wad lub ograniczeń.

  • chronologiczny porządek może być pomieszane jeśli ktoś ponownie nasiona kolumnę
  • Chronologia na okres data nie może być ustalona bez dodatkowych danych
  • Ta konfiguracja uniemożliwia sortowanie chronologicznie jeśli system kiedykolwiek akceptuje nowe, nie chronologiczne dane

Na podstawie realistycznej oceny tych "ograniczeń" powinieneś być w stanie doradzić właściwe podejście.

+0

Zaufajcie mi, że jakiś mądry przyjdzie i powie, że chce zmienić kolumnę Tożsamości na coś sensownego lub zresetować wartości z innego punktu początkowego z jakiegoś głupiego powodu. Użyj DateTime – Roadie57

+0

@ Roadie57, myślałem, że diaboliczny charakter "użytkownika" był oczywisty :) Zgadzam się z tobą, jednak OP powiedział, aby założyć, że struktura bazy danych została "osadzona w kamieniu".Nie wspominając o tym, że pracuje dla * klienta *, a nie dla pracodawcy, który może być gotów zapłacić za takie "niepoważne" ulepszenia. – Brad

+0

Pozwalałem, aby prawdziwe doświadczenie życiowe przeszkadzało mi w myśleniu. Właściwie to miałem kogoś, kto powiedział, że wszystkie wartości przyrostu automatycznego musiały zostać ponownie ustawione, aby zacząć od 1008000, tak aby niektóre głupie niemądre raporty mogły być uruchamiane bez filtrowania przez kolumny z wyjątkiem id – Roadie57

1

Auto-inkrementujący ID da ci pojęcie porządku, jak Brad wskazuje, ale rób to dobrze - jeśli chcesz wiedzieć, KIEDY coś zostało dodane, musisz mieć kolumnę datetime. Wtedy możesz nie tylko sortować chronologicznie, ale także stosować filtry.

2

Po odpowiedzi egginina zmiana logiki trwałości lub przetwarzania tych wierszy może powodować wstawianie wierszy do bazy danych w sposób niesekwencyjny lub niedeterministyczny. Możesz zaimplementować równoległy procesor plików, który rzuca wiersz do bazy danych, gdy tylko wątek zakończy przekształcanie go, co może nastąpić, zanim inny wątek zakończy przetwarzanie wiersza, który wystąpił wcześniej w pliku. Użycie ORM do utrwalenia rekordów może spowodować podobne zachowanie; ORM może po prostu utrzymywać "torbę" (kolekcję nieuporządkowaną) wykresów obiektów oczekujących na utrwalenie i chwytać je losowo, aby utrzymać je w bazie danych, gdy zostanie im nakazane "opróżnienie" buforu obiektów.

W obu przypadkach zaufanie do kolumny autoinkrementacji, która informuje o kolejności zapisów w SYSTEMIE, jest złe juju. Może, ale nie musi być w stanie podać kolejność, w jakiej zapisuje jego BAZY DANYCH; to zależy od wdrożenia DB.

0

Nie rób tego. Nigdy nie powinieneś polegać na rzeczywistej wartości kolumny ID. Traktuj to jak czarną skrzynkę, przydatne tylko przy wyszukiwaniu kluczy.

Mówisz "mniej miejsca w pamięci na rekord", ale jak ważne jest to? Jak duże są te wiersze, o których mówimy? Jeśli masz 200-bajtowe wiersze, kolejne 4 bajty prawdopodobnie nie będą miały większego znaczenia.

Nie optymalizuj bez pomiaru. Spraw, aby działał on na pierwszym miejscu, a następnie Zoptymalizuj.

0

@MadBreaker

Jest oddzielić rzeczy, jeśli trzeba znać kolejność Ci stworzyć kolejność kolumn z autoIncrement, jednak jeśli chcesz znać datę i czas, jaki został włożony użyć datetime2.

Kolejność chronologiczną można zagwarantować, jeśli nie zezwolisz na aktualizacje lub usuwasz, ale jeśli chcesz mieć kontrolę nad czasem, powinieneś użyć datetime2.

0

Nie wspomniano, czy korzystasz z pojedynczego db, czy z klastrów. Jeśli jesteś skupiony, bądź ostrożny przy wdrażaniu inkrementacji, ponieważ nie zawsze masz gwarancję, że rzeczy wyjdą w kolejności, którą naturalnie myślisz. Na przykład sekwencje Oracle mogą buforować grupy o następnych wartościach (w zależności od konfiguracji) i dają 1,2,2,4,5 listy sortowania ...

Powiązane problemy