Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
pl:miw:2009:piw09_des [2009/09/08 02:12]
piw09
pl:miw:2009:piw09_des [2019/06/27 15:50] (aktualna)
Linia 1: Linia 1:
 ===== 1. Wstęp ===== ===== 1. Wstęp =====
  
-Celem tego dokumentu jest omówienie implementacji dedukcyjnego systemu bazodanowego DES, bazującego na języku Datalog. Największa część uwagi zostanie skupiona na praktycznych cechach narzędzia, jakkolwiek zawarte zostaną także uwagi o charakterze bardziej teoretycznym.+Celem tego dokumentu jest omówienie implementacji dedukcyjnego systemu bazodanowego DES, opierającego ​się na języku Datalog. Największa część uwagi zostanie skupiona na praktycznych cechach narzędzia, jakkolwiek zawarte zostaną także uwagi o charakterze bardziej teoretycznym.
  
 ===== 2. Informacje wstępne ===== ===== 2. Informacje wstępne =====
Linia 31: Linia 31:
 Tego typu komendy pozwalają na permanentne (do czasu kolejnego wpisania kolejnej tego typu komendy) przełączenie się na dany język. Tego typu komendy pozwalają na permanentne (do czasu kolejnego wpisania kolejnej tego typu komendy) przełączenie się na dany język.
  
-Jeśli natomiast chcemy wpisać tylko jedne polecenie w danym języku, odmiennym od aktualnie używanego, należy wykonać ​nastepujące komendy:+Jeśli natomiast chcemy wpisać tylko jedne polecenie w danym języku, odmiennym od aktualnie używanego, należy wykonać ​następujące komendy:
  
 ''/​datalog polecenie\\ ''/​datalog polecenie\\
Linia 40: Linia 40:
  
 Taki sposób operowania na trzech językach jednocześnie jest bardzo wygodny i pozwala na wykonywanie różnych czynności w sposób wyjątkowo szybki i wydajny, pozwalając na maksymalną elastyczność w osiągnięciu zamierzonego celu bądź rozwiązaniu jakiegoś problemu, jako że języki SQL oraz Datalog / Prolog cechują się większą elastycznością w trochę innych obszarach, uzupełniając się wzajemnie. Taki sposób operowania na trzech językach jednocześnie jest bardzo wygodny i pozwala na wykonywanie różnych czynności w sposób wyjątkowo szybki i wydajny, pozwalając na maksymalną elastyczność w osiągnięciu zamierzonego celu bądź rozwiązaniu jakiegoś problemu, jako że języki SQL oraz Datalog / Prolog cechują się większą elastycznością w trochę innych obszarach, uzupełniając się wzajemnie.
 +
 +Co więcej, dzięki łatwości w przełączaniu się można bardzo szybko poznać wszystkie trzy języki używane w DES.
  
 === 2.3. Pomoc === === 2.3. Pomoc ===
Linia 81: Linia 83:
 == 3.1.1. Wnioski == == 3.1.1. Wnioski ==
  
-Jak widać, język Datalog oferuje maksymalny wachlarz możliwości programowania logicznego, od najprostszych i najpopularniejszych elementów do znacznie bardziej wyrafinowanych i rzadziej stosowanych.+Jak widać, język Datalog oferuje maksymalny wachlarz możliwości programowania logicznego, od najprostszych i najpopularniejszych elementów do znacznie bardziej wyrafinowanych i rzadziej stosowanych. Nie ustępuje tutaj znacznie takim implementacjom jak chociażby SWI.
  
 === 3.2. SQL === === 3.2. SQL ===
Linia 125: Linia 127:
 Różnica wynika z faktu, iż w językach Datalog i Prolog operator ten należy odróżnić od operatora implikacji (<=), a skoro w SQL nie istnieje taki operator, to bardziej naturalne wydaje się zapisanie operatora "​mniejszy lub równy"​ dla tego języka w sposób zgodny z nazwą (<=). Różnica wynika z faktu, iż w językach Datalog i Prolog operator ten należy odróżnić od operatora implikacji (<=), a skoro w SQL nie istnieje taki operator, to bardziej naturalne wydaje się zapisanie operatora "​mniejszy lub równy"​ dla tego języka w sposób zgodny z nazwą (<=).
  
-== 3.4.1. Operatory ​relacji ​==+== 3.4.1. Operatory ​porównania ​==
  
 Operatory dostarczane przez system DES są standardowym zestawem spotykanym w każdym z języków programowania. Należą do nich: Operatory dostarczane przez system DES są standardowym zestawem spotykanym w każdym z języków programowania. Należą do nich:
Linia 136: Linia 138:
   * ''​X <= Y''​ - testuje czy X jest mniejszy lub równy Y   * ''​X <= Y''​ - testuje czy X jest mniejszy lub równy Y
  
-== 3.4.1. Funkcje ==+== 3.4.2. Funkcje ==
  
 Należą do nich: Należą do nich:
Linia 165: Linia 167:
     * ''​floor(X)''​ - zwraca największą wartość całkowitą mniejszą lub równą X     * ''​floor(X)''​ - zwraca największą wartość całkowitą mniejszą lub równą X
     * ''​ceiling(X)''​ - zwraca najmniejszą wartość całkowitą większą lub równą X     * ''​ceiling(X)''​ - zwraca najmniejszą wartość całkowitą większą lub równą X
 +
 +== 3.4.3. Operatory arytmetyczne ==
 +
 +Również tutaj, podobnie jak w przypadku operatorów porównania,​ mamy do czynienia ze standardowym zestawem. Jakkolwiek, niektóre z operatorów są oznaczone dość niestandardowymi symbolami, dlatego dla porządku wypunktujmy je wszystkie:
 +
 +  * ''​\X''​ - negacja bitowa
 +  * ''​-X''​ - wartość przeciwna do X
 +  * ''​X ^ Y''​ - operator potęgowania
 +  * ''​X * Y''​ - mnożenie
 +  * ''​X / Y''​ - dzielenie
 +  * ''​X + Y''​ - dodawanie
 +  * ''​X - Y''​ - odejmowanie
 +  * ''​X // Y''​ - dzielenie całkowite X przez Y
 +  * ''​X rem Y''​ - reszta z dzielenie X przez Y
 +  * ''​X \/ Y''​ - operacja OR w sensie bitowym
 +  * ''​X /\ Y''​ - operacja AND w sensie bitowym
 +  * ''​X # Y''​ - operacja XOR w sensie bitowym
 +  * ''​X << Y''​ - przesunięcie bitowe w lewo X o Y bitów
 +  * ''​X >> Y''​ - przesunięcie bitowe w prawo X o Y bitów
 +
 +== 3.4.4. Stałe arytmetyczne ==
 +
 +  * **pi**
 +  * **e**
 +
 +== 3.4.5. Wykonywanie operacji arytmetycznych ==
 +
 +Po wypunktowaniu poszczególnych elementów arytmetycznych (funkcji, operatorów i stałych) nadszedł czas na praktyczne omówienie ich stosowania. W języku Datalog używamy zapożyczonego z Prologu wyrażenia **is**, postaci:
 +
 +<​code>​X is expression</​code>​
 +
 +Istotne są trzy ograniczenia - zasady:
 +
 +  * X musi być zmienną lub wartością liczbową
 +  * expression musi być wyrażeniem arytmetycznym zbudowanym z liczb, zmiennych, stałych arytmetycznych,​ funkcji bądź operatorów arytmetycznych
 +  * zmienne używane w expression muszą być zunifikowane z jakimś wartościami na etapie wyliczania wartości expression.
 +
 +Poniżej podajmy prawidłowe i błędne przykłady stosowania omawianego wyrażenia:
 +
 +Najpierw dla języka Datalog. Jak widać poniżej, poza oczywistymi wnioskami dotyczącymi używania obliczeń arytmetycznych,​ w Datalogu wyniki zapytań przetwarzane są jako **krotki**. Jest to jedna z tych subtelnych różnic pomiędzy Datalogiem i Prologiem.
 +
 +{{:​pl:​miw:​2009:​3_4_5_1.png|}}
 +
 +Następnie prezentujemy analogiczne zapytania dla interpretera Prologu
 +
 +{{:​pl:​miw:​2009:​3_4_5_2.png|}}
 +
 +=== 3.5. Różnice między Datalogiem i Prologiem ===
 +
 +Jest tylko jedna różnica - dotyczy sposobu traktowania wyników zapytań w każdym z tych języków.
 +
 +W Datalogu informacja wyjściowa jest traktowana, podobnie jak w SQL, jako zbiór krotek.
 +W Prologu podejście jest zupełnie inne, podobnego do tego, które znamy z innych implementacji tego języka (np. SWI-Prolog).
 +
 +=== 3.6. Wnioski ===
 +
 +Elementy wspólne w naturalny sposób unifikują używanie trzech języków w systemie DES, pozwalając na szybkie i intuicyjne korzystanie z systemu.
 +
 ===== 4. Porównanie na przykładach ===== ===== 4. Porównanie na przykładach =====
  
-Po teoretycznych rozważaniach prezentuję kilka praktycznych przykładów programów dla każdego z 3 opisanych językow.+Po teoretycznych rozważaniach prezentuję kilka praktycznych przykładów programów dla każdego z 3 opisanych języków.
  
 === 4.1. Rodzina === === 4.1. Rodzina ===
  
-Rozpoczynamy od klasycznego dla programowania deklaratywnego,​ przykładu rodziny.+Rozpoczynamy od klasycznego dla programowania deklaratywnego,​ przykładu rodziny. W tym przykładzie,​ wykonamy analogiczne zadanie najpierw w języku Datalog, a następnie w SQL.
  
 == Przykład w języku Datalog / Prolog == == Przykład w języku Datalog / Prolog ==
  
-''​father(tom,​amy). ​\\ +<​code>​father(tom,​amy). 
-father(jack,​fred). ​\\ +father(jack,​fred). 
-father(tony,​carolII). ​\\ +father(tony,​carolII). 
-father(fred,​carolIII). ​\\ +father(fred,​carolIII). 
-mother(graceI,​amy). ​\\ +mother(graceI,​amy). 
-mother(amy,​fred). ​\\ +mother(amy,​fred). 
-mother(carolI,​carolII). ​\\ +mother(carolI,​carolII). 
-mother(carolII,​carolIII). ​\\ \\+mother(carolII,​carolIII).
  
-parent(X,Y) :- \\ +parent(X,Y) :- 
-  father(X,​Y) ​\\ +  father(X,​Y) 
-  ; \\ +  ; 
-  mother(X,​Y). ​\\ \\+  mother(X,​Y).
  
-The above clause for parent is equivalent to \\ +Powyzsze jest rownowazne z zapisem
-% parent(X,Y) :- \\ +% parent(X,Y) :- 
-%   ​father(X,​Y). ​\\ +%   ​father(X,​Y). 
-% parent(X,Y) :- \\ +% parent(X,Y) :- 
-%   ​mother(X,​Y). ​\\ \\+%   ​mother(X,​Y).
  
-ancestor(X,​Y) :- \\ +ancestor(X,​Y) :- 
-  parent(X,​Y). ​\\ +  parent(X,​Y). 
-ancestor(X,​Y) :- \\ +ancestor(X,​Y) :- 
-  parent(X,​Z), ​\\ +  parent(X,​Z),​ 
-  ancestor(Z,​Y). ​''​+  ancestor(Z,​Y). ​</​code>​
  
  
Linia 205: Linia 265:
  
 DES pozwala na zapis alternatywy w jednej regule – jest to równoważne z klasycznym zapisem za pomocą dwóch reguł. DES pozwala na zapis alternatywy w jednej regule – jest to równoważne z klasycznym zapisem za pomocą dwóch reguł.
 +
 +Wykorzystajmy jakoś nasz powyższy kod. Zapiszmy go w pliku family.dl:
 +
 +Najpierw wczytajmy plik z kodem:
 +
 +<​code>​ /c family</​code>​
 +
 +Następnie znajdźmy wszystkie osoby, których przodkiem jest tom:
 +
 +<​code>​ancestor(tom,​X)</​code>​
 +
 +{{:​pl:​miw:​2009:​4_1_1.png|}}
 +
 +Widzimy po raz kolejny, że Datalog operuje na **krotkach**.
 +
 +== Przykład w języku Prolog ==
 +
 +Jako że składnia Prologu jest taka sama jak Datalogu, podajmy od razu rozwiązanie problemu:
 +
 +{{:​pl:​miw:​2009:​4_1_2.png|}}
 +
 +Widać wyraźnie, że Prolog różni się od Datalogu sposobem operowania na rezultatach działania.
  
 == Przykład w języku SQL: == == Przykład w języku SQL: ==
  
-''​/sql \\ +<​code>​/sql 
-create table father(father,​child); ​\\ +create table father(father,​child);​ 
-insert into father values('​tom','​amy'​); ​\\ +insert into father values('​tom','​amy'​);​ 
-insert into father values('​jack','​fred'​); ​\\ +insert into father values('​jack','​fred'​);​ 
-insert into father values('​tony','​carolII'​); ​\\ +insert into father values('​tony','​carolII'​);​ 
-insert into father values('​fred','​carolIII'​); ​\\ +insert into father values('​fred','​carolIII'​);​ 
-create table mother(mother,​child); ​\\ +create table mother(mother,​child);​ 
-insert into mother values('​graceI','​amy'​); ​\\ +insert into mother values('​graceI','​amy'​);​ 
-insert into mother values('​amy','​fred'​); ​\\ +insert into mother values('​amy','​fred'​);​ 
-insert into mother values('​carolI','​carolII'​); ​\\ +insert into mother values('​carolI','​carolII'​);​ 
-insert into mother values('​carolII','​carolIII'​); ​\\ +insert into mother values('​carolII','​carolIII'​);​ 
-create view parent(parent,​child) as select * from father union select * from mother; ​\\ +create view parent(parent,​child) as select * from father union select * from mother; 
-create or replace view ancestor(ancestor,​descendant) as select parent,​child from parent union select parent,​descendant from parent,​ancestor where parent.child=ancestor.ancestor; ​\\ +create or replace view ancestor(ancestor,​descendant) as select parent,​child from parent union select parent,​descendant from parent,​ancestor where parent.child=ancestor.ancestor;​ 
-select * from ancestor where ancestor='​tom'; ​\\ +select * from ancestor where ancestor='​tom';​ 
-select child,​father,​mother from father,​mother where father.child=mother.child;''​+select child,​father,​mother from father,​mother where father.child=mother.child;​</​code>​ 
 + 
 +Także i tutaj sprawdźmy działanie kodu w praktyce. Najpierw załadujmy plik z kodem sql: 
 + 
 +<​code>/​process family.sql</​code>​ 
 + 
 +A potem: 
 + 
 +{{:​pl:​miw:​2009:​4_1_3.png|}} 
 + 
 +=== 4.2. Gramatyki === 
 + 
 +Kolejny problem będzie bardzo odmienny od poprzedniego - spróbujemy zapisać w Datalogu, z użyciem systemu DES, prosty parser działający od lewej do prawej rekursywnie wedle formuły: 
 + 
 +''​A -> a \\ 
 +A -> Ab \\ 
 +A -> Aa''​ 
 + 
 +Pierwszym zagadnieniem do rozwiązania jest sposób zapisu łańcucha wejściowego tak, by móc odczytać z niego każdy token z osobna razem z jego pozycją początkową i końcową. Pod pojęciem **token** rozumiemy tutaj dowolny podłańcuch łańcucha wejściowego. 
 + 
 +Rozwiązaniem jest relacja 
 + 
 +''​t(F,​T,​L)''​ 
 + 
 +gdzie: 
 + 
 +F - pozycja początkowa tokenu, 
 +T - token 
 +L - pozycja końcowa tokenu 
 + 
 +Ustalmy, że łańcuch wejściowy ma postać "​ababa"​. Zakodujmy go z użyciem powyższego:​ 
 + 
 +<​code>​t(1,​a,​2). 
 +t(2,b,3). 
 +t(3,a,4). 
 +t(4,b,5). 
 +t(5,​a,​6).</​code>​ 
 + 
 +Następnie zapiszmy formułę parsera dla powyższego łańcucha:​ 
 + 
 +<​code>​a(F,​L) :- t(F,a,L). 
 +a(F,L) :- a(F,M), t(M,b,L). 
 +a(F,L) :- a(F,M), t(M,​a,​L).</​code>​ 
 + 
 +=== 4.3. Ciąg Fibonacciego === 
 + 
 +W następnym przykładzie przyjrzymy się sposobowi rozwiązania ciągu Fibonacciego. 
 + 
 +Najpierw zdefiniowanie początkowych wartości ciągu: 
 + 
 +<​code>​fib(0,​1). 
 +fib(1,​1).</​code>​ 
 + 
 +Następnie formuła wyznaczająca kolejne: 
 + 
 +<​code>​fib(N,​F) :- 
 +  N > 1, 
 +  N2 is N - 2, 
 +  fib(N2, F2), 
 +  N1 is N - 1, 
 +  fib(N1, F1), 
 +  F is F2 + F1.</​code>​ 
 + 
 +Na sam koniec przykład działania:​ 
 + 
 +{{:​pl:​miw:​2009:​4_3_1.png|}} 
 + 
 +=== 4.4. Wieże Hanoi oraz tablice rozszerzeń DES=== 
 + 
 +Rozwiążmy problem wież hanoi. Będzie to jednocześnie pokazanie działania **tablicy rozszerzeń** systemu DES, przechowującej poszczególne etapy rozwiązywania danego zagadnienia. 
 + 
 +Najpierw kod w Datalogu: 
 + 
 +<​code>​hanoi(1,​A,​B,​C). 
 +hanoi(N,​A,​B,​C) :- 
 +  N > 1, 
 +  N1 is N - 1, 
 +  hanoi(N1,​A,​C,​B),​ 
 +  hanoi(N1,​C,​B,​A).</​code>​ 
 + 
 +Przykład działania dla 10 dysków: 
 + 
 +{{:​pl:​miw:​2009:​4_4_1.png|}} 
 + 
 +Okazuje się, że wynik nie odzwierciedla ilości przełożeń. Aby zobaczyć faktyczną drogę do wyniku końcowego, należy wywołać DES'​ową **tablicę rozszerzeń**:​ 
 + 
 +część pierwsza, dotycząca odpowiedzi z systemu DES: 
 + 
 +{{:​pl:​miw:​2009:​4_4_2.png|}} 
 + 
 +część druga, dotycząca wywołań systemu DES: 
 + 
 +{{:​pl:​miw:​2009:​4_4_3.png|}} 
 + 
 +=== 4.5. Relacje === 
 + 
 +Zanalizujmy bardziej złożony przykład, pokazujący jak imitować polecenia SQL za pomocą Datalogu. Będzie to  
 + 
 +przyklad testujący możliwości DES pod kątem współdziałania różnego rodzaju języków, oraz tego, czy faktycznie  
 + 
 +można je stosować mniej więcej wymiennie. 
 + 
 +Przedstawmy polecenia SQL razem z analogami w Datalogu: 
 + 
 +== Tworzenie tabel i wstawianie wartości == 
 + 
 +<​code>​% Najpierw tworzymy tabele 
 +create or replace table a(a); 
 +create or replace table b(b); 
 +create or replace table c(a,b); 
 + 
 +% Listujemy powyższe zależności 
 +/dbschema 
 + 
 +% Dodajemy rekordy do tabeli 
 +insert into a values ('​a1'​);​ 
 +insert into a values ('​a2'​);​ 
 +insert into a values ('​a3'​);​ 
 +insert into b values ('​b1'​);​ 
 +insert into b values ('​b2'​);​ 
 +insert into b values ('​a1'​);​ 
 +insert into c values ('​a1','​b2'​);​ 
 +insert into c values ('​a1','​a1'​);​ 
 +insert into c values ('​a2','​b2'​);</​code>​ 
 + 
 +Odpowiednik w Datalogu, łączący tworzenie tabel oraz wstawianie rekordów:​ 
 + 
 +<​code>​a(a1). 
 +a(a2). 
 +a(a3). 
 + 
 +b(b1). 
 +b(b2). 
 +b(a1). 
 + 
 +c(a1,b2). 
 +c(a1,a1). 
 +c(a2,​b2).</​code>​ 
 + 
 +== Projekcja == 
 + 
 +Kod SQL: 
 + 
 +<​code>​ 
 +% Testujemy operację projekcji 
 +select a from c;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​projection(X) :- c(X,​Y).</​code>​ 
 + 
 +== Selekcja z kryterium == 
 + 
 +Kod SQL: 
 + 
 +<​code>​% Selekcja z pewnym kryterium 
 +select a from a where a='​a2';</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​selection(X) :- a(X), X=a2.</​code>​ 
 + 
 +== Iloczyn kartezjański == 
 + 
 +Kod SQL: 
 + 
 +<​code>​% Iloczyn kartezjański 
 +select * from a,​b;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​cartesian(X,​Y) :- a(X), b(Y).</​code>​ 
 + 
 +== Inner Join == 
 + 
 +Kod SQL: 
 + 
 +<​code>​% złączenie typu inner join 
 +select a from a inner join b on a.a=b.b;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​inner_join(X) :- a(X), b(X).</​code>​ 
 + 
 +== Left Join == 
 + 
 +Kod SQL: 
 + 
 +<​code>​% złączenie typu left join 
 +select * from a left join b on a.a=b.b;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​left_join(X,​Y) :- lj(a(X), b(Y), X=Y).</​code>​ 
 + 
 +== Right Join== 
 + 
 +Kod SQL: 
 + 
 +<​code>​% złączenie typu right join 
 +select * from a right join b on a.a=b.b;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​right_join(X,​Y) :- rj(a(X), b(Y), X=Y).</​code>​ 
 + 
 +== Full join == 
 + 
 +Kod SQL: 
 + 
 +<​code>​% złączenie typu full foin 
 +select * from a full join b on a.a=b.b;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​full_join(X,​Y) :- fj(a(X), b(Y), X=Y).</​code>​ 
 + 
 +== Union == 
 + 
 +Kod SQL: 
 + 
 +<​code>​% złączenie typu unia 
 +select * from a union select * from b;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​union(X) :- a(X) ; b(X).</​code>​ 
 + 
 +== Różnica == 
 + 
 +Kod SQL: 
 + 
 +<​code>​% Testujemy operację select z kryterium różnicy 
 +select * from a except select * from b;</​code>​ 
 + 
 +Kod Datalog: 
 + 
 +<​code>​difference(X) :- a(X), not(b(X)).</​code>​ 
 + 
 +== Relacje w Datalog i SQL == 
 + 
 +Ważnym aspektem systemu DES jest fakt, iż mimo że polecenia w SQL i Datalog można stosowac wymiennie i przeplatać  
 + 
 +je ze sobą, to jednak relacji utworzonych w Datalog nie można używać od razu jako tabeli w SQL. 
 + 
 +Przyjrzyjm się powyższemu kodowi. Załóżmy, że utworzyliśmy w Datalogu relacje: 
 + 
 +<​code>​a(a1). 
 +a(a2). 
 +a(a3)</​code>​ 
 + 
 +Nie możemy po prostu użyć jej w SQL za pomocą, np., polecenia:​ 
 + 
 +<​code>/​sql select * from a;</​code>​ 
 + 
 +**Musimy WPIERW utworzyć analogiczną tabelę w SQL:** 
 + 
 +<​code>/​sql 
 +create table a(a)</​code>​ 
 + 
 +I dopiero teraz spróbować powyższej operacji. Całość obrazuje poniższy przykład. 
 + 
 +Zakładamy, że wczytaliśmy już całość powyższego kodu do systemu DES. 
 + 
 +{{:​pl:​miw:​2009:​4_5_1.png|}} 
 + 
 +===== 5. Wnioski końcowe =====
  
 +System DES jest bardzo skutecznym systemem edukacyjnym,​ posiadającym liczne walory. Zaliczamy do nich:
  
 +  * Efektywny sposób poznania trzech języków: Datalogu, Prologu i SQL, poprzez możliwość rozwiązywania problemów niemal natychmiast w każdym z trzech języków
 +  * Prostota użytkowania
 +  * Szeroki wachlarz możliwości w przypadku języka Datalog / Prolog
  
 +Nawet limitowana implementacja SQL ma swoje zalety - DES ma służyć jako system edukacyjny, a nie typowy transakcyjny DBMS, czyli przede wszystkim powinien być mały i szybki, co byłoby niemożliwe w przypadku pełnej implementacji całego standardu SQL.
pl/miw/2009/piw09_des.1252368734.txt.gz · ostatnio zmienione: 2019/06/27 15:58 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0