To pytanie jest w rzeczywistości wiązką problemów z połączonym modelem danych. Musisz zacząć je rozplątywać pojedynczo. Bardziej naturalne, intuicyjne rozwiązania znikną, gdy spróbujesz uprościć każdy element układanki.
Problem 1: Nie możesz polegać na zamówieniu DB
Twoje opisy sortowania danych nie są jasne.
- Największym potencjalnym problemem jest to, że nie określasz jawnego sortowania w bazie danych za pomocą
ORDER BY
klauzuli. Jeśli nie jesteś, ponieważ wydaje się to zbyt drogie, twój program ma błąd . Bazy danych mogą zwracać wyniki w dowolnej kolejności, jeśli nie zostanie określona; nie możesz polegać na tym, że przypadkowo zwraca dane w kolejności tylko dlatego, że uruchomiłeś zapytanie kilka razy i tak to wygląda. Kolejność może ulec zmianie, ponieważ wiersze są przestawiane na dysku lub niektóre są usuwane, a nowe zajmują miejsce lub dodawany jest indeks. Państwo musi określić ORDER BY
klauzulę jakiegoś rodzaju. Prędkość jest bezwartościowa bez poprawności.
- Nie jest również jasne, co rozumiesz przez znaczenie kolejności wstawiania. Jeśli mówisz o samej bazie danych, musisz mieć kolumnę, która faktycznie to śledzi, i musi być uwzględniona w
ORDER BY
klauzuli. W przeciwnym razie masz błędy. Jeśli taka kolumna jeszcze nie istnieje, musisz ją dodać. Typowe opcje dla takich kolumn to kolumna ze znacznikiem czasu wstawiania lub klucz automatycznego zwiększania. Klucz automatycznego zwiększania jest bardziej niezawodny.
Problem 2: Wydajne sortowanie w pamięci
Po upewnieniu się, że gwarantowane jest zwracanie danych w oczekiwanej kolejności, możesz wykorzystać ten fakt, aby sortowanie w pamięci było znacznie wydajniejsze. Wystarczy dodać kolumnę row_number()
lubdense_rank()
(lub odpowiednik bazy danych) do zestawu wyników zapytania. Teraz każdy wiersz ma indeks , który da ci bezpośrednie wskazanie, jaka powinna być kolejność, i możesz sortować według tego trywialnie w pamięci. Upewnij się tylko, że nadasz indeksowi znaczącą nazwę (np sortedBySomethingIndex
.).
Altówka. Teraz nie musisz już polegać na kolejności zestawów wyników bazy danych.
Problem 3: Czy w ogóle potrzebujesz tego przetwarzania w kodzie?
SQL jest naprawdę bardzo wydajny. To niesamowity deklaratywny język, który pozwala na wiele przekształceń i agregacji danych. Większość DB obsługuje obecnie nawet operacje między wierszami. Nazywa się je funkcjami okna lub analitycznymi:
Czy w ogóle potrzebujesz wciągnąć swoje dane do pamięci? Czy możesz wykonać całą pracę w zapytaniu SQL, używając funkcji okna? Jeśli możesz wykonać całą (a może nawet znaczącą część) pracę w DB, to fantastycznie! Twój problem z kodem zniknął (lub stał się o wiele prostszy)!
Problem 4: Co robisz data
?
Zakładając, że nie możesz zrobić tego wszystkiego w DB, pozwól mi to wyjaśnić. Bierzesz dane jako mapę (na którą składają się rzeczy, których nie chcesz sortować), a następnie iterujesz je w kolejności wstawiania i modyfikujesz mapę w miejscu, zastępując wartość niektórych kluczy i dodając nowe?
Przepraszam, ale co do cholery?
Dzwoniący nie powinni się o to martwić . System, który stworzyłeś, jest wyjątkowo delikatny. Wystarczy jeden głupi błąd (może nawet popełniony przez ciebie, tak jak wszyscy to zrobiliśmy), aby wprowadzić jedną małą złą zmianę, a cała sprawa zapada się jak talia kart.
Oto może lepszy pomysł:
- Niech twoja funkcja zaakceptuje a
List
.
- Istnieje kilka sposobów rozwiązania problemu z zamówieniem.
- Zastosuj szybko Fast. Zgłaszaj błąd, jeśli lista nie jest w kolejności wymaganej przez funkcję. (Uwaga: Możesz użyć indeksu sortowania z Problemu 2, aby stwierdzić, czy jest).
- Utwórz samodzielnie posortowaną kopię (ponownie, korzystając z indeksu z problemu 2).
- Wymyśl sposób na zbudowanie samej mapy w kolejności.
- Zbuduj potrzebną mapę wewnętrznie dla funkcji, aby osoba dzwoniąca nie musiała się tym przejmować.
- Teraz powtarzaj wszystko, co reprezentujesz w porządku, i rób to, co musisz.
- Zwróć mapę lub przekształć ją w odpowiednią wartość zwracaną
Możliwą odmianą może być zbudowanie posortowanej reprezentacji, a następnie utworzenie mapy klucza do indeksu . Umożliwi to zmodyfikowanie posortowanej kopii w miejscu, bez przypadkowego tworzenia duplikatów.
A może ma to bardziej sens: pozbyć się data
parametru i processData
faktycznie pobrać własne dane. Następnie możesz udokumentować, że to robisz, ponieważ ma bardzo specyficzne wymagania dotyczące sposobu pobierania danych. Innymi słowy, spraw, aby funkcja była właścicielem całego procesu, a nie tylko jednego jego fragmentu; wzajemne zależności są zbyt silne, aby podzielić logikę na mniejsze części. (Zmień nazwę funkcji w tym procesie.)
Może to nie zadziała w twojej sytuacji. Nie wiem bez pełnych szczegółów problemu. Ale znam kruchy i mylący projekt, kiedy go słyszę.
Podsumowanie
Myślę, że problemem tutaj jest to, że diabeł tkwi w szczegółach. Kiedy zaczynam mieć takie kłopoty, zwykle dzieje się tak dlatego, że mam nieodpowiednią reprezentację moich danych dla problemu, który próbuję rozwiązać. Najlepszym rozwiązaniem jest znalezienie lepszej reprezentacji , a wtedy mój problem staje się prosty (może nie łatwy, ale bezpośredni) do rozwiązania.
Znajdź kogoś, kto osiągnie ten punkt: Twoim zadaniem jest zredukowanie problemu do zestawu prostych, prostych. Następnie możesz zbudować solidny, intuicyjny kod. Porozmawiaj z nimi. Dobry kod i dobry design sprawiają, że myślisz, że każdy idiota mógł je wymyślić, ponieważ są one proste. Może jest jakiś starszy programista, który ma sposób myślenia, z którym możesz porozmawiać.