Jakie problemy mogą być rozwiązane, albo łatwiej rozwiązać, wykorzystując wykresy i drzewa?




Jakie są najczęstsze problemy, które można rozwiązać za pomocą obu tych struktur danych?


Byłoby dobrze dla mnie mieć również zalecenia dotyczące książek, które:


* Wdrożenie struktur
* Wdrożenie i wyjaśnić powody algorytmów, które ich używają
Pierwszą rzeczą, myślę o tym, kiedy czytam to pytanie brzmi: *jakiego rodzaju rzeczy wykorzystywać wykresy / drzew?* i wtedy myślę wstecz, jak mogę z nich korzystać.


Na przykład, weźmy dwa wspólne zastosowań drzewa:


* DOM
* systemy plików


DOM, XML dla tej sprawy, przypominają struktury drzewa.   

![tekst alternatywny](https://i.stack.imgur.com/bk5RY.gif)


To ma sens, też. **Ma to sens, ponieważ, jak wymaga tego dane do uzgodnienia** . System plików, too. W systemie UNIX istnieje węzeł główny, a rozgałęzienia w dół poniżej. Podczas montażu nowego urządzenia, jesteś dołączenie go do drzewa.


Należy również być zadając sobie pytanie: czy dane należą do tego typu konstrukcji? Tworzenie struktur danych, które mają sens problemu, a reszta przyjdzie sama.


O ile łatwiej jest, myślę, że to jest to względne. Czy jesteś dobry z funkcji rekurencyjnych przemierzać drzewo / wykres? Co zrobić, jeśli trzeba zrównoważyć drzewo?


Pomyśl o program, który rozwiązuje zagadkę wyszukiwarki słowo. Można nakreślić wszystkie litery szukanej słowo na wykresie i sprawdzić okolicznych węzłów aby sprawdzić, czy ciąg jest dopasowanie którekolwiek ze słów. Ale nie można po prostu zrobić to samo z jednym z tablicy? Wszystko, co naprawdę trzeba zrobić, to przenieść wskaźnik do sprawdzenia listy po lewej i prawej stronie, a przez szerokość, by sprawdzić powyżej i poniżej liter. Rozwiązanie tego problemu z wykresu nie jest trudne, ale może stworzyć wiele dodatkowej pracy i trudności, jeśli nie jesteś dobrze z ich użyciem - oczywiście, że nie powinna zniechęcać od robią to, zwłaszcza jeśli są nauki o im.


Mam nadzieję, że pomaga myśleć o tych struktur. Jeśli chodzi o zalecenie książki, będę musiał iść z **[Wprowadzenie do algorytmów](http://rads.stackoverflow.com/amzn/click/0262032937)** .
<p>byłbym bardzo podejrzliwy wobec jakiegokolwiek zestawu uniwersalnych najlepszych praktyk, ponieważ w większości tych dziedzin diabeł tkwi w szczegółach. to, że informacje są stosunkowo powszechne, nie oznacza, że ​​aplikacja korzysta z danych dokładnie w taki sam sposób, jak inne aplikacje. oznacza to, że twój model danych może być nieco inny.</p><ul> <li>imię i nazwisko: dlaczego przechwytujesz imię? jeśli masz obowiązek przechwycenia pełnego imienia i nazwiska osoby (tj. przygotowujesz dokumenty prawne lub akty urodzenia), prawdopodobnie chcesz dać ludziom więcej miejsca na pisanie niż gdybyś tylko prosił o imię i nazwisko osoby, więc wezwać ich w nowej aplikacji internetowej.</li> <li>adres: co zamierzasz zrobić z adresem? jakie adresy przechowujesz? jeśli przechowujesz adres nieruchomości w stanach zjednoczonych, na której tworzysz hipotekę, prawdopodobnie bardzo zależy ci na uzyskaniu w pełni znormalizowanego adresu, w którym to przypadku model danych prawdopodobnie będzie chciał bardzo blisko pod dowolnym adresem narzędzie normalizacyjne zwraca. jeśli chcesz tylko, aby ludzie mogli wpisać adres w celu dostarczenia produktu, prawdopodobnie wystarczy kilka wierszy tekstu swobodnego. długość linii może zależeć od wymagań dalszych procesów, które wykonują takie czynności jak drukowanie etykiet adresowych.</li> <li>stan: zakładając, że możesz zidentyfikować prawidłowe wartości stanu, prawdopodobnie sensowne jest utworzenie tabeli <code>state</code> i utworzenie relacji klucza obcego między tabelami <code>state</code> i <code>address</code>. ale możliwość zidentyfikowania prawidłowych wartości oznacza, że ​​ograniczasz zestaw prawidłowych adresów przynajmniej do określonego zestawu krajów. to jest w porządku dla wielu stron, ale musisz trochę popracować, aby wesprzeć nowy kraj.</li> <li>miasto: jeśli masz do czynienia z danymi, w których istnieją potencjalnie regulacje na poziomie miasta (tj. w których istnieją różne rodzaje stawek podatkowych, które są stosowane w zależności od miasta), możesz chcieć traktować je podobnie jak państwo i mieć <code>city</code> tabela z prawidłowymi miastami i relacja klucza obcego między tabelami <code>city</code> i <code>address</code>. z drugiej strony, jeśli próbujesz tylko dostarczyć produkt i nie przejmujesz się tym, że masz w tabeli różne wersje tego samego miasta, wystarczy, że użytkownik wprowadzi dowolny tekst. oczywiście, jeśli przechowujesz klucze obce, będziesz mieć sporo pracy, aby upewnić się, że masz wszystkie prawidłowe wartości. ale są produkty, w których chodzi o to, że firma już wykonała tę pracę (tj. bazy danych podatków od sprzedaży).</li> <li>telefon: co robisz z numerami telefonów i dlaczego? niektóre aplikacje będą chciały pobierać numery telefonów w dowolnym formacie, w którym użytkownik zdecyduje się je wprowadzić i zachować to formatowanie dla wszystkich kolejnych zapytań. byłoby to powszechne, jeśli projektujesz osobistą książkę adresową, w której użytkownicy mają własne preferencje dotyczące sposobu przechowywania i wyświetlania numerów telefonów. inne aplikacje chciałyby zignorować wprowadzone formatowanie, wyodrębnić tylko znaki numeryczne, a następnie sformatować dane przy pobieraniu, aby wszystkie numery telefonów miały podobne formatowanie. jeśli prowadzisz działalność dla firm, możesz chcieć wprowadzić oddzielne pole dla użytkowników, aby wprowadzić rozszerzenie. jeśli próbujesz wesprzeć proces połączeń wychodzących, możesz chcieć przechowywać numer kierunkowy i kod kraju w osobnych kolumnach, ponieważ chcesz mieć pewność, że masz okna specyficzne dla strefy czasowej do nawiązywania połączeń z osobami o różnych numerach kierunkowych (tworzenie połączenie z kimś ze wschodniej strefy czasowej o 10 rano będzie znacznie lepsze niż wykonanie tego samego połączenia z kimś w strefie czasowej pacyfiku, gdzie jest 7 rano).</li> <li>płeć: w przypadku wielu aplikacji jest całkowicie rozsądne przechowywanie kodu płci („m” lub „f”) w tabeli. z drugiej strony zdarzają się sytuacje, w których możesz chcieć dodatkowych opcji (inne, interseksualne, transseksualne) lub gdy musisz przechowywać coś takiego jak płeć przy urodzeniu i aktualna płeć.</li> </ul> <p>oprócz innych odpowiedzi ...</p><p> <a href="https://dba.stackexchange.com/questions/1677/is-there-any-good-tool-for-making-database-design-and-prototypes/1678#1678">najpierw przechwytywanie modelu koncepcyjnego</a> powinno określać zakres i wymagania. na tej podstawie możesz uzyskać logiczne i fizyczne modele danych.</p><p>gdy jest to w większości statyczne, masz stabilną bazę danych, na której można zbudować aplikację. jest to sprzeczne z pierwszą opcją.</p><p>twój drugi punkt zakończy się brudną, niemożliwą do utrzymania <em> kulą błota </em>. model danych nigdy nie zostanie naprawiony: jeśli nie zaprojektowałeś go z góry, nie będziesz miał czasu, aby go naprawić przed wysyłką. będziesz zbyt zajęty hakowaniem rzeczy razem.</p><p>nastąpią niewielkie zmiany w schemacie, łączenie lub dzielenie tabel, zmiana relacji itp., ale na zlokalizowanych „wyspach”, a model + podstawowy projekt pozostaną niezmienione.</p> Niestety, algorytm powtórek w Duoligo pozostawia wiele do życzenia, dlatego przy powtórzeniach wspieram się arkuszem kalkulacyjnym, gdzie wklejam sprawiające mi trudność lekcje i zdania. Przy kolejnych powtórzeniach błędne zdania zaznaczam czerwonym kolorem, a przerobione lekcje dodatkowo koloruję w kolejnych powtórkach. U mnie zdaje to egzamin i łatwiej mi wychwycić zagadnienia, którym muszę poświęcić więcej czasu. Na początku korzystałem z "kartki i ołówka", ale było to bardzo niepraktyczne. Później przeszedłem na arkusz kalkulacyjny i z czasem wypracowałem zestaw narzędzi, które bardzo pomagają w nauce i kontroli postępów. Przy cięciu wzdłużnym, tniesz wzdłuż ziarna; przy cięciu poprzecznym, tniesz w poprzek ziarna. 


Cięcie wzdłuż ziarna jest bardzo łatwe; jeszcze zanim miałeś mechaniczną piłę, miałeś piły z kilkoma, ale dużymi zębami, więc tniesz tak szybko i prosto, jak to możliwe. Zasadniczo, można "rozerwać" drewno na strzępy, tak jak można je rozłupać siekierą, z wyjątkiem prostszego cięcia, ponieważ nadal można ciąć niektóre włókna drewna. Cięcie to ma tendencję do wiązania ostrza w miarę jak włókna drzewne się rozluźniają. 


Cięcie w poprzek włókien jest znacznie trudniejsze dla piły (musisz ciąć dużo włókien), i zazwyczaj używasz piły o mniejszych zębach, ale o wiele więcej. 


Kolejny powód, dla którego masz więcej lub mniej zębów ma związek z ilością pyłu z piły, który musisz odprowadzić po każdym cięciu. Ponieważ rozdarcie jest łatwiejsze, potrzebujesz więcej miejsca między zębami, aby je wykonać. 


[![http://www.rockler.com/how-to/blades-101/](https://i.stack.imgur.com/u6g7R.png)](https://i.stack.imgur.com/u6g7R.png)Image pochodzi z <http://www.rockler.com/how-to/blades-101/> np na matematyce nam nauczycielka udostępnia swój pulpit wchodzi w painta xd i tam rozwiązujemy zadnania. wydaje mi się, że lekcje w tym programie prowadzoną tak samo jak w każdym innym. a no i są zakładki zadań i tam czasem nauczyciele umieszcząją zad do wykonania i jest kalendarz i tam są umieszczone lekcje jakie będziesz miała np dzisiejszego dnia w sumie, to pewnie teraz w każdym takim lepszym programie graficznym -da radę tak zrobić, ja jednak polecam photoshopa, z początku może wydawać się trudny do okiełznania, ale to mylne wrażenie :)  
tego typu rzeczy, były u mnie podstawowymi, kiedy zaczynałam się bawić w photoshopie, a z biegiem czasu rzucałam się coraz to na głębszą wodę, więc jeśli cię nie przerazi to polecam, w internecie znajdziesz również wiele tutoriali (poradników) dla "zielonych" :) oczywiście excel, ale word też może być.  
  
zaś ogólnie informatyki nie cierpię przez te głupie ustawy co na pamięć musieliśmy kłuć, masakra. znać się na sieciach, (oczywiście podstawy to format komputera, reinstall windy, sterów itd), do tego chociaż jeden język programowania, resztę wyczytasz u innych. <p>oto wyniki zapytania tabeli w <strong>druga kolumna indeksu wielokolumnowego</strong>.<br> efekty są łatwe do odtworzenia dla każdego. po prostu spróbuj w domu.</p><p>testowałem z postgresql <strong>9.0.5</strong> na debianie, używając średniej wielkości tabeli bazy danych z 23322 wierszami. implementuje relację n: m między tabelami <code>adr</code> (adres) i <code>att</code> (atrybut), ale tutaj nie ma to znaczenia. uproszczony schemat:</p><pre><code>create table adratt ( adratt\_id serial primary key , adr\_id integer not null , att\_id integer not null , log\_up timestamp(0) not null default (now())::timestamp(0) , constraint adratt\_uni unique (adr\_id, att\_id) ); </code></pre><p>ograniczenie <code>unique</code> skutecznie implementuje unikalny indeks. dla pewności powtórzyłem test z prostym indeksem i uzyskałem identyczne wyniki, jak oczekiwano.</p><pre><code>create index adratt\_idx on adratt(adr\_id, att\_id) </code></pre><p>tabela jest skupiona w <code>adratt\_uni</code> indeks i przed testem uruchomiłem:</p><pre><code>cluster adratt; analyze adratt; </code></pre><p>skanowanie sekwencyjne w poszukiwaniu zapytań na <code>(adr\_id, att\_id)</code> są tak szybkie, jak to tylko możliwe. indeks wielokolumnowy będzie nadal używany jako warunek zapytania w samej drugiej kolumnie indeksu.</p><p>uruchomiłem zapytania kilka razy, aby zapełnić pamięć podręczną i wybrałem najlepszy z dziesięciu przebiegów, aby uzyskać porównywalne wyniki.</p><h2>1. zapytanie za pomocą obu kolumn</h2><pre><code>select * from adratt where att\_id = 90 and adr\_id = 10; adratt\_id | adr\_id | att\_id | log\_up +++ 123 | 10 | 90 | 2008-07-29 09:35:54 (1 row) </code></pre><p>wyjście <code>explain analyze</code>:</p><blockquote> <pre><code>index scan using adratt\_uni on adratt (cost=0.00..3.48 rows=1 width=20) (actual time=0.022..0.025 rows=1 loops=1) index cond: ((adr\_id = 10) and (att\_id = 90)) total runtime: 0.067 ms </code></pre></blockquote><h2>2. zapytanie za pomocą pierwszej kolumny</h2><pre><code>select * from adratt where adr\_id = 10 adratt\_id | adr\_id | att\_id | log\_up +++ 126 | 10 | 10 | 2008-07-29 09:35:54 125 | 10 | 13 | 2008-07-29 09:35:54 4711 | 10 | 21 | 2008-07-29 09:35:54 29322 | 10 | 22 | 2011-06-06 15:50:38 29321 | 10 | 30 | 2011-06-06 15:47:17 124 | 10 | 62 | 2008-07-29 09:35:54 21913 | 10 | 78 | 2008-07-29 09:35:54 123 | 10 | 90 | 2008-07-29 09:35:54 28352 | 10 | 106 | 2010-11-22 12:37:50 (9 rows) </code></pre><p>wyjście <code>explain analyze</code>:</p><blockquote> <pre><code>index scan using adratt\_uni on adratt (cost=0.00..8.23 rows=9 width=20) (actual time=0.007..0.023 rows=9 loops=1) index cond: (adr\_id = 10) total runtime: 0.058 ms </code></pre></blockquote><h2>3. zapytanie za pomocą drugiej kolumny</h2><pre><code>select * from adratt where att\_id = 90 adratt\_id | adr\_id | att\_id | log\_up +++ 123 | 10 | 90 | 2008-07-29 09:35:54 180 | 39 | 90 | 2008-08-29 15:46:07 ... (83 rows) </code></pre><p>wyjście <code>explain analyze</code>:</p><blockquote> <pre><code>index scan using adratt\_uni on adratt (cost=0.00..818.51 rows=83 width=20) (actual time=0.014..0.694 rows=83 loops=1) index cond: (att\_id = 90) total runtime: 0.849 ms </code></pre></blockquote><h2>4. wyłącz indeksowanie i skanowanie bitmaps</h2><pre><code>set enable\_indexscan = off; select * from adratt where att\_id = 90 </code></pre><p>wynik analizy explain analyze:</p><blockquote> <pre><code>bitmap heap scan on adratt (cost=779.94..854.74 rows=83 width=20) (actual time=0.558..0.743 rows=83 loops=1) recheck cond: (att\_id = 90) -&gt; bitmap index scan on adratt\_uni (cost=0.00..779.86 rows=83 width=0) (actual time=0.544..0.544 rows=83 loops=1) index cond: (att\_id = 90) total runtime: 0.894 ms </code></pre></blockquote><pre><code>set enable\_bitmapscan = off select * from adratt where att\_id = 90 </code></pre><p>wyjście <code>explain analyze</code>:</p><blockquote> <pre><code>seq scan on adratt (cost=0.00..1323.10 rows=83 width=20) (actual time=0.009..2.429 rows=83 loops=1) filter: (att\_id = 90) total runtime: 2.680 ms </code></pre></blockquote><h2>wniosek</h2><p>zgodnie z oczekiwaniami indeks wielokolumnowy służy do zapytania tylko w drugiej kolumnie.<br> zgodnie z oczekiwaniami jest mniej skuteczny, ale zapytanie jest nadal <strong>x szybsze</strong> niż bez indeksu.<br> po wyłączeniu skanowania indeksów planista zapytań wybiera skanowanie sterty map bitowych, które wykonuje prawie tak samo szybko. dopiero po wyłączeniu tego wraca do skanowania sekwencyjnego.</p> Jest to dość szerokie, ale dam ci tak ogólną odpowiedź, jak tylko mogę.

**CTE ...**

* Są niezindeksowalne (ale mogą używać istniejących indeksów na obiektach, do których istnieją odwołania)
* Nie można mieć ograniczeń
* Są zasadniczo jednorazowe `VIEW` s
* Trwać tylko do momentu uruchomienia następnego zapytania
* Może być rekurencyjny
* Nie masz dedykowanych statystyk (polegaj na statystykach dotyczących podstawowych obiektów)

**#Temp Tables ...**

* Są prawdziwe zmaterializowane tabele, które istnieją w tempdb
* Może być indeksowany
* Może mieć ograniczenia
* Trwaj w życiu obecnego POŁĄCZENIA
* Może odwoływać się do innych zapytań lub podprocedur
* Masz dedykowane statystyki generowane przez silnik

Jeśli chodzi o użycie każdego z nich, mają bardzo różne przypadki użycia.Jeśli masz bardzo duży zestaw wyników lub musisz odwołać się do niego więcej niż raz, umieść go w tabeli `#temp` .Jeśli ma być rekurencyjny, jednorazowy lub po prostu dla uproszczenia logicznego, preferowany jest `CTE` .

Ponadto należy `CTE`**nigdy nie używaj do wykonania**.Prawie nigdy nie przyspieszysz przy użyciu CTE, ponieważ znowu jest to widok jednorazowy.Możesz zrobić z nimi kilka fajnych rzeczy, ale przyspieszenie zapytania nie jest jednym z nich.