A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Linguagens de Programação de Bases de Dados

Apresentações semelhantes


Apresentação em tema: "Linguagens de Programação de Bases de Dados"— Transcrição da apresentação:

1 Linguagens de Programação de Bases de Dados
João Correia Lopes FEUP/INESC Referências: 1. C. Delobel, C. Lécluse, P. Richard. Databases: From Relational to Object-Oriented Systems, International Thomson Publishing, London, UK, 1995 2. L. Cardelli, P.Wegner. On Understanding types, data abstraction and Polymorphism. ACM Computing Surveys, 17(4): , December, 1985 3. N. Paton, R. Cooper, H. Williams, P. Trinder. Database Programming Languages. Prentice Hall International, Series in Computer Science, 1996 v 1.1, Março, 1999

2 Índice modelos de dados sistemas de tipos
extensões ao modelo relacional linguagens de programação de bases de dados linguagens persistentes ortogonais Napier88

3 Integração de Modelos de Dados e Sistemas de Tipos
os novos SGBDs devem possuir maior capacidade de modelização que os baseados no modelo relacional, e estar melhor integrados com as linguagens de programação modelos de dados para suprir limitações do modelo relacional em termos de modelização (o fosso semântico) através de um maior número de abstracções: classificação, generalização, … são tradicionalmente usados nas bases de dados para descrever o modelo estático (dados) normalmente são pouco adaptados à descrição do modelo dinâmico (computações) sistemas de tipos as linguagens de programação com sistemas de tipos mais complexos mapeiam com mais facilidade a informação do mundo real através da introdução de tipos mais elaborados, polimorfismos, encapsulamento, .… tradicionalmente usados nas linguagens de programação para descrever computações (complexas) constituem o equivalente para as linguagens de programação ao esquema da base de dados integração dos dois conceitos = linguagens de programação de bases de dados

4 Modelos de Dados Estrutura Conceptual Estrutura Lógica
são usados na obtenção do modelo conceptual de sistemas de informação metodologias centradas no uso de um modelo semântico por forma a obter uma descrição independente do ambiente e isenta de detalhes de implementação tentam minorar a chamada “crise de software” [RAM 84] os projectos são entregues muito depois do prazo a qualidade é pobre a manutenção é cara Estrutura Conceptual Estrutura Lógica modelo semântico base de dados gerida pelo SGBD modelo relacional modelo hierárquico modelo reticulado Estrutura Física

5 Abstracções Comuns a Vários Modelos de Dados
classes e entidades uma classe é um conjunto de entidades com características comuns uma entidade possui uma identidade imutável e independente de modificações eventuais esta noção não existe no modelo relacional é essencial para certas aplicações (e.g. CAD) agregações agrupar várias entidades numa entidade de nível superior (endereço = cidade x rua x no-policia) associações não criam uma entidade ligam várias entidades podem conter restrições à cardinalidade atributos relações bidireccionais entre duas classes de entidades mono-valor (pessoa –> nome) ou multi-valor (pessoa –>> filhos) agrupamento constrói uma entidade a partir de um conjunto (finito) de entidades com uma dada estrutura a sua identidade é determinada pela identidade dos componentes (e.g. Pessoal: Monumento –> Pessoa) é diferente de uma classe porque esta não é uma entidade mas sim uma meta-primitiva é diferente de um atributo multi-valor porque com um agrupamento pode referir-se explicitamente todo o conjunto e com um atributo só se pode referir a associação Pessoal Monumento Pessoa

6 Modelização Baseada em Construtores
a modelização enfatizando o uso de agregações, associações e agrupamentos para representar ligações entre entidades o esquema pode ser visto como um conjunto de estruturas obtidas pela aplicação de construtores tuplo: agregação, associação conjunto: agrupamento nome Dirige nome N 1 Monumento Pessoa filho salário

7 Modelização Baseada em Atributos
a modelização enfatizando o uso de atributos para representar ligações entre entidades atributos ligam classes de entidades não há novas estruturas construídas como no caso anterior nome nome Dirigido filho Monumento Pessoa Dirige

8 Especialização e Generalização
na especialização uma classe é redefinida numa sub-classe e.g. Empregado especialização de pessoa a especialização pode ser explícita indicada explicitamente na altura da criação ou derivada indicada através de um predicado na generalização uma classe é definida como a união de várias classes e.g. Monumento, Museu e Palácio as várias classes podem ser mutuamente exclusivas não existem entidades pertencentes à generalização (e.g. Monumento) na base de dados o grafo de especialização/generalização constitui a hierarquia ISA ou hierarquia de herança nome nome Monumento idade Pessoa idade<33 Empregado Jovem Museu Palácio

9 Restrições de Integridade
para além das restrições de integridade estruturais (directamente nas primitivas do modelo) restrições de integridade adicionais são usadas para enriquecer o poder expressivo dos modelos semânticos restrições na chave (vide modelo relacional) são traduzidas por atributos mono-valor ou são desnecessárias no caso das entidades possuírem a sua própria identidade atributos parciais podem ser usados no caso de serem opcionais atributos totais, no caso de serem obrigatórios restrições de cardinalidade podem ser especificadas para as associações de entidades Notas finais sobre modelos de dados: exemplos de modelos semânticos E/A, SDM, IFO, RM/T, DAPLEX, INFOLOG os modelos de dados têm por objectivo representar os dados importantes para uma dada aplicação A aproximação à modelização usando técnicas orientadas aos objectos (O-O) permite a implementação de numerosas características dos modelos semânticos e proporciona ainda a modelização do comportamento dos objectos

10 Sistemas de Tipos o objectivo de uso dos tipos nas linguagens de programação é o de distinguir valores usados na execução de programas o conceito de tipo é similar ao conceito de classe mas é usado noutro contexto e com objectivos distintos o objectivo de um sistema de tipos é o de prevenir a ocorrência de erros durante a execução dos programas illegal instruction fault illegal memory reference divisão por zero desreferenciar NIL o que é um tipo? a gama de valores que uma variável de um programa pode tomar durante a execução do programa exemplo: x é booleana not(x) tem significado o sistema de tipos é o componente de uma linguagem tipada que tem em atenção os tipos das variáveis ou os tipos das expressões num programa

11 Tipagem linguagem tipadas linguagens não tipadas
podem ser atribuídos tipos ás variáveis linguagens não tipadas não colocam qualquer restrição à gama de valores que as variáveis podem tomar não têm tipos, ou podemos dizer que possuem um tipo universal que contém todos os valores possíveis exemplos: cadeias de bits na memória do computador o significado de uma zona de memória é determinado por uma interpretação do seu conteúdo expressões do calculus lambda tudo são funções; não podem ocorrer erros já que a única operação é a aplicação de funções expressões S do LISP puro o programa e os dados são expressões S conjuntos na teoria dos conjuntos temos elementos ou conjuntos de elementos apontadores em Smalltalk

12 Linguagens Fortemente Tipadas
erros de execução podem ser: interceptáveis (TRAPed) obrigam o computador a parar e.g. “divide by zero”, “illegal address”, “overflow” não-interceptáveis (UNTRAPed) e.g. aceder a um endereço ilegal ir além dos limites de um array saltar para um endereço errado e interpretar o conteúdo como sendo uma instrução um programa é seguro se não causa erros não-interceptáveis uma linguagem é segura se todos os fragmentos dos seus programas são seguros linguagens tipadas garantem a segurança dos programas rejeitando todos os programas que sejam potencialmente inseguros através de análise estática ou através de verificações em tempo de execução (runtime) note-se que linguagens não tipadas podem garantir a segurança através de verificações em tempo de execução erros proibidos nas linguagens seguras incluem normalmente mais do que os erros chamados não-interceptáveis uma linguagem é fortemente tipada se: não ocorrem erros não-interceptáveis nenhum dos erros proibidos pode ocorrer os outros erros, interceptáveis, podem ocorrer e é da responsabilidade do programador evitá-los

13 Segurança versus Flexibilidade
C é uma linguagem segura? PASCAL é uma linguagem suficientemente flexível? em termos de segurança: o C não é seguro aritmética de apontadores “casts” a tendência é no sentido de maior segurança C++ Java em termos de flexibilidade em PASCAL uma função genérica que traduza maiúsculas em minúsculas em cadeias de caracteres não pode ser construída! a tendência é no sentido de maior flexibilidade TURBOPASCAL, Delphi polimorfismos, ADTs, reflexão exemplos tipadas não-tipadas seguras ML LISP não-seguras C Assembly

14 Verificação de Tipos f(3); f(x); f(y);
consiste na detecção de erros de tipos a verificação de tipos pode ser: Estática, durante a compilação de programas, através da análise do código fonte Dinâmica, durante a execução do programa int x; any y; int f (int p) { … }; { f(3); f(x); f(y); } os erros devem ser detectados tão cedo quanto possível, porque: em tempo de execução exigem informação sobre tipos disponível a verificação de tipos atrasa a execução o programa é dificilmente validado já que podem sempre ocorrer erros os programadores devem dispôr de meios que lhes permitam especificar o comportamento dos programas quando um erro é detectado durante a execução por exemplo com excepções estática dinâmica

15 Inferência de Tipos as linguagens podem ter tipos explícitos na sintaxe como em PASCAL ou Java ou implícitos como em ML ou Haskell neste caso o sistema de tipos atribui tipos aos fragmentos do programa a inferência de tipos é uma extensão natural da verificação de tipos se o programador não fornece os tipos, o compilador deve extraí-los da análise do programa exemplo em ML: fun append(nil, l) = l | append(hd:: tl, l) = hd:: append(tl, l) o compilador de ML devolve o tipo da expressão val append = fn: ('a list * 'a list) -> 'a list e em fun suc(x) = x + 1 a inferência de tipos está ligada ao polimorfismo, como veremos mais tarde

16 Equivalência de Tipos um algoritmo decide quando são equivalentes, em termos de tipos, duas expressões escritas independentemente A e B são equivalentes? type A = record( x, y; real); type B = record( x, y; real); equivalência estrutural todos os tipos base são equivalentes tipos construídos são equivalentes se resultam da aplicação do mesmo construtor a tipos equivalentes e.g. SML, … A e B são equivalentes! equivalência por nomes duas expressões são equivalentes se resultam da mesma avaliação de uma expressão de tipos e.g. PASCAL, ADA, … A e B não são equivalentes!

17 Formalizar um Sistema de Tipos
é necessário formalizar toda a linguagem em questão a sintaxe dos termos (comportamento algorítmico) dos tipos (conhecimento estático) o alcance (scope) dos identificadores associa ocorrências de variáveis com as localizações onde foram ligados (binding) estático, quando a ligação entre identificador e localização pode ser determinada por análise léxica do programa (alcance léxico) dinâmico um fragmento de programa pode conter variáveis livres as regras de tipos tem-tipo M : A subtipo-de M <: A equivalência de tipos A = B contextos estáticos de tipos  M: A qual a semântica da relação tem-valor entre termos e uma colecção de resultados os tipos do resultado e dos termos devem ser os mesmos

18 Teoria de Tipos é usada para estudar problemas tais como:
se a verificação de tipos é decidível se a verificação pode ser feita durante a compilação senão, quais são os erros que podem aparecer em tempo de execução se podem ser gerados verificadores de tipos a partir de uma especificação do sistema de tipos na construção de um sistema de tipos há um compromisso entre poder expressivo segurança o sistema de tipos deve ser restritivo por forma a assegurar programas confiáveis flexível por forma a permitir que fragmentos do programa possam ser usados noutros contextos semelhantes sob o ponto de vista sintáctico, a teoria de tipos pode ser vista como sendo um conjunto de regras que, a partir de afirmações verdadeiras sobre tipos, permite deduzir outras afirmações verdadeiras

19 Regras de Tipos asserções julgamentos de tipos regras de tipos
proposições enunciadas como verdadeiras   as variáveis livres de  estão declaradas no contexto estático de tipos  contextos são listas ordenadas de variáveis (distintas) e seus tipos , X1:A1, x2:A2, x3:A3, …, xn:An dom() = x1, x2, …, xn julgamentos de tipos por exemplo:  M:A (“M tem o tipo A em  “)  true: Bool (“true tem tipo Bool “) , x: Nat x+1: Nat (“se x for do tipo Nat então x+1 é do tipo Nat “) regras de tipos do tipo: dado um conjunto um conjunto de premissas pode deduzir-se uma conclusão       a: A  (a): B “Se é conhecido que  é uma função de  em  e que a é do tipo A então pode deduzir-se que (a) toma valores em ”

20 Abstracções Proporcionadas pelas LPs
traduzem em termos abstractos os mecanismos físicos processador, memória, … variáveis funções nem todas as LP possuem funções, BASIC com ou sem efeitos secundários (side-effects), C/Haskell a semântica de passagem de parâmetros pode ser por valor ou por referência, SML/C++ podem ter verdadeira estrutura em blocos ou não, Algol/C controlo if-then-else for-do repeat-until do-while excepções podem servir, por exemplo, para tratar erros no exemplo apresentado, usando ADA, quando y=0, a excepção pre-definida DATA_ERROR é devolvida e o tratamento da excepção (exception handler) especifica o comportamento do programa o que aconteceria num programa em C? caso geral caso particular function divide (x, y: float) return float is begin return x / y; exception when DATA_ERROR => if y = 0 then return 1; else return sign(x) * MAXINT; endif end

21 Poder Expressivo de um Sistema de Tipos
conjunto de tipos básicos integer, boolean, float, string tipos enumerados, cadeias de bits, imagens conjunto de construtores de tipos registo ou tuplo (produto cartesiano etiquetado) variante (soma disjunta etiquetada) registo com variantes colecções array indexado, verificação de limites lista car, cdr conjunto mas em PASCAL é bastante restritivo sequência Galileo, O2 função apontador ADT polimorfismo record nome: string, idade: int end; union animal: DescAnimal, vegetal: DescVegeta, mineral: DescMineral end; record nome: string, idade: int, case sexo Sexo of Mulher: olhos: DescCor end end;

22 Tipos de Dados Abstractos
permitem um estilo de programação que leva a software de qualidade exemplo: problema pilha-de-palavras operações criar pilha nova adicionar palavra à pilha remover a última palavra da pilha ver se a pilha está vazia restrições só pode retirar-se uma palavra da stack se esta não estiver vazia o programador de C tem de conhecer os detalhes de implementação pode aceder a informação interna e aplicar operações ilegais o programador de ADA usando packages pode conseguir ADTs o compilador verifica se a pilha é usada apenas conforme especificado e não permite acesso aos elementos internos

23 Pilha-de-palavras em C
/* especificação */ typedef char[256] word; typedef struct stack { int size; word * elements; } * stack; stack stack_create(); void stack_insert(stack, word); void stack_drop(stack); char stack_empty(stack); /* implementação */ stack stack_create() { stack st = malloc(sizeof(struct stack)); st->size = 0; st->elements = (word *) malloc(1024 * sizeof(word)); return st; } void stack_insert(stack st, word w) { strcopy(st->elements[++st->size], w); void stack_drop(stack st) { --st->size; char stack_empty(stack st) { return (st->size == 0); /* uso */ char w1[] = "hello"; char w2[] = "world"; stack s; s = stack_create(); stack_insert(s, w1); stack_insert(s, w2); stack_drop(s); if (stack_empty(s)) { /* do st */ }

24 Pilha-de-palavras em ADA
/* especificação */ package STACKS is type stack is private; type word is private; function create() return stack; function insert (s: stack, w: word) return stack; function drop (s: stack) return stack; function empty (s: stack) return boolean; private type word is string; type stack is record size: integer; data: array( ) of word; end record end /* implementação */ package body STACKS is function create () return stack is begin s: stack; s.size:= 0; return s; end; function insert (s: stack, w: word) return stack is begin s.size:= s.size +1; s.data(s.size):= w; return s; end; function drop (s: stack) return stack is s.size:= s.size -1; function empty (s: stack) return boolean is return (s.size = 0); end STACKS; /* uso */ uses STACKS s: stack:= create(); s:= insert(s, "hello"); s:= insert(s, "world"); s:= drop(s); s.size;= 0; // type error!

25 Vantagens de Programar com ADTs
é uma técnica de desenvolvimento que leva a software de maior qualidade agrupa na mesma unidade os dados de uma aplicação e as operações que podem ser aplicadas a esses dados separa a especificação de tipos da implementação e torna visível apenas informação pertinente permite a existência de diversas implementações para a mesma especificação (com diferentes desempenhos)

26 Polimorfismo linguagens polimórficas linguagens monomórficas
um valor, em particular uma função, pode pertencer simultaneamente a vários tipos linguagens monomórficas valores têm apenas um tipo que pode ser determinado quando o programa é compilado polimorfismo introduz maior flexibilidade (e.g. a aplicação de uma função a valores de tipos diferentes) mantendo os programas seguros como vimos sistemas de tipos são conjuntos de restrições impostos sobre uma linguagem não tipada que limitam o número de programas correctos que podem ser escritos na ausência de tipos não há restrições, mas os programas podem falhar variedades de polimorfismo ad-hoc (código diferente executado para cada tipo) overloading o mesmo nome é usado para funções diferentes (e.g. 3+4 e ) coercion um argumento é convertido para o tipo esperado pela função (e.g ) universal (o mesmo código é executado para cada tipo) paramétrico funções aplicadas a uma categoria de tipos com a mesma estrutura (e.g. lenght l) de inclusão funções aplicadas a tipos ligados por relações de ordem (e.g. pessoa.idade e estudante.idade)

27 Funções Paramétricas ML Napier88 fun append (nil, l) = l
| append (hd:: tl, l) = hd:: append(tl, l) é polimórfica e o seu tipo (inferido como vimos) é: val append = fn : ('a list * 'a list) -> 'a list (aplicada a duas listas com elementos de qualquer tipo 'a produz uma lista com elementos desse mesmo tipo) Napier88 let id = proc[t](x: t -> t); x é polimórfica com tipo proc[t](t -> t) antes de ser usada, a função é instanciada duas vezes com um parâmetro de tipo e com um valor desse tipo let three = id[int](3) também se podem conseguir versões monomórficas instanciando com um parâmetro de tipo let idInt = id[int] se tipos fossem considerados valores da linguagem (como em Quest) esta separação não seria necessária A:: K A tem kind K (kinds classificam tipos e operadores de tipos) a: A a tem tipo A (tipos classificam valores)

28 Tipos Paramétricos quando definições de tipo têm estrutura semelhante, podem ser expressas num tipo paramétrico type Pair_of_integers = int x int type Pair_of_reals = real x real type Pair[t] = t x t type Pair_of_integers = pairs[int] type Pair_of_reals = pairs[real] um tipo paramétrico não é um tipo, é uma operação sobre tipos! Pair_of_integers não cria um novo tipo, apenas associa um nome a uma expressão de tipos exemplos: type A[t] = proc(t -> t) type B = proc[t](t -> t) operação que associa qualquer tipo t com o tipo de funções de t em t tipo das funções que transformam um valor do tipo t noutro valor do mesmo tipo

29 Subtipagem (sub-typing)
se existir uma relação de ordem entre tipos (A <: B) esta pode ser usada para: conversão automática de tipos pelo compilador resolver sobrecarga (overloading) de operadores formalizar o conceito de herança esta relação de ordem pode ser implícita, quando é inferida usando as regras de tipos explícita, quando é declarada na altura em que os tipos são definidos uma combinação dos dois casos anteriores; por exemplo, apenas nos ADTs (representando entidades) a relação de ordem é explícita, para todos os outros tipos é implícita implicitamente type Car = [name: string, speed: int, fuel: string] type Vehicle = [name: string, speed: int] explicitamente type Car subtype Vehicle = [name: string, speed: int, fuel: string]

30 Subtipagem subtipagem em escalares (range) subtipagem em funções
n..m <: p..q sse p<=n e q>=m subtipagem em funções s -> t <: s' -> t' sse s' <: s e t <: t' é a regra contravariante: domínio maior e contradomínio menor onde uma função de um dado tipo pode ser usada, também uma função de um seu subtipo pode ser usada subtipagem em tuplos [a1:t1,… ,an:tn,… ,am:tm] <: [a1:u1,… ,an:un] sse ti <: ui para i  [1,n] aparece nas linguagens Orientadas aos Ojectos

31 Regras de Subtipagem top reflexiva transitiva funcional tuplos
 t <: any reflexiva  t <: t transitiva  s <: t  t <: u  s <: u funcional  s' <: s  t <: t'  s  t <: s'  t' tuplos  s1 <: t1 …  sn <: tn  [a1:s1,…,an:sn,…,am: sm] <: [a1:t1,…,an:tn] um valor de subtipo pode ser usado onde um valor do tipo é esperado  e:t  t <: u  e:u

32 Polimorfismo de Inclusão
subtipagem é uma forma de polimorfismo uma função que pode ser aplicada a valores de um tipo, também pode ser aplicada a valores de todos os seus subtipos exemplo: value g fun(x: [age: int]) x.age tem tipo [age: int] -> int e pode ser aplicada a [age:31] ou a [name: Jean, age: 34] polimorfismo de inclusão pode ser combinado com paramétrico value h = all[a <: [age: int]] fun(x: a) x.age:= 29, x não é possível aplicar h a todos os a; admite apenas os subtipos de um dado tipo

33 Reflexão “um sistema computacional é dito reflexivo se incorpora em si próprio dados representando aspectos de si próprio” reflexão é o processo de raciocinar acerca de si próprio ou actuar em si mesmo e mudar de comportamento no curso de uma avaliação pode ser obtida mudando a forma como os programas são avaliados no sistema mudando as estruturas próprias do programa em reflexão comportamental um programa pode alterar o seu próprio significado, através: de manipulação do seu avaliador (e.g. interpretador) do envio de mensagens a um meta-objecto que especifica aspectos do seu comportamento (e.g. como o objecto herda da superclasse) em reflexão linguística programas podem alterar-se directamente (e.g. gerando novas estruturas de dados ou código para ser executado) em tempo de compilação (TRPL) em tempo de execução (PS-algol, Napier88)

34 Reflexão Linguística Segura em Tempo de Execução
permite a existência de programas construídos, compilados e integrados na computação corrente !* ... writeString("Escreva uma expressão com i") let theProgram = "proc(i: int -> int); " ++ readString() let theResult = compile(theProgram) project theResult as R onto proc(int -> int) : newProc:= R() string : writeString("Erros : " ++ R) default : {} !* nunca acontece writeString("Expressão com 10 = " ++ iformat( newProc(10) ) !* neste exemplo (usando a sintaxe Napier88) reflexão é conseguida através do uso de procedimento compile, de verificação de tipos dinâmica e de ligação dinâmica do resultado do programa no programa em execução

35 Polimorfismos e Reflexão
tanto polimorfismos como programas reflexivos permitem abstrair detalhes promover reutilização polimorfismo pode ser usado quando uma computação não depende dos tipos dos operandos permitindo que estes sejam abstraídos (paramétrico) uma computação depende apenas parcialmente nos tipos (inclusão) usando reflexão linguística, segura (type-safe) podem ser escritos programas que dependem arbitrariamente nos tipos de dados que manipulam reflexão permite escrever programas que operam em valores de tipos ainda não conhecidos na altura em que são feitos exemplo do browser

36 Conclusão sistemas de tipos
servem para estruturar os valores manipulados pelas linguagens de programação servem os papéis: de modelação: estruturar os dados de uma aplicação de protecção: proteger contra usos ilícitos as linguagens de programação têm evoluído no sentido de tipagem forte predominantemente estática mas com sistemas de tipos mais flexíveis tipos de dados abstractos (ADT) polimorfismo paramétrico subtipagem bulk data types variantes tipos dinâmicos (any) first-class procedures reflexão logo estão mais adaptadas à modelização!

37 Conclusão (cont) modelos semânticos de dados
servem para descrever os aspectos estruturais da aplicação mas têm limitações a nível do comportamento das entidades da implementação dos aspectos temporais ou dinâmicos (fica-se normalmente por proposições sobre a dinâmica) note-se que os modelos orientados aos objectos proporcionam implementação e modelização do comportamento (OMT, UML) linguagens de programação de bases de dados (LPBD) têm por objectivo unificar a estrutura dos dados e as funções que o sistema deve implementar LPBDs são linguagens completamente gerais, baseadas num sistema de tipos permitindo programas que podem ser validados, se possível estaticamente; como são usadas para aplicações orientadas aos dados, devem permitir a modelização de dados complexos

38 Como Combinar Abstrações dos Modelos Semânticos com Abstrações dos Sistemas de Tipos?
os tipos de dados abstractos dos modelos semânticos definem a estrutura nas linguagens de programação a estrutura e as operações são definidas os ADTs podem ser usados em conjunto com os outros valores da linguagem o interesse especial é o que se pode fazer com as instâncias do tipo (o comportamento!) por exemplo, a STACK em ADA package STACKS is type stack is private; type word is private; function create() return stack; function insert (s: stack, w: word) return stack; function drop (s: stack) return stack; function empty (s: stack) return boolean; private type word is string; type stack is record size: integer; data: array( ) of word; end record end apenas existe a preocupação de dizer como o que se pode fazer com a stack e não o que é a stack as linguagens orientadas aos objectos fornecem mecanismos para a definição de ADTs na fronteira entre os tipos abstractos dos modelos semânticos e os ATDs das linguagens de programação

39 Classe Point em Eiffel mais geral que no exemplo apresentado em ADA
deve ser possível definir a estrutura e o comportamento num ADT preservando as propriedades de abstracção por exemplo, em Eiffel: class Point export x, y, translate, scale feature x, y: real scale (f: real) is do x:= x * f; y:= y * f; end translate (a, b: real) is x:= x + a; y:= y + b; end Point esta classe define ponto como tendo certas propriedades: x, y atributos como nos modelos semânticos scale, translate operações

40 Herança conceito muito sobrecarregado linguagem modelação subtipagem
tipos paramétricos módulos classificações modelação especificação incremental Empregado is-a Pessoa polimorfismo paramétrico Set[Pessoa] is-a Set[t] implementação Dictionary[t] is-a Set[t] modularidade classes com papel de módulos (Eiffel) especialização e generalização Red-cars class ( Car ) = Cars / colour = red Human-being class = Men Union Women

41 Classes e Relações classe é um conceito de extensão
agrupa várias entidades com propriedades semelhantes a existência de uma entidade está ligada à pertença a uma classe e as classes organizam-se em hierarquias conjuntos não são suficientes para representar classes relação representa ligações não direccionais entre entidades registos e atributos das linguagens de programação representam ligações direccionais entre entidades (pessoa -> idade) relações podem ter chaves e métodos de acesso específicos nos esquemas relacionais temos relações para representar classes de entidades relações para representar ligações (não direccionais) entre entidades pertencendo a classes classes e relações são mecanismos independentes e uma LPBD deve ter ambos!

42 Tipos Abstractos e Independência Lógica
a parte de interface de ADTs pode ter várias representações exemplo com edifícios com a entrada dependente do monumento e noutros determinada pela C.M. type Cidade is abstract nome: string entradas: float end type Monumento is abstract name: string cidade: Cidade entrada: float end let CriarMonumento= fun(n: string, c: Cidade, e: float) Monumento( nome= n, cidade= t, entrada= e) let CriarMonumentoCamarario = fun(n: string, c: Cidade) Monumento( nome= n, cidade= t, derived entrada= t.entradas) preservando uma interface simples para a manipulação de dados, podem ser representadas situações complexas com ADTs e o conceito de dados derivados é um passo no sentido da independência lógica!

43 Módulos e Esquemas de BDs
um módulo é um espaço para nomes module Pessoal export Pessoa, Empregado type Pessoa … type Empregado … … end module Propriedades export Cidade, Monumento, … type Cidade … type Monumento … … end module Aplicação import Pessoal, Propriedade export Consultar, Criar, Modificar … end o esquema das BDs representa a totalidade da informação vistas são usadas para derivar representações secundárias com módulos a definição é descentralizada menor complexidade na definição do esquema, melhor controlo de evolução, definição de vistas resume-se à definição de módulos deve ser procurada uma síntese entre as técnicas de modelação de BDs e de Engenharia de Software! vista 1 vista 2 esquema modulo 1 modulo 3 modulo 2 vista 2 vista 1

44 Conclusão uma LPBD deve beneficiar dos avanços
nos modelos de dados e nas linguagens de programação o centro da integração de conceitos dos dois domínios reside nos tipos de dados abstractos mais á frente veremos que os ADTs das linguagens orientadas aos objectos são ainda mais convenientes! subtipagem é importante pois permite uma definição incremental dos tipos de uma aplicação o mecanismo de excepções pode ser usado nas LPBDs para tratar da violação de restrições de integridade; estas restrições devem ser especificadas globalmente e de forma declarativa o modelo de transacções numa LPBD tem de ser bastante mais sofisticado do que nos sistemas relacionais já que os processamentos são mais complexos “nested transactions”, por exemplo

45 Dos Conceitos para os Sistemas
ERDBMS Exodus, Genesis,Starbus, Sabrina,Postgres Modelo Relacional ADT Ada, Clu Lógica modelos datalog NF2 Lógica + NF2 modelos NF2 OOPL + identidade Smalltalk, C++ LDL, Col, Nail Modelos OODB outras linguagens Semântico Gemstone, Iris,Orion, O2 IFO, Daplex, FQL PPL PS-algol,Napier88, Pascal-R

46 Linguagens de Programação de BDs
extensões ao modelo relacional Pascal-R integrar características SGBD numa LP Adaplex LPBD PS-algol persistência Napier88 orientação aos objectos

47 Extensões ao Modelo Relacional
1) modelos com valores estruturados modelos NF2 (non-first normal form) 2) modelos dedutivos e programação em lógica datalog, LDL 3) modelos de objectos com identidade O2 4) sistemas extensíveis Exodus, Starbust, Genesis, Postgres

48 Modelos com Valores Estruturados
no modelo relacional temos: conjuntos tuplos (que não são cidadãos de primeira) atributos atómicos generalizando os domínios possíveis para os atributos para valores complexos não 1NF tuplos (relações hierárquicas) se v1, v2, …, vn são valores e a1, a2, …, an são atributos então [v1:a1, …, vn:an] é um tuplo conjuntos (relações encaixadas) se v1, v2, …, vn são valores distintos então {v1, …, vn} é um conjunto por exemplo: { [nome: "Torre dos Clérigos", endereco: [cidade: "Porto", rua: "Carmelitas"], fechado_em: {"Natal", "Páscoa", "10 Junho"}, entrada: ] [nome: "Museu Soares dos Reis", endereco: [cidade: "Porto", rua: "D. Manuel II"], fechado_em: {"Natal", "Páscoa", "10 Junho"}, entrada: ] [nome: "Estádio das Antas", endereco: [cidade: "Porto", rua: "Fernão de Magalhães"], fechado_em: {"Natal", "Páscoa"}, entrada: ] }

49 Modelos Dedutivos e Programação em Lógica
Prolog: factos + regras podem ser inferidos outros factos usando regras e factos Bases de dados dedutivas resultam da aplicação desta mesma visão duas aproximações factos são gerados sempre que é adicionado um novo facto ou regra factos são gerados apenas como resposta a interrogações os predicados Prolog podem ser vistos com um conjunto de tuplos (relações) mas nas bases de dados o desempenho é crucial existem linguagens que trabalham ao nível do tuplo (em Prolog só um tuplo de cada vez) as quantidades de dados são muito grandes a aproximação lógica tem como vantagens apresentar um formalismo uniforme e de nível superior para definir dados, vistas e restrições de integridade permitir a existência de linguagens baseadas em regras de dedução não haver distinção entre processamento de dados gerais e dados da base de dados (ver desadaptação de impedâncias) exemplos: Datalog, cláusulas de Horn sem funções LDL, extensão ao Datalog com conjuntos e operações em conjuntos, e funções pré-definidas

50 Modelos de Objectos com Identidade
nestes modelos a identidade aparece de forma explícita é um nome dado a cada objecto da base de dados no modelo relacional 2 tuplos são considerados iguais se contiverem os mesmos valores a identidade permite a partilha de dados por exemplo: clerigos= [nome: "Torre dos Clérigos", endereco: [cidade: porto, rua: "Carmelitas"], fechado_em: {"Natal", "Páscoa", "10 Junho"}, entrada: 350.0] pilar= [nome: "Mosteiro da Serra do Pilar", endereco: [cidade: gaia, rua: "Av. República"], fechado_em: {"Natal", "Páscoa", "10 Junho"}, entrada: 350.0] museu= [nome: "Museu Soares dos Reis", endereco: [cidade: porto, rua: "D. Manuel II"], fechado_em: {"Natal", "Páscoa", "10 Junho"}, entrada: 650.0] porto= [nome: "Porto", população= , estacoes= {"Campanhã", "S. Bento", "Trindade"} ] gaia= [nome: "Vila Nova de Gaia", população= , estacoes= {"Devesas", "Gaia"} ]

51 Sistemas Extensíveis sistemas com tipos mais complexos resultado da introdução de ADTs como domínios de valores modelo de dados mais rico exemplos: Exodus, Starbust, Genesis uma implementação possível consiste no uso do componente "data manager" de um SGBD com extensões para objectos complexos e módulos Postgres, baseado no Ingres foram propostas várias extensões a SQL para lidar com valores destes sistemas exemplo de sistema extensível tipos (apenas podem ser usados em atributos) type Regiao = [ rec: Rectangulo contorno: Poligono] type Rectangulo = [ sw: Ponto ne: Ponto] type Ponto = [ x: float y: float] type Poligono = array of Ponto

52 Exemplo de Sistema Extensível (cont)
operações (algumas das funções devolvem atributos) rec(Regiao) : Rectangulo contorno(Regiao) : Poligono sw(Retangulo) : Ponto ne(Retangulo) : Ponto x(Ponto) : float y(Ponto) : float superficie(Regiao) : float janela(Regiao,Rectangulo : Regiao interseccao(Regiao, Regiao) : Regiao rectinterseccao(Rectangulo, Rectangulo) : Rectangulo isin(Poligono, Ponto) : boolean inter(Regiao, Regiao) : boolean inrect(Rectangulo, Rectangulo) : boolean interrect(Rectangulo, Rectangulo) : boolean esquema da Base de Dados create table Cidade (cnome: string, cplano: Regiao) create table Monumento (mnome: string, mlocal: Pont) create table Floresta (fnome: string, fplano: Regiao)

53 As duas Opções Para Conseguir uma LPBD
INTEGRAÇÃO - partir de uma linguagem e adicionar características de SGBD coloca o ênfase em bulk data types características os dados são estruturados em colecções (RELAÇÕES) a procura pode ser feita pelo conteúdo (FILTROS) permite acesso concorrente (SGBD) PERSISTÊNCIA - conseguir que os valores manipulados pela linguagem persistam coloca o ênfase em tornar persistentes todos os valores manipulados pela linguagem tipos e persistência são ortogonais possuem ADTs permitem programação modular espaço sofisticado para nomes contextos usados para especificar persistência o espaço de nomes fica no armazém de objectos

54 PASCAL/R combina PASCAL com o Modelo Relacional
usa record do PASCAL sem variantes para representar tuplos; os campos têm valores atómicos adiciona Relation para definir uma estrutura em que todos os elementos são da mesma espécie de record adiciona Database para tratar da persistência; database associa um nome com as relações que vão persistir podem ser definidas variáveis em database, relation e record relation pode servir de argumento para funcões desvantagens desta abordagem: o tipo record só permite definir tuplos com atributos atómicos apenas valores do tipo relation podem persistir assim um record só persiste se estiver dentro de uma relação

55 Exemplo em PASCAL/R programa exemplo interrogação exemplo
Monumentos = relation nome, cidade of record nome: string; cidade: string; rua: string; fechado_em: string; entrada: integer; end; Restaurantes = relation nome,cidade of record name: string; cidade: string; rua: string; fechado_em: string; prato: string; preco: integer; end; Turismo = database monumentos: Monumentos; restaurantes: Restaurantes; end; interrogação exemplo for each m in Turismo.monumentos: m.nome = "Clérigos" do for each r in Turismo.restaurantes: r.cidade = m.cidade and r.rua = m.rua do writeln(r.nome); qual o nome dos restaurantes na mesma rua que os monumentos chamados Clérigos?

56 ADAPLEX integra a linguagem ADA e o modelo funcional Daplex
ADA tem uma posição ímpar dentro das linguagens imperativas, porque possui módulos, ADTs, programação paralela, etc Daplex baseia-se no paradigma funcional e suporta herança Adaplex é um extensão de ADA com novos tipos e estruturas de controlo correspondentes a Daplex entidades têm uma estrutura de tuplo mas os atributos podem ter qualquer valor (por exemplo estruturas) herança é definida explicitamente pratos(restaurante) devolve o conjunto de pratos do restaurante

57 Programa em Adaplex database Turismo is type Monumento is entity nome: string; cidade: string; rua: string; fechado_em: string; entrada: integer; end entity; type Prato is entity nome: string; preco: integer; end entity type Restaurante is entity nome: string; cidade: string; rua: string; fechado_em: string; menu: set of Prato; end entity; type Restaurante_classificado is entity entrada: integer; end entity; include Restaurante_classificado in Restaurante; end database

58 Transacção em Adaplex use Turismo * designa a BD envolvida na computação* atomic * start transaction* procedure average(in a_rest: Restaurante; out average: pnum); declare number: pnum :=0; sum: pnum:= 0; for each prato in pratos(a_rest) loop number:= number + 1; sum:= sum + preco(prato); end loop; average:= sum/number; end average; declare ave: pnum; average(a_rest in Restaurante where nome(a_rest) = "A Torre de Belém", ave); put (av); end atomic; *end transaction*

59 Linguagens Persistentes Ortogonais
PS-Algol (82) -> Napier88 (88) Galileo (84) -> Fibonacci (94), Galileo95 DBPL (80) -> Tycoon (94) TIPOS E PERSISTENCIA SÃO ORTOGONAIS todos os valores manuseados pela linguagem podem persistir uma linguagem pode ser considerada PPL se respeitar os seguintes princípios: persistence independence, a forma de um programa é independente da longevidade dos dados que manipula data type orthogonality, todos os valores devem ter direito a possuir todo o espectro da persistência persistence identification, o mecanismo usado para identificar objectos persistentes não deve depender do sistema de tipos consequências: parâmetros de procedimentos podem ser transitórios ou persistentes permite desenvolvimento incremental de aplicações e troca de componentes para manutenção um valor mantém o tipo mesmo quando é utilizado noutro programa

60 PS-Algol primeira linguagem de programação que trata persistência de forma uniforme baseada em S-Algol tipos básicos: boolean, integer, real, file, string, pntr tipos construídos: vector, structure adiciona table, indexada por inteiros ou cadeias de caracteres, e as respectivas operações em tabelas pntr não é verificado estaticamente mas sim em tempo de execução procedimentos são “first class values” como em Algol e podem ser guardados na BD exemplo:

61 Programa em PS-Algol structure Prato( string nome; int preco)
structure Restaurante( string nome; string cidade; string rua; pntr fechado_em; *pntr pratos) !ligar á base de dados let db = open.database("Restaurantes","miam","read") if db is error.record do { write "error, database not opened"} !ler a lista de restaurantes e inicializar let restaurantes = s.lookup("Restaurantes", db) let rest = s.lookup("A Bolsa", restaurantes) let sum := 0 !procedimento para adicionar o preco de um prato á soma let add = proc(pntr val -> bool) begin let sum := sum + val(preco) true end !calcula a soma dos precos dos pratos e a média let number := s.scan(rest(pratos), add) average := sum div number

62 Encapsulamento em PS-Algol
let add:= proc(pntr a, b -> pntr); nullproc let print:= proc(pntr a); nullproc let Complex:= proc(real a, b -> pntr); nullproc !definir o ADT begin structure ComplexX(real r, i) add:= proc(pntr a, b -> pntr) ComplexX(a(r)+b(r), a(i)+b(i)) print:= proc(pntr a) write(a(r)) if a(i)<0 write "-" else write "+" write (a(i)), "i" Complex:= proc(real a, b -> pntr) ComplexX(a, b) end !exemplos de manipulacoes let a= Complex(-1.0,-2.4) let b= Complex(2.3,3.2) print(add(a,b))

63 Napier88 o sistema Napier88 consiste na linguagem e num ambiente persistente contém um armazém (store) com objectos usados pelo próprio sistema o modelo de persistência é o de atingibilidade (reachability) persistem os valores no fecho transitivo de uma raiz de persistência. o armazém vai de estado estável em estado estável definido por uma operação STABILISE explícita ou implícita o armazém é mantido estável através de um mecanismo de “after look shadow pagging” Napier88 é (quase integralmente) tipada estatisticamente é modular já que podem ser usados contextos (environment) aceita polimorfismo paramétrico, procedimentos de ordem superior e reflexão linguística permite a definição de ADTs, quantificados em existência pixel e picture são tipos básicos da linguagem possui o tipo file para comunicação com o sistema de ficheiros possui arrays, tuplos e variantes mas, não tem linguagem de interrogação não suporta subtipagem

64 Simplicidade e Poder power through simplicity and simplicity through generality no projecto desta linguagem foram seguidos os princípios da correspondência da abstração data-type completness quando um tipo é usado num construtor qualquer tipo pode ser usado, sem excepção levam a maior poder e menor complexidade já que não há excepções arquitectura distribuição concorrência transacções PAM heap local heap estável memória estável memória não volátil

65 Exemplos em Napier88 !* definicao let get-size = proc[t](*t -> int) size(t) ! uso get-size[sting](vector of ("um","dois")) !* tipo de dados abstractos type Test is abstract[ref](a: ref; b: proc(ref -> ref)) !* criar 2 values do tipo Test let three= Test[int](3, proc(x: int -> int); x+1); let half= Test[real](0.5, proc(x: real -> real); x+1.0); !* uso use half as X in X(a):= X(b)(X(a)) !* infinite union type, verificado dinamicamente let quid= any(34); let i= project quid X onto int: X default: 0 !* contextos com ligações let e= env() in e let um:= 1 in e let dois:= 2 in e let tres:= 3 !* uso use e with um, dois: int in e let modify = proc() {um:= um +1; dois:= dois + 1}

66 Sistemas Orientados aos Objectos
extensões ao modelo relacional integração/persistência Gemstone Orion LPBD Lisp/ST80 orientação aos objectos Daplex/Object Iris Vbase O2 Ontos Imperative Simula67, classe — agrupa estrutura de dados com métodos Smalltalk — tudo são objectos

67 Princípios e Terminologia OO
identidade a identidade de um objecto deve ser independente do valor associado; não pode ser manipulada directamente pelo programador pode ser implementada com um identificador interno único id1 -> [nome: R4, fabricante: Renault, ano: 1978, chassis: id3] igualdade por valor id2 -> [nome: R4, fabricante: Renault, ano: 1978, chassis: id4] igualdade profunda (não são idênticos) id3 -> [tipo: XF330, peso: 200] id4 -> [tipo: XF330, peso: 200] encapsulamento a aplicação é um conjunto de objectos caracterizados por uma estrutura e uma interface a estrutura é identificada por um id único e possui um estado que agrupa campos com informação o valor destes campos pode ser atómico ou outros objectos representados pelos seus ids a parte visível de um objecto, interface, é constituída por selectores de métodos a estrutura é apenas conhecida pelo objecto e não pode ser acedida do exterior leva a programação modular uma subclasse pode redefinir métodos da superclasse grafo de herança classes predefinidas (de uma biblioteca de utilitários) também constituem um grafo de herança

68 Classes exemplo Class Pessoa Attributes nome data_nascimento esposa filhos Methods nome return(self.nome) nome_esposa return(self.esposa) idade … Class Empregado Superclass Pessoa Attributes salario chefe departamento bonus methods salario return(self.salario) nome_do_chefe return(self.chefe) … os métodos executáveis são linkados dinamicamente ao selector, de acordo com a classe do receptor da mensagem a aplicação de um método a um objecto é chamada envio de mensagem o método é escolhido por late binding

69 Gemstone 1984 extensão do Smalltalk tipagem dinâmica
não permite herança múltipla exemplo object subclass: #Turismo instVars: 'monumentos restaurants' classVars:'' immutable: false constraints: #[#[monumentos Monumentos] #[restaurantes Restaurantes]] object subclass: #Monumento instVars: 'nome rua cidade fechado_em entrada' classVars:'' immutable: false constraints: #[#[nome String] #[rua String] #[cidade String] #[fechado_em Dias] #[entrada Float]] object subclass: #Restaurante instVars: 'nome rua cidade fechado_em pratos' classVars:'' immutable: false constraints: #[#[nome String] #[rua String] #[cidade String] #[fechado_em Dias] #[pratos Pratos]]

70 Gemstone (cont.) qual é o preço médio dos pratos do restaurante ?
object subclass: #Prato instVars: 'titulo preco' classVars:'' immutable: false constraints: #[#[titulo String] #[preco Float]] qual é o preço médio dos pratos do restaurante ? método na classe Restaurante Restaurante mediaPratos | conjuntoPratos Soma | conjuntoPratos:= self menus. soma:= 0. conjuntoPratos do[:prato | preco | preco:= prato preco. soma:= soma + preco.] ^(soma / (conjuntoPratos size)) possui linguagem de interrogação exemplo: Restaurante select: {umRest | umRest.rua = 'Rua do Bonjardim' & umRest mediaPratos < 150}

71 Orion projectado para aplicações de CAD, IA, Automação de escritório
baseado Lisp (funcional) interrogações usando predicados tratamento de versões, objectos compostos, evolução dinâmica dos esquema, dados multimédia tudo são objectos (como em Smalltalk) proporciona classes, métodos e herança múltipla um objecto não pode ser um conjunto mas o valor de um atributo pode ser um conjunto de objectos exemplo: Monumento [nome: string, endereco: Endereco, fechado_em: string, entrada: num] Restaurante [nome: string, endereco: Endereco, fechado_em: string, pratos: dependent setof Prato] Endereco [rua: string, cidade: string] Prato [nome: string, preco: int]

72 Orion (cont) a linguagem de interrogação é baseada na mensagem select
quais os restaurantes na Rua dos Clérigos que vendem pratos a menos de 500$00 (Restaurante select :R (:R endereco rua = "Rua dos Clérigos") and (:R endereco cidade = "Porto") and (:R prato some:M (:M preco < 500))) a variável R percorre os restaurantes some opera em conjuntos e envia uma mensagem a cada elemento; devolve true ou false não permite interrogações envolvendo duas classes não relacionadas select é aplicada à extensão de uma classe o conceito de objectos dependentes é interessante não permite tipagem estática

73 Iris influenciado pelos modelos semanticos Daplex e TAXIS Object SQL
Editor gráfico OQL embebido CLI funções externas tipos, objectos, funções, interrogações, modificações, versões IRIS Kernel controlo de concorrência, recuperação, manipulação de buffers, Índices, Agrupamentos (clusters), manipulação de identificadores Iris Storage Manager

74 Iris (cont.) objectos 'literais' objectos 'identificáveis'
identidade definida pelo valor strings, inteiros, listas objectos 'identificáveis' objectos com ids independentes do valor pessoa, prato objectos podem adquirir ou perder tipos dinamicamente evolução da base de dados não pode ter tipagem estática tipos são caracterizados por conjuntos de funções exemplo do Monumento nome: Monumento -> Charstring endereco: Monumento -> Endereco fechado_em: Monumento ->-> Charstring entrada: Monumento -> integer

75 Iris via OSQL OSQL é uma extensão ao SQL exemplo
os objectos podem ser referidos directamente sem o uso de chaves uma interrogação pode usar funções definidas pelo programador ou funções do sistema nas cláusulas where e from exemplo create type Monumento (nome Charstring required, endereco Endereco, fechado_em Charstring many, entrada Integer); create type Restaurante_Classificado subtype of Monumento (pratos Prato many); criar funções guardadas (correspondendo a relações entre objectos) arrays associando entradas a saídas create function classifica (Restaurante_Classificado, Guia) -> Integer; atribuição de valores set classifica (r, g) = 4; funções derivadas e funções externas selecção select nome(r) for each Restaurante_Classificado r where classifica(r, Michelin) = 4

76 Ontos ODBS distribuído versões, transacções encaixadas, excepções
interfaces com C++ e OSQL programação de mais baixo nível para obter melhor desempenho perdendo em segurança e facilidade de utilização arquitectura cliente/servidor usando uma LAN transferências de objectos (ou o fecho transitivo de um objecto) de disco para memória, podem ser controladas pelo programador configurações usam versões de objectos possui classes (de esquema) com descrições acessíveis em execução Type, Property, Procedure, ArgumentList, Argument a interface ao SQL estende o tipo de argumentos nas cláusulas select, from e where

77 Conclusão os primeiros sistemas foram baseados em linguagens interpretadas não tipadas a tendência é no sentido da definição de linguagens OO com funções compiladas (melhor desempenho) e tipagem estática (mais segurança) fornecem identidade de objectos e permitem manipular estruturas sem identidade (tuplos, conjuntos) fornecem uma linguagem de interrogação e uma linguagem geral poucos sistema fornecem o conjunto de facilidades dos SGBDs particularmente o tratamento de recuperação e concorrência


Carregar ppt "Linguagens de Programação de Bases de Dados"

Apresentações semelhantes


Anúncios Google