2013-02-27 9 views
10

Mam więc tabelę ulubionych użytkowników. Jest ich kilka milionów.Wydajny sposób na przechowywanie elementów do ponownego zamówienia w bazie danych

Obecnie mają tylko trzy kolumny: id (pk), userId i someFkRef. Jest indeks na userId, który pozwala mi szybko wybrać ulubione osoby.

Obecnie są one zamawiane przez id, co jest w rzeczywistości tylko zamówieniem wkładki. Chcielibyśmy zaoferować użytkownikowi szansę na ponowne zamówienie swoich ulubionych, najprawdopodobniej za pomocą pewnego rodzaju interakcji przeciągnij i upuść.

Moje pierwsze (i podejrzewam naiwne) podejście do tego byłoby po prostu dodanie kolumny order i indeksu złożonego ponad userId, order. Jednak po odbiciu, gdy użytkownik przesunie swój przedmiot w pewnej odległości nad listą, wszystkie pośrednie wiersze między początkową pozycją przedmiotu a końcową pozycją będą musiały ponownie przeliczyć kolumnę order, a tym samym także indeks.

Jest to (najprawdopodobniej) złe.

Zanim przejdę przez wieki próbując dokładnie określić, jak źle, zastanawiam się, czy istnieje lepsza reprezentacja oparta na tabelach, która jest tańsza w manipulowaniu przy operacjach opisanych powyżej.

+0

Nie jestem przekonany, że musisz zindeksować nowe pole. –

+0

Ogólnie rzecz biorąc, 'order by' ops wymaga indeksu, nie? – spender

+0

@spender Wymagaj nie, ale jeśli twoje wiersze tabeli są duże i otrzymujesz duży zestaw wyników, sortowanie za pomocą indeksu może generować nieco mniej operacji we/wy. –

Odpowiedz

3

Jeśli nie potrzebujesz, aby móc manipulować someFkRef pomiędzy użytkownikami (np. Zdobywając listę użytkowników zainteresowanych czymś), możesz mieć tylko jeden rekord na użytkownika, z uporządkowaną listą someFkRef (refA , refB).

Ale jest to forma de-normalizacji, a ponieważ ma pewne wady, to naprawdę zależy od Twoich potrzeb (i przyszłych potrzeb, czyli skąd się bierze ten problem)

+0

Tak, denormalizacja uderzy cię nawet wtedy, gdy jest to ten sam użytkownik: a) musisz "ograniczyć/przesunąć" i manipulować dużą listą; b) dane te są przesyłane przez Internet, a użytkownik sortuje listę stu elementów w szybki sposób (hello, O (N), opóźnienia i desynchronizacja). Denormalizacja to wielki ból i nikt nigdy nie powinien tego robić. –

6

Dla przeciągnij i upuść interakcji, lepszy zakład jest priorytetem. Zaczynasz od priorytetów 1, 2, 3 itd., Podobnie jak kolejność sortowania.

Ale wtedy użytkownik chce przenieść pozycję 5 między 1 a 2. Voila! Podaj wartość 1,5. Żadne inne wartości nie muszą się zmieniać. Aktualizacja indeksu zajmuje się resztą.

Aby to działało, priorytet musi być przechowywany jako liczba zmiennoprzecinkowa. To może być problem. Ponadto wystarczająco duża liczba zmian może spowodować przesunięcie granic zmiennoprzecinkowych. Tak więc, jeśli użytkownik spróbuje wziąć ostatni element i włożyć go między dwie pierwsze, może uciec z nim około kilkudziesięciu razy.

Można rozwiązać ten problem w procesie, który okresowo przypisuje numer do jednego (lub wszystkich użytkowników, jeśli w partii), począwszy od 1.

+0

To także cenne podejście. Ale nadal musisz mieć indeks na kolumnie someFkRef, więc nadal będzie to trochę wymagające, ponieważ tabela jest BARDZO duża. –

+1

@SamuelEUSTACHI Indeks nie jest najgorszy. Najgorsze jest to, że liczby zmiennoprzecinkowe mają skończoną precyzję i po 53 dobrze zaprojektowanych ruchach można złamać logikę porządkowania. Tak, zawsze możesz mieć licznik i wyzwalacz do renormalizacji tej listy, ale nie jestem pewien, czy to będzie bardziej wydajne rozwiązanie. –

1

Nie wiesz, co twoje referencje zależnych może być do pola ID, ale masz Myślałeś o przepisaniu go? Wydaje mi się, że istnieje IDENTYFIKACJA SET IDENTYFIKACJI = WŁ, lub kilka takich, które możesz zrobić.

Zdaję sobie sprawę, że jest to dziwna rzecz do zasugerowania, ale biorąc pod uwagę to, co próbujesz zrobić, może to mieć sens, i spowodować najmniejszy narzut.

+0

@Joachim - Przenumeruj numer rekordu = 2 - tylko rekordy dawcy i odbiorcy. Reindex jest nieokreślony - prawdopodobnie ma wbudowaną wbudowaną pamięć, a przy milionach rekordów prawdopodobnie ponownie indeksuje poza szczytem. – Chains

Powiązane problemy