Czuję się bardzo dobrze z programowaniem imperatywnym. Nigdy nie mam problemu z wyrażeniem algorytmicznym tego, co chcę, aby komputer zrobił, gdybym zorientował się, co mam zrobić. Ale jeśli chodzi o języki takie jak SQL lub często utknąłem, ponieważ moja głowa jest zbyt przyzwyczajona do programowania imperatywnego.
Załóżmy na przykład, że masz zespół relacji (bandName, bandCountry), venue (venueName, venueCountry), odtworzenia (bandName, venueName), a ja chcę napisać zapytanie, które brzmi: wszystkie nazwy venue takie, że dla każdego bandCountry jest zespół z kraj, który gra w miejscu o tej nazwie.
Przykład: Chcę, aby wszystkie nazwy miejsc, w których grały zespoły ze wszystkich krajów (bandCountry). Również przez „relację” rozumiem tabelę SQL.
W mojej głowie od razu wybieram „dla każdego miejsca nazwa-miejsca iteruje po wszystkich zespołach-krajach i dla każdego zespołu-państw otrzymuję listę zespołów, które z niego pochodzą. Jeśli żadne z nich nie gra w miejscu-nazwa, przejdź do następnego miejsca-nazwa. W przeciwnym razie na końcu zespołu iteracja dodaj venueName do zestawu dobrych venueName ".
... ale nie można tak mówić w języku SQL i muszę pomyśleć o tym, jak to sformułować, a intuicyjne rozwiązanie Imperative ciągle dręczy mnie z tyłu głowy. Czy ktoś miał ten problem? Jak sobie z tym poradziłeś? Czy wymyśliłeś zmianę paradygmatu? Czy stworzyłeś mapę od koncepcji imperatywnych do koncepcji SQL, aby przetłumaczyć rozwiązania imperatywne na deklaratywne? Przeczytaj dobrą książkę?
PS Nie szukam rozwiązania powyższego zapytania, rozwiązałem je.
źródło
Odpowiedzi:
Pomysł robienia rzeczy deklaratywnie polega na tym, że należy określić, co , a nie jak .
Dla mnie brzmi, jakbyś był na dobrej drodze. Problemem nie jest to, że myślisz o rzeczach w niewłaściwy sposób. Chodzi o to, że posuwasz się za daleko. Spójrzmy na to, co próbujesz zrobić:
Jak dotąd jest to świetne. Ale potem robisz to:
Zasadniczo wykonujesz niepotrzebną pracę. Wiesz, czego chcesz, a to wszystko, czego naprawdę potrzebujesz. Ale potem idź dalej i spróbuj dowiedzieć się, jak go zdobyć.
Gdybym był tobą, starałbym się nabrać następującego nawyku:
Może to zająć trochę czasu i wysiłku z twojej strony, ale kiedy naprawdę zaczniesz programować deklaratywnie, staje się to bardzo przydatne. W rzeczywistości możesz znaleźć deklaratywne programowanie w pozostałej części kodu.
Jeśli szukasz książki, polecam SQL i teorię relacyjną . To naprawdę pomaga zrozumieć teorię baz danych SQL. Pamiętaj tylko, aby wziąć zalecenia Date z odrobiną soli. Udziela bardzo dobrych informacji, ale czasem może być nieco uparty.
źródło
myśl w kategoriach zbiorów, a nie iteratorów; instrukcje sql definiują właściwości pożądanego zestawu danych wyjściowych (inaczej tabela / relacja)
wynikiem tego (jeśli dobrze zrozumiałem twoje intencje!) byłby zestaw miejsc, w których przynajmniej jeden zespół gra w tym miejscu. Iteracja nad bandCountry nie jest konieczna, ponieważ relacja PLAYS już zawiera informacje, których szukasz, po prostu musisz wyeliminować duplikaty
więc w SQL byłoby to:
EDYCJA: ok, więc faktyczny pożądany zestaw jest nieco bardziej skomplikowany. Baza danych zadaje pytanie: jakie miejsca gościły zespoły ze wszystkich krajów?
Tak więc definiujemy kryteria członkostwa dla elementu pożądanego zestawu jako cel, a następnie pracujemy wstecz, aby wypełnić zestaw. Miejsce jest członkiem zestawu wyników, jeśli ma wiersz PLAYS dla co najmniej jednego zespołu z każdego kraju. Jak uzyskać te informacje?
Jednym ze sposobów jest policzenie różnych krajów dla każdego miejsca i porównanie ich z liczbą wszystkich krajów. Ale nie mamy relacji KRAJ. Jeśli zastanowimy się przez chwilę nad modelem, zobaczymy, że zbiór wszystkich krajów nie jest właściwym kryterium; to zbiór wszystkich krajów, które mają co najmniej jeden zespół. Nie potrzebujemy więc tabeli kraju (chociaż w przypadku znormalizowanego modelu powinniśmy ją mieć) i nie dbamy o kraj miejsca, możemy po prostu policzyć kraje, które mają pasma, np. (W MS-SQL )
Możemy policzyć kraje zespołu dla każdego miejsca
i możemy poskładać je razem za pomocą podzapytania
To nie jest najładniejsze możliwe zapytanie (GROUP BY i HAVING można uznać za bardziej „eleganckie” rozwiązanie niż zmienne tymczasowe i podzapytanie), ale to dość oczywiste, o co nam chodzi, więc zostawimy to na cel PO .
Celem PO było nauczenie się, jak zmienić sposób myślenia z imperatywnego na deklaratywny. W tym celu spójrz na to, co robiło opisane imperatywne rozwiązanie:
Jakie są powyższe kryteria? Myślę, że to jest:
To są kryteria dyskwalifikujące . Konieczny proces myślenia rozpoczyna się od pełnego wiadra i wyrzucania rzeczy, które nie spełniają kryteriów. Jesteśmy filtrowanie danych.
To proste w przypadku prostych rzeczy, ale pomaga myśleć w kategoriach konstruowania pożądanego zestawu wyników; jakie są odpowiednie kryteria kwalifikacyjne , które pozwoliłyby zamiast tego wypełnić wiadro?
Ostateczny kwalifikator można uprościć za pomocą liczników: bandCountry jest „zadowolony”, jeśli przynajmniej jeden zespół stamtąd gra w danym miejscu; liczba „zadowolonych” krajów zespołu dla danego miejsca musi być równa liczbie krajów zespołu dla danego miejsca, które ma zostać zakwalifikowane.
Teraz możemy uzasadnić relacje między nawigacjami:
co prowadzi do powyższego rozwiązania (lub jego uzasadnionego faksu)
PODSUMOWANIE
źródło
Jednym ze sposobów nauczenia się myślenia i programowania w stylu deklaratywnym jest nauczenie się języka tablic ogólnego przeznaczenia, takiego jak APL lub J. SQL prawdopodobnie nie jest najlepszym narzędziem do nauki deklaratywnego programowania. W APL lub J uczysz się obsługiwać całe tablice (wektory, macierze lub tablice wyższej rangi), bez wyraźnego zapętlania lub iteracji. To znacznie ułatwia zrozumienie algebry SQL i relacyjnej. Jako bardzo prosty przykład, aby wybrać elementy z wektora V, których wartość jest większa niż 100, w APL piszemy:
Tutaj V> 100 przyjmuje wartość logiczną do tablicy o tym samym kształcie co V, gdzie 1 oznacza wartości, które chcemy zachować. Doświadczonemu APLerowi nie przychodzi do głowy, że trwa iteracja, po prostu nakładamy maskę na wektor V, zwracając nowy wektor. Jest to oczywiście koncepcyjnie to, co robi operacja SQL, w której klauzula lub relacyjna algebra ograniczają działanie.
Nie sądzę, że można dobrze opanować programowanie deklaratywne bez robienia tego dużo, a SQL ogólnie jest zbyt specyficzny. Musisz napisać dużo kodu ogólnego przeznaczenia, nauczyć się, jak obchodzić się bez pętli i struktur if / then / else, a także całego aparatu, który uczestniczy w programowaniu imperatywnym, proceduralnym i skalarnym.
Mogą istnieć również inne języki funkcjonalne, które pomagają w takim sposobie myślenia, ale języki tablicowe są bardzo zbliżone do SQL.
źródło
a = a + 1
) przez noc. Nauczenie się stylów deklaratywnych, takich jak logika, funkcjonalność, zajmuje trochę czasu, podobnie jak nauczenie się programowania imperatywnego.Najpierw musisz nauczyć się obu. Możesz mieć preferencje, ale pracując w obszarach, w których drugi jest lepszy, nie walcz z nim. Wielu programistów ma pokusę używania kursorów w relacyjnych bazach danych, ponieważ są przyzwyczajeni do przechodzenia przez każdy rekord, ale baza danych jest znacznie lepsza w zestawach. Nie chcesz wejść w sposób myślenia: „Wiem, jak to zrobić w ten sposób i mam największą kontrolę, bla, bla, bla”.
źródło
Nauczysz się myśleć deklaratywnie, tak jak nauczyłeś się myśleć imperatywnie: ćwicząc zaczynając od prostszych problemów i pracując nad tym, jak „rozumiesz”.
Twoje pierwsze doświadczenia z programowaniem imperatywnym obejmowały całą masę sprzecznych z intuicją (i wręcz absurdalnie) stwierdzeń takich jak „
a = a + 1
”. Otoczyłeś to umysłem do tego stopnia, że teraz prawdopodobnie nie pamiętasz nawet odrzutu z oczywistej nieprawdy tego stwierdzenia. Problem ze stylami deklaratywnymi polega na tym, że powróciłeś tam, gdzie byłeś, kiedy zacząłeś ze stylami imperatywnymi: „nieświadomym nowością”. Co gorsza, masz lata praktyki z jednym stylem, który jest całkowicie sprzeczny z tym nowym stylem i masz lata nawyków, aby je cofać - na przykład nawyk „kontrolowania za wszelką cenę”.Style deklaratywne działają z innym podejściem, na razie brakuje ci intuicji (chyba że z biegiem lat utrzymywałeś bardzo matematyczne umiejętności - czego większość ludzi nie ma). Musisz nauczyć się, jak myśleć i jedynym sposobem, aby nauczyć się tego robić, jeden prosty krok na raz.
Wybór SQL jako pierwszego wyjścia do deklaratywnego programowania może być błędem, jeśli naprawdę chcesz nauczyć się pojęć. Jasne, że rachunek krotek, na którym jest oparty, jest tak naprawdę deklaratywny, jak to tylko możliwe, ale niestety czystość rachunku krotek została poważnie naruszona przez realia implementacji, a język stał się trochę mętnym bałaganem. Zamiast tego możesz spojrzeć na inne bardziej użyteczne (w tym sensie, do jakiego jesteś przyzwyczajony) języki deklaratywne, takie jak Lisps (zwłaszcza Scheme ), Haskell i ML dla (głównie) programowania funkcjonalnego lub, alternatywnie, Prolog i Mercury dla (głównie) programowanie logiki.
Nauka tych innych języków zapewni moim zdaniem lepszy wgląd w działanie deklaratywnego programowania z kilku powodów:
Przydają się do programowania „od kołyski do grobu” - ponieważ możesz napisać pełny program w tych językach od początku do końca. Są przydatne samodzielnie, w przeciwieństwie do SQL, który jest naprawdę bezużyteczny dla większości ludzi jako samodzielny język.
Każdy z nich ma inne podejście do deklaratywnego programowania, które może dać ci różne drogi, by w końcu „zdobyć”.
Każdy z nich daje inne podejście do programowania w ogóle. Poprawią twoją zdolność rozumowania problemów i kodowania, nawet jeśli sam nigdy ich nie użyjesz.
Lekcje, których się z nich nauczysz, pomogą ci również w posługiwaniu się językiem SQL - szczególnie jeśli odświeżysz rachunek krotek za relacyjnymi bazami danych, aby uzyskać czystą formę myślenia o danych.
Szczególnie polecam naukę jednego z języków funkcjonalnych ( Clojure , jako jeden z Lisps, jest prawdopodobnie dobrym wyborem tutaj) i jednego z języków logicznych (lubię Mercury'ego najbardziej, ale Prolog ma o wiele bardziej użyteczny materiał do nauki) dla maksymalnego rozszerzenia procesu myślowego.
źródło
Nie jest źle myśleć imperatywnie w deklaratywnych ustawieniach, takich jak SQL. Po prostu imperatywne myślenie powinno odbywać się na poziomie nieco wyższym niż to, co opisałeś. Ilekroć muszę zapytać bazę danych, która korzysta z SQL, zawsze myślę sobie:
Powyżej jest algorytm imperatywny wysokiego poziomu i działa całkiem dobrze dla mnie w ustawieniach SQL. Myślę, że jest to uważane za podejście top-down i Steven A. Lowe opisać całkiem dobry oddolne podejście.
źródło
Kluczem do twojego pytania jest to, co powiedziałeś w ostatnim akapicie: „Nie możesz tak mówić w języku SQL”. Na tym etapie może być bardziej użyteczne podejście do SQL jako języka obcego zamiast języka programowania. Jeśli pomyślisz o tym w ten sposób, napisanie zapytania SQL naprawdę tłumaczy angielską instrukcję na „SQLish”. Komputer doskonale rozumie SQLish i zrobi dokładnie to, co mówisz, więc nie musisz się martwić o implementację, o ile poprawnie tłumaczysz.
To powiedziawszy, jaki jest najlepszy sposób na naukę języka obcego? Oczywiście musisz nauczyć się gramatyki i słownictwa, które możesz uzyskać z dokumentacji SQL. Najważniejsza jest praktyka. Powinieneś czytać i pisać jak najwięcej SQL, i nie czujesz, że najpierw musisz dokładnie znać składnię; możesz i powinieneś szukać rzeczy w miarę postępów. Będziesz wiedział, że go masz, gdy łatwiej jest opisać, jakie dane chcesz w SQL niż w języku angielskim.
źródło
Zajęło mi również dużo czasu, aby owinąć głowę wokół SQL. Na uniwersytecie zrobiliśmy teorię relacyjną, która tylko skomplikowała sprawę. Ostatecznie mój proces uczenia się opierał się na wielu próbach i błędach opartych na różnych materiałach do nauki i przykładach, które uznałem za przydatne po drodze. Zasadniczo w końcu się do tego przyzwyczaisz, a dodanie nowego sposobu myślenia o danych i zapytaniach będzie miało pewną wartość dla twojego rozwoju umysłowego.
Odkryłem, że byłem w stanie przyspieszyć naukę, stopniowo budując kolekcję prostych skryptów pokazujących, jak korzystać z każdej funkcji języka i jak osiągnąć określone wyniki na znanej tabeli (definicje tabel podano w celach informacyjnych).
Na początku tego roku odbyłem formalne szkolenie obejmujące projekt migracji danych w niechlujnej bazie danych Oracle, w której musiałem stopniowo składać fragmenty z mojej biblioteki, aby filtrować wyniki zapytań na różne sposoby, aż do uzyskania dokładnie tego, czego chciałem, a następnie przekształcić je w konieczne i tak dalej. Niektóre zapytania stały się bardzo złożone i trudne do debugowania. Wątpię, czy mógłbym je teraz przeczytać, ale mam nadzieję, że uda mi się ponownie znaleźć podobne rozwiązanie, korzystając z referencyjnych elementów konstrukcyjnych.
Innymi sposobami na zwiększenie intuicyjnej świadomości przestrzeni deklaratywnych i funkcjonalnych są nauka teorii mnogości i języki programowania bardziej dostosowane do określonego paradygmatu. Obecnie uczę się Haskella, na przykład, aby utrzymać i poprawić swoje zdolności matematyczne.
źródło
Kiedy napotykasz problem, zwykle myślisz, jak go rozwiązać. Ale jeśli wiesz, jak komputer rozwiązuje to za Ciebie! W takim razie martwisz się, jak zostaniesz wyeliminowany.
Próbuję powiedzieć, jak to się dzieje.
Być może znasz już programy rekurencyjne, w programach rekurencyjnych definiujesz problem, a raczej określasz sposób jego rozwiązania. Ci określić bazę, a następnie określ n na podstawie n-1 . (na przykład
factorial(n) = n * factorial(n-1)
) Ale możesz już wiedzieć, jak komputer to rozwiązuje. zaczyna się od funkcji i wywołuje funkcję rekurencyjnie, aż osiągnie podstawową definicję, a następnie ocenia wszystkie pozostałe funkcje na podstawie wartości podstawowej.Tak dzieje się w programowaniu deklaratywnym. definiujesz wszystko na podstawie istniejących definicji. A komputer wie, jak uzyskać odpowiedź na podstawie podstawowych funkcji.
W SQL nie możesz powiązać definicji między sobą, ale odnosisz obiekty lub informacje, określasz to, czego chcesz, i wyszukujesz komputer na podstawie czegoś (obiektu, informacji) na podstawie podanych przez ciebie relacji.
źródło