Czego powinienem użyć? Ciąg lub 15 pól liczb całkowitych?

9

Rozwijam program śledzenia studentów, w którym muszę przechowywać 15 ocen z egzaminu.

Mogę przechowywać znaki jako ciąg i dzielić je w razie potrzeby, do celów takich jak wykonywanie operacji arytmetycznych. Potrzebuję jednak jak największej wydajności.

Który jest lepszy? Pole pojedynczego ciągu lub 15 pojedynczych pól int?

mikrofon
źródło
„15 ocen egzaminacyjnych” - tak jak wielokrotny wybór jednego egzaminu lub 15 testów?
rfusca
wyniki 15 testów
mike
1
Bez dodatkowych informacji o typie bazy danych (tradycyjny relacyjny z dostępnym indeksowaniem?) I wymaganiach dotyczących dostępu do danych i wzorców użytkowania trudno jest powiedzieć, jakiego projektu należy użyć i jak będzie on działać.
Cade Roux,

Odpowiedzi:

27

Jeśli mówisz już o dzieleniu i przetwarzaniu, nie przechowuj tego jako tablicy.

Bez względu na teorię relacyjną oraz tradycyjne reguły normalizacji i dogmaty, jest to po prostu projekt, który zapewnia MINIMALNĄ elastyczność.

Spraw, aby każdy wynik egzaminu był wierszem.

Nie staram się przewidzieć wszystkiego, ale istnieje bardzo duża liczba rzeczy, które ułatwia ten bardziej szczegółowy (i tak, znormalizowany) i tylko nieco droższy projekt przestrzenny, którego możesz teraz potrzebować lub nie, a może lub nie. może nie potrzebować w przyszłości:

  • Wyrzucasz najwyższy i najniższy wynik? Będziesz musiał pokroić tablicę i posortować ją.

  • Uśrednianie Będziesz musiał go pokroić i zsumować

  • Analiza wyniku egzaminu po egzaminie wśród studentów? Będziesz musiał kroić i obracać

  • Sortowanie do zliczania (lub np. Brytyjskie GCSE, gdzie może być 7 As i 2B)? Będziesz musiał kroić i sortować

Zauważ, że całe to krojenie i sortowanie odbywa się bardzo tanio w indeksowanym, znormalizowanym projekcie.

Cade Roux
źródło
4
Właśnie to chciałem powiedzieć, ale powiedziałeś to lepiej! Przechowywanie wielu wartości w jednym ciągu jest jednym z najgorszych możliwych wyborów projektowych dla dowolnej bazy danych.
HLGEM
+1 Świetne dalsze wyjaśnienia z mojego. Zwykle jestem zbyt zwięzły, lol.
rfusca
12

W przypadku wyników, pod względem wydajności, wyraźny zwycięzca przechowuje to liczbowo coś takiego;

create table test_scores
(
  student_id int,
  test_id int,
  score int
);

Jest łatwy w wyszukiwaniu, łatwy do aktualizacji i dodawania, a także bardzo łatwy i szybki do wykonywania agregacji. Biorąc pod uwagę wybór „przechowuj tę informację jako ciąg, który muszę podzielić” lub „przechowuj w kolumnie” ... zwycięzca prawie zawsze będzie „przechowywał w kolumnie” dla większości przypadków użycia w RDBMS.

rfusca
źródło
Jeśli zawsze jest to ten sam zestaw 15 egzaminów, może się zdarzyć, że przechowywanie ich w postaci zdenormalizowanej (15 kolumn) jest szybsze w przetwarzaniu. Pytanie, czy celowo zaproponowałeś całkowity typ danych?
Edward Dortland,
Dodatkowo za każde 15 egzaminów 1 ucznia przechowujesz 15 razy identyfikator studenta i dodatkowe ID testu.
Edward Dortland,
1
skrzypce tutaj - sqlfiddle.com/#!1/f7343/10
rfusca
6
@EdwardDortland zawsze będzie 15, dopóki nie będzie.
stamtąd
1
@EdwardDortland: Obliczenia są w porządku. Czy możesz to zrobić dla potrzebnych indeksów?
ypercubeᵀᴹ
1

pod warunkiem, że używasz malutkiej liczby int (od 0 do 255) za pomocą znaku char (15) lub 15 malutki jest taki sam (jeśli chodzi o rozmiar). Zatem z punktu widzenia wydajności wybierz 15 maleintów, ponieważ oszczędzasz na wydobywaniu i obsłudze ciągów.

AKTUALIZACJA

jeśli znaki są dwucyfrowe, potrzebujesz CHAR (30) i jest to dwukrotność 15-krotnego malutkiego.

Edward Dortland
źródło
9
Biorąc pod uwagę ten niezwykle prosty projekt, jeśli na tej planecie jest instytucja, która ma wystarczającą liczbę studentów, którzy zdają 15 egzaminów (ze znakami), aby spowodować problemy z wydajnością w nowoczesnym systemie RDBMS, będę płakać dziś wieczorem.
Philᵀᴹ
1
Jeśli znaki są dwucyfrowe? Ale małe int obejmuje wyniki od 0 do 255 lub od -127 do 127, w zależności od tego, jak wolisz liczyć. Ponieważ wyniki rzadko wypadają negatywnie, daje to ponad 250 punktów za jeden egzamin, a większość egzaminów jest oceniana w skali 0-100%. Myślę, że tinyint jest tutaj absolutnie użyteczny.
jcolebrand
Tak, zgadzamy się, po prostu stwierdziłem, że przy znakach dwucyfrowych w przeciwieństwie do znaków jednocyfrowych jeszcze gorzej jest przechowywać go jako znak. Od tego czasu potrzebujesz char (30) zamiast char (15). Chociaż dwucyfrowe lub nie, 15 małych liczb całkowitych zawsze będzie mieć tylko 15 bajtów.
Edward Dortland,
-1, ponieważ ta odpowiedź zaleca, aby pola na rzędy były znacznie gorsze od przechowywania wyników każdego egzaminu we własnym wierszu, jak proponują inne posty
cud 173