Czy potrzebuję identyfikatorów w mojej bazie danych, jeśli rekordy można zidentyfikować według daty?


17

Piszę swoją pierwszą aplikację na Androida i będę korzystał z bazy danych SQLite, więc będę starał się jak najbardziej ograniczyć rozmiar, ale myślę, że pytanie dotyczy ogólnie projektowania bazy danych.

Planuję przechowywać rekordy, które będą miały tekst i datę utworzenia. Aplikacja jest samodzielną aplikacją, tzn. Nie będzie łączyła się z Internetem i tylko jeden użytkownik będzie ją aktualizował, więc nie ma szans, że będzie więcej niż jeden wpis z określoną datą.

Czy moja tabela nadal potrzebuje kolumny identyfikatora? Jeśli tak, jakie są zalety używania identyfikatora jako identyfikatora rekordu w porównaniu z datą?


SQLite zawsze tworzy kolumnę całkowitą dla rowid, jeśli nie podasz liczby całkowitej PK. Więc nie licz na to, że nie będziesz mieć kolumny „ID”, by zaoszczędzić miejsce.
Codism

Dodam, że w Androidzie niektóre klasy potrzebują tabel, aby kolumna _id działała. Więcej informacji w tej odpowiedzi SO .
bigstones

5
Jeśli otrzymujesz datę z samego telefonu, a użytkownik podróżuje do wcześniejszej strefy czasowej (a jego telefon automatycznie aktualizuje czas), istnieje niewielka szansa, że ​​możesz uzyskać ten sam znacznik czasu więcej niż raz.
Eugene

Odpowiedzi:


22

IMHO najlepiej unikać kolumny danych jako klucza podstawowego.

Pracowałem w systemach, w których pole daty jest używane jako klucz podstawowy, a pisanie zapytań w celu wycofania podzbiorów danych jest nieco uciążliwe, jeśli pracujesz z polami daty.

Niektóre inne kwestie, które warto rozważyć:

Możesz pomyśleć, że moment w czasie jest wyjątkowy, ale zależy to raczej od szczegółowości kolumny daty. Czy to minuty, sekundy, milisekundy itp. Czy możesz być absolutnie pewien, że nigdy nie otrzymasz naruszenia klucza podstawowego?

Wreszcie, jeśli chcesz przenieść bazę danych na inną platformę, możesz ponownie napotkać problemy, w których ziarnistość danych daty różni się między platformami.

Oczywiście musisz zrównoważyć ideał z tym, z czym musisz pracować. Jeśli przestrzeń jest tak istotnym problemem, użycie kolumny daty może być mniejszym z dwóch zła. To decyzja projektowa, którą musisz podjąć.

Edytować:

Powinienem zaznaczyć, że w żaden sposób nie świadczy to o złej decyzji projektowej. Tyle, że mogą występować problemy z praktycznymi aspektami omawianego RDBMS.


minęło trochę czasu, odkąd napisałem zapytanie SQLite, ale czy nie filtruje według dat identycznych z filtrowaniem według liczb całkowitych, poza bardziej szczegółową deklaracją wiążących wartości?
DougM

Jest to po prostu bardziej szczegółowe, a także na niektórych RDBMS występuje ten problem, w którym element dzień i miesiąc jest odwrócony, jeśli DB został skonfigurowany w formacie amerykańskim.
Robbie Dee,

Dzięki, to są wszystkie dobre odpowiedzi, ale twoje doświadczenie w pracy zdecydowanie przypieczętowało umowę.
Nieszka

Jako postscriptum do tego: dopiero dziś otrzymałem problem wsparcia dla tabeli audytu aplikacji, w której dochodzi do naruszenia klucza podstawowego dla numeru pracownika i daty dostępu / godziny PK z powodu różnicy czasu między 2 urządzeniami klienckimi. ..
Robbie Dee,

13

Nie, nie potrzebujesz ściśle kolumny identyfikatora zdefiniowanej w schemacie, jeśli możesz zagwarantować, że nigdy nie będzie zduplikowanej daty.

ALE ...

... powiedziawszy, równie dobrze możesz go użyć. Mały sekret polega na tym, że SQLite ma już unikalny, automatycznie zwiększający się identyfikator dla każdej tabeli o nazwie ROWID. Jeśli zadeklarujesz kolumnę z automatyczną inkrementacją liczb całkowitych w swojej tabeli jako PK, SQLite nie utworzy nowej kolumny - po prostu alias tej wcześniej istniejącej kolumny ROWID.

W SQLite każdy wiersz każdej tabeli ma 64-bitową liczbę całkowitą ROWID ze znakiem. ROWID dla każdego wiersza jest unikalny dla wszystkich wierszy w tej samej tabeli.

Możesz uzyskać dostęp do ROWID tabeli SQLite, używając jednej ze specjalnych nazw kolumn ROWID, ROWID lub OID. Z wyjątkiem sytuacji, gdy zadeklarujesz zwykłą kolumnę tabeli do używania jednej z tych specjalnych nazw, wówczas użycie tej nazwy będzie odnosić się do zadeklarowanej kolumny, a nie do wewnętrznego ROWID.

Jeśli tabela zawiera kolumnę typu INTEGER PRIMARY KEY, wówczas ta kolumna staje się aliasem dla ROWID. Następnie można uzyskać dostęp do ROWID przy użyciu dowolnej z czterech różnych nazw, trzech oryginalnych nazw opisanych powyżej lub nazwy nadanej kolumnie INTEGER PRIMARY KEY. Wszystkie te nazwy są dla siebie pseudonimami i działają równie dobrze w każdym kontekście.

http://www.sqlite.org/autoinc.html

Więc nie będziesz oszczędzać miejsca, nie używając kolumny identyfikatora, ponieważ dostajesz jedną na tabelę, czy chcesz, czy nie!


9

Użyj pola identyfikatora, jeśli spełniony jest dowolny z poniższych warunków:

  1. Nie istnieje naturalny klucz (data nie będzie niepowtarzalna)
  2. Pole daty będzie się często zmieniać
  3. Data może nie być znana w momencie wstawienia.
  4. Identyfikator wielokolumnowy przekracza trzy kolumny, co spowodowałoby, że połączenia byłyby zbyt szczegółowe.

Przeczytaj to pytanie: Czy istnieje źródło kanoniczne wspierające „surogatów”?

Edytować:

Ponieważ, moim zdaniem, żadne z powyższych nie jest prawdziwe, nie musisz używać pola identyfikatora, ale możesz użyć jednego, jeśli chcesz.


1
Kolumny +1 identyfikatora to zapach kodu schematu, wskazujący, że dane tak naprawdę nie pasują do modelu relacyjnego.
Ross Patterson

10
@RossPatterson Nie jestem tego taki pewien. Mogę wymyślić kilka przypadków, w których nie istniałby naturalny klucz, ale dane wciąż mogą pasować do modelu relacyjnego. Tylko jedna sprawa z mojej głowy: przechowywanie informacji o żywych osobach. Wiele ( nie wszystkie! ) Krajów przypisuje unikalne identyfikatory każdemu obywatelowi, ale to nie znaczy, że użycie tego identyfikatora jest właściwe lub nawet możliwe (może nie być znane w momencie tworzenia rekordu, może nie zostać przypisane lub jego użycie mogą być zabronione np. przez obowiązujące przepisy). Czy to oznacza, że ​​dane nie pasują do modelu relacyjnego? Nie wydaje mi się
CVn

I jest trochę zabawny fakt, że tam, gdzie jest taki unikalny identyfikator, policja (itp.) Czasami używa duplikatów dla swoich fałszywych identyfikatorów. A gdy nie jest to zamierzone, błąd pisarski i tak zapewni duplikaty.
user470365,

4
Niezależnie od tego, czy jest wbudowany (a la Oracle), czy dodany jako kolumna bona fide, są one bardzo przydatne. Jako ktoś, kto był po obu stronach ogrodzenia (DBA i programista), o wiele łatwiej jest wydedukować tabelę z identyfikatorem, który możesz zagwarantować, że będzie unikalny.
Robbie Dee,

1
@RobbieDee Masz rację. To nie temat.
Tulains Córdova

2

Pamiętaj, że możesz również chcieć zmienić znaczenie kolumny „data” z created_atna updated_atlub dowolną inną zmianę wzdłuż tych linii, co uważam za bardzo częsty przypadek.

Dodanie kolumny identyfikatora w niektórych przypadkach zapewni większą elastyczność przy zmianie projektu.


Dodanie +1 do tabel data_tworzone i data_modyfikowane jest bardzo przydatne do śledzenia, kiedy wiersze zostały utworzone i zaktualizowane. Jest to warte swojej wagi w złocie podczas badania problemów z aktualizacją repozytorium / hurtowni danych.
Robbie Dee,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.