Trudność SQL wynika z algebry relacyjnej

W dziedzinie przetwarzania danych strukturalnych SQL jest nadal najczęściej używanym językiem roboczym, nie tylko przyjętym przez wszystkie relacyjne bazy danych, ale także ukierunkowanym przez wiele nowych platform Big Data.

W przypadku określonej technologii obliczeniowej ludzie zwykle dbają o dwie wydajności. Jedną z nich jest opisowa wydajność operacji, a drugą wydajność wykonania operacji. Łatwo to zrozumieć. Jeśli wydajność opisowa jest zbyt niska, oznacza to, że koszt rozwoju jest zbyt wysoki i trudno jest pisać programy do obliczeń; Jeśli wydajność wykonania jest niska, uzyskanie wyników zajmuje dużo czasu, co znacznie zmniejsza jego praktyczną wartość. Mówiąc prościej, oznacza to proste pisanie i szybkie działanie.

Jednak wcześniej przeanalizowaliśmy niektóre scenariusze obliczeniowe dla danych strukturalnych, a SQL w rzeczywistości nie radzi sobie dobrze zarówno z prostym pisaniem, jak i szybkim działaniem. Gdy sytuacja jest nieco bardziej złożona, trudno jest sobie z nią poradzić, często skutkując tysiącami linii zagnieżdżonych N warstw kodu i dziesiątkami gigabajtów obliczeń wymagających kilku godzin na uruchomienie. Dwa typowe przykłady to obliczanie liczby dni, w których akcje nieprzerwanie rosły oraz TopN dla całego zbioru i w grupach dużego zbioru. Szczegóły nie będą tutaj powtarzane, a zainteresowanych odsyłam do poprzednich wpisów.

Ile dni akcje nieprzerwanie rosną przez najdłuższy czas? Pierwotnie proste zadanie, ze względu na brak uporządkowanej zdolności obliczeniowej, musi być zapisane w wielowarstwowej zagnieżdżonej formie, która jest trudna do napisania i zrozumienia:

select max(ContinuousDays) from (

    select count(*) ContinuousDays from (

        select sum(UpDownTag) over (order by TradeDate) NoRisingDays from (

            select TradeDate,case when Price>lag(price) over ( order by TradeDate)then 0 else 1 end UpDownTag from Stock ))

    group by NoRisingDays )

Aby uzyskać 10 najlepszych spośród 100 milionów danych i uzyskać 10 najlepszych z każdej grupy po pogrupowaniu, istnieje znaczna różnica w pisaniu, a wszystkie mają ORDER BY w instrukcji, co oznacza, że należy wykonać sortowanie o dużej złożoności i można polegać tylko na optymalizatorze bazy danych, aby znaleźć algorytmy o niskiej złożoności.

SELECT TOP 10 * FROM Orders ORDER BY Amount DESC
SELECT * FROM (
    	SELECT *, ROW_NUMBER() OVER (PARTITION BY Area ORDER BY Amount DESC) rn FROM Orders )
WHERE rn<=10

Przeanalizowaliśmy również przyczyny. SQL nie ma dyskretności, co skutkuje niekompletną orientacją zbiorów, trudnymi obliczeniami uporządkowanymi i trudnościami w opisywaniu wysokowydajnych algorytmów…

Kryje się za tym jednak głębszy powód, ponieważ fundamentalna trudność SQL w rzeczywistości wynika z jego teoretycznych podstaw, a mianowicie algebry relacyjnej.

Aby wyjaśnić ten pogląd, musimy przeanalizować, co tak naprawdę robi używanie programów do implementacji obliczeń.

Zasadniczo, proces pisania programu jest procesem przekładania pomysłów na rozwiązywanie problemów na precyzyjny język formalny, który może być wykonywany przez komputer. Na przykład, podobnie jak uczniowie szkoły podstawowej rozwiązujący praktyczne problemy, po przeanalizowaniu problemu i znalezieniu rozwiązania, muszą również wypisać cztery wyrażenia arytmetyczne. To samo dotyczy obliczania za pomocą programu. Nie tylko musimy wymyślić rozwiązanie problemu, ale musimy również przełożyć rozwiązanie na działania, które komputer może zrozumieć i wykonać w celu wdrożenia obliczeń.

W przypadku języka formalnego używanego do opisu metod obliczeniowych, jego rdzeń leży w używanym systemie algebraicznym. Nie możemy tutaj ściśle zdefiniować pojęcia systemu algebraicznego, wyjaśnimy je jedynie w kategoriach laika. Aby rozwiązać pewien problem obliczeniowy, ludzie definiują pewne typy danych i zestaw reguł operacyjnych dla tych typów danych, zapewniając bliskość i spójność tych operacji, które można nazwać systemem algebraicznym. Na przykład, znane liczby wymierne i ich cztery operacje arytmetyczne są systemem algebraicznym używanym do rozwiązywania potrzeb obliczeń numerycznych w życiu codziennym. Bliskość odnosi się do wymogu, aby wynik obliczeń nadal był zdefiniowanym obiektem danych, takim jak wynik czterech operacji arytmetycznych na liczbach wymiernych, który nadal jest liczbą wymierną. Spójność odnosi się do faktu, że operacje te nie mogą dawać sprzecznych wyników. Na przykład, musimy zgodzić się, że nie można ich dzielić przez 0, w przeciwnym razie dzielenie pewnej liczby przez 0 na dowolną liczbę doprowadzi do logicznych sprzeczności.

Jeśli projekt tego systemu algebraicznego nie jest starannie przemyślany, a dostarczone typy danych i operacje są niewygodne, bardzo trudno będzie opisać algorytm. W tym momencie pojawia się dziwne zjawisko – trudność przetłumaczenia rozwiązania na kod znacznie przewyższa trudność rozwiązania samego problemu.

Na przykład, od dzieciństwa nauczyliśmy się używać cyfr arabskich do codziennych obliczeń, a implementacja dodawania, odejmowania, mnożenia i dzielenia jest bardzo wygodna. Każdy naturalnie wierzy, że operacje numeryczne powinny tak wyglądać. W rzeczywistości niekoniecznie! Myślę, że większość ludzi wie o czymś, co nazywa się cyframi rzymskimi. Nie jestem pewien, czy system cyfr rzymskich ma również znane operacje dodawania, odejmowania, mnożenia i dzielenia (które nie mogą być łatwo zaimplementowane jak cyfry arabskie, a definicja operacji może być inna). Nie wiem też, jak starożytni Rzymianie robili zakupy.

Wiemy więc, że to, czy program można napisać w prosty sposób, jest w rzeczywistości problemem algebraicznym stojącym za językami programowania.

Jak wspomnieliśmy wcześniej, szybkie działanie jest zasadniczo tym samym, co proste pisanie, czyli może sprawić, że algorytmy o wysokiej wydajności będą łatwe do napisania. W ten sposób szybkie działanie jest nadal problemem algebraicznym.

Proszę pozwolić sobie na jeszcze jedną analogię:

Większość uczniów, którzy uczęszczali do szkoły podstawowej w Chinach, zna historię Gaussa obliczającego 1+2+3+…+100. Zwykli ludzie po prostu dodają 100 razy krok po kroku. Dziecko Gaussa jest bardzo bystre i odkryło, że 1+100=101, 2+99=101, …, 50+51=101, a wynik to 50 pomnożone przez 101, szybko skończyło obliczenia i poszło do domu na obiad.

Po wysłuchaniu tej historii wszyscy czujemy, że Gauss jest bardzo sprytny i może wymyślić tak sprytną metodę, która jest prosta i szybka. Nie jest to błędne, ale łatwo przeoczyć jedną kwestię: w czasach Gaussa mnożenie istniało już w ludzkim systemie arytmetycznym (również algebrze)! Jak wspomniano wcześniej, kiedy uczymy się czterech działań arytmetycznych od najmłodszych lat, możemy uznać mnożenie za coś oczywistego, ale w rzeczywistości mnożenie zostało wynalezione później niż dodawanie. Chociaż mnożenie jest zdefiniowane przez dodawanie, jego cechy można wykorzystać do obliczeń przy użyciu tabeli 9×9, co znacznie poprawia wydajność. Gdyby w czasach Gaussa nie istniało mnożenie, nawet przy pomocy sprytnego Gaussa nie byłoby możliwe szybkie rozwiązanie tego problemu.

Matematyczną podstawą SQL jest algebra relacyjna, która jest systemem algebraicznym używanym do wykonywania obliczeń na danych o strukturze wsadowej. Dlatego też bazy danych korzystające z SQL są również nazywane relacyjnymi bazami danych.

Algebra relacyjna została wynaleziona pięćdziesiąt lat temu, a wymagania aplikacji i środowisko sprzętowe pięćdziesiąt lat temu znacznie różnią się od dzisiejszych. Ze względu na dużą liczbę istniejących użytkowników i brak dojrzałych nowych technologii, SQL oparty na algebrze relacyjnej pozostaje obecnie najważniejszym językiem programowania baz danych. Chociaż w ciągu ostatnich kilku dekad wprowadzono pewne ulepszenia, podstawy nie uległy zmianie. W obliczu współczesnych złożonych wymagań i środowisk sprzętowych, relacyjne bazy danych nie są już tak sprawne.

Algebra relacyjna jest zbyt prosta i brakuje jej wystarczających typów danych i operacji. Dlatego też, używając SQL do opisania rozwiązania problemu, konieczne jest znalezienie zawiłych sposobów na jego implementację. Na przykład problem wzrostu cen akcji, ponieważ algebra relacyjna stosuje teorię zbiorów nieuporządkowanych w matematyce i nie tworzy koncepcji porządku dla SQL, zamienia prosty problem w trudny problem, nawet jeśli obiera objazd, jest trudny do napisania. Prowadzi to do zjawiska, że trudność rozwiązania problemów z tłumaczeniem jest większa niż trudność rozwiązania samego problemu, jak wspomniano wcześniej. Problem top 10 jest również tym samym przypadkiem, operacja agregacji zaprojektowana dla algebry relacyjnej nie obejmuje TOPN i nie ma typu danych zestawu. Dlatego operacja ta nie może być zaprojektowana jako operacja agregacji i może być opisana tylko jako sortowanie duże.

Algebra relacyjna jest jak system arytmetyczny, który obejmuje tylko dodawanie, ale nie wymyślił jeszcze mnożenia, a wiele rzeczy jest nieuniknionych, jeśli nie zostaną dobrze wykonane.

Gdy obliczenia są proste lub wymagania dotyczące wydajności nie są wysokie, korzystanie z SQL jest nadal stosunkowo wygodne, w końcu istnieje wielu mistrzów, a powiązane oprogramowanie jest również bardzo bogate. Jednak wymagania dotyczące danych w nowoczesnych aplikacjach stają się coraz bardziej złożone, a ilość danych również rośnie. Dalsze korzystanie z SQL poważnie wpłynie na wydajność pracy. Co więcej, problem ten jest niestety teoretyczny i bez względu na to, w jaki sposób dokonywana jest optymalizacja w inżynierii, jest ona bezużyteczna i może być poprawiona tylko w ograniczonym zakresie, a nie wyeliminowana. Jednak zdecydowana większość deweloperów baz danych nie pomyślałaby o tej warstwie, a raczej, aby zaspokoić kompatybilność istniejących użytkowników, nie zamierzali myśleć o tej warstwie. Tak więc główny nurt branży baz danych krąży w tym kręgu.

Co zatem powinniśmy zrobić? Jak sprawić, by obliczenia były prostsze i działały szybciej?

Proszę wymyślić nową algebrę! Algebra z “mnożeniem”. Na tym polega różnica między esProc SPL. Nadaliśmy algebraicznej podstawie SPL matematyczną nazwę: dyskretne zbiory danych. SPL jest formalnym językiem tej algebry. Zalety SPL były wielokrotnie omawiane w poprzednich artykułach. Dzięki wsparciu nowej algebry jesteśmy naprawdę w stanie pisać proste, ale szybkie programy.