Chciałbym dokonać paginacji przez losowo posortowaną listę modeli ActiveRecord (wiersze z bazy danych MySQL).Stały/powtarzalny sortowanie losowe (MySQL, Rails)
Jednak ta randomizacja musi trwać przez jedną sesję, aby inne osoby odwiedzające tę stronę otrzymały losową, możliwą do paginacji listę rekordów.
Załóżmy, że istnieje wystarczająco dużo encji (dziesiątek tysięcy), które przechowują losowo posortowane wartości ID w sesji lub plik cookie jest zbyt duży, więc muszę tymczasowo utrzymywać go w jakiś inny sposób (MySQL, plik itp.).).
Początkowo myślałem, że mogę utworzyć funkcję opartą na identyfikatorze sesji i identyfikatorze strony (zwracanie identyfikatorów obiektu dla tej strony), jednak ponieważ wartości identyfikatora obiektu w MySQL nie są sekwencyjne (są luki), które wydawały się być rozpadnie się, gdy go szturchałem. Fajną rzeczą jest to, że nie wymagałoby to/minimalnego przechowywania, ale wadą jest to, że prawdopodobnie jest dość skomplikowany w implementacji i prawdopodobnie intensywny procesor.
moim odczuciu należy utworzyć tabelę przecięcia, coś takiego:
random_sorts(sort_id, created_at, user_id NULL if guest)
random_sort_items(sort_id, item_id, position)
A potem po prostu przechowywać „sort_id” w sesji. Następnie mogę w paginacji random_sorts WHERE sort_id = n ORDER BY position LIMIT ... jak zwykle.
Oczywiście, musiałbym włożyć tam pewnego rodzaju żniwiarkę, aby usunąć je po pewnym okresie bezczynności (na podstawie random_sorts.created_at).
Niestety, musiałbym unieważnić sortowanie w miarę tworzenia nowych obiektów (i/lub usuwania starych obiektów, chociaż usuwanie jest bardzo rzadkie). I, jak obciążenie zwiększa rozmiar/wydajność tej tabeli (nawet poprawnie indeksowane) spada.
Wygląda na to, że powinien to być problem rozwiązany, ale nie mogę znaleźć wtyczek, które to robią ... Jakieś pomysły? Dzięki!!
Tak, to działa tak długo, jak wiersze w tabeli nigdy się nie zmieniają (jeśli dodany jest nowy, rozumiem, że cały zestaw może się zmienić). Co więcej, powoduje to skanowanie tabeli za każdym razem, co może być dużym hitem wydajności ... –
Twój komentarz wydaje się prawidłowy (choć czasami * chcesz * wszystko trzeba zastosować, jeśli tabela podstawowa dodaje coś nowego). Niestety nie mogę wymyślić sposobu, aby uniknąć skanowania całego stołu za każdym razem, ale może "zamówienie według id 10" może być wystarczająco inteligentne, aby wyjść wcześnie ...). Jeśli jednak nie wykonasz "zamówienia przez", to dodanie nowego wpisu może nadal losować twoje dane wyjściowe, AFAIK, więc to może być trudne pytanie, aby dostać się dobrze ... – rogerdpack
wygląda jak zamówienie przez rand, następnie limit "robi "co najmniej pełne skanowanie tabeli (w mysql), chociaż mogą istnieć sztuczki, których można by użyć, aby go przyspieszyć w przypadku dużych tabel: http://stackoverflow.com/questions/211329/quick-selection-a- random-row-from-a-large-table-in-mysql/211388 – rogerdpack