370 likes | 459 Vues
Capítulo 8: BDs Orientadas a Objectos. Necessidade de Tipos de Dados Complexos O Modelo de Dados Orientado para Objectos Linguagens Orientadas para Objectos Linguagens de Programação Persistentes Linguagem de definição de dados ODMG Linguagem de manipulação de dados ODMG.
E N D
Capítulo 8: BDs Orientadas a Objectos • Necessidade de Tipos de Dados Complexos • O Modelo de Dados Orientado para Objectos • Linguagens Orientadas para Objectos • Linguagens de Programação Persistentes • Linguagem de definição de dados ODMG • Linguagem de manipulação de dados ODMG
Necessidade de Tipos Complexos • As aplicações de Bases de Dados apenas usavam tipos de dados conceptualmente simples • Poucos tipos de dados, verificando-se a 1ª Forma Normal • Os tipos de dados complexos têm ganho importância • E.g. Moradas podem ser vistas como • String, ou • Atributos separados para cada parte da morada, ou • Atributos compostos (que não estão na 1ª Forma Normal) • Por vezes é útil guardar atributos compostos como tal, em vez de criar uma relação separada para guardar os valores na 1ª Forma Normal • Aplicações • computer-aided software engineering, computer-aided design • multimedia, e bases de dados de documentos e hipertexto.
Modelo de Dados Orientado a Objectos • Podemos ver um objecto como uma entidade do modelo ER. • O paradigma de objectos baseia-se na encapsulação de código e dados relativos a um objecto, numa unidade única. • Trata-se de um modelo lógico de dados (como o modelo ER). • É uma adaptação do paradigma de programação por objectos (e.g., Smalltalk, C++, Java) a sistemas de Bases de Dados.
Estrutura de Objectos • A um objectos estão associados: • Um conjunto de variáveis, contendo os dados do objecto, onde o valor de cada variável é um objecto • Um conjunto de mensagensàs quais o objecto responde; cada mensagem pode ter zero, um ou mais parâmetros. • Um conjunto de métodos, cada um dos quais consistindo em código que implementa uma mensagem; um método devolve um valor como resposta a uma mensagem • A representação física dum objecto só está visível a quem o implementou • As mensagens (e respostas) são o único interface possível com um objecto. • Apesar do nome, uma mensagem não obriga a que haja algo a ser passado. As mensagem podem ser implementadas como invocação de procedimentos.
Mensagens e Métodos • Os métodos são programas com as seguintes características: • Só se podem usar (directamente) variáveis do próprio objecto • Dados noutros objectos só podem ser acedidos por envio de mensagens. • Os métodos podem ser read-only ou de actualização • Métodos read-only não alteram o valor do objecto • Levado à regra, em bases de dados cada atributo duma entidade tem que ser representado por uma variável (que guarda o valor) e dois métodos (um para ler o valor, e outro para o alterar) • e.g., o atributo morada é representado pela variável morada e dois métodos get-morada e set-morada. • Para facilitar, muitos dos modelos de objectos permitem acesso directo às variáveis de outros objectos.
Classes • Objectos semelhantes são agrupados em classes; cada um desses objectos agrupados chama-se uma instância da classe • Todos os objectos duma classe, têm os mesmos: • Variáveis com os mesmos tipos • Interface de mensagens • Métodos Só podem diferir nos valores das suas variáveis • Exemplo: Grupo de objectos para pessoas na classe pessoa • Classes correspondem a conjuntos de entidades do modelo ER.
Exemplo de Definição de Classe class empregado { /*Variáveis */string nome;string morada;date data_inicio;int salario;/* Mensagens */int salario_anual();string get_nome();string get_morada();int set-morada(string nova_morada);int tempo_na_casa();}; • Os métodos são definidos separadamente • E.g. inttempo_na_casa () { returntoday() – data_inicio;}int set-morada(string nova_morada) { morada = nova_morada;}
Herança • E.g., A classe dos clientes dum banco é semelhante à dos empregados do banco, embora hajam diferenças. • Partilham algumas variáveis e mensagens, e.g., nome and morada. • Mas há variáveis e mensagens específicas a cada uma das classes e.g., salario (só) para empregados e limite_crédito (só) para clientes. • Todo o empregado é uma pessoa: empregados é uma especialização de pessoas • clientes é também uma especialização de pessoas. • Criar classes: pessoas, empregados e clientes • Associam-se a pessoas as variáveis e mensagem aplicáveis quer a empregados quer a clientes. • As variáveis/mensagens específicas de empregados associam-se directamente a essa classe; idem para clientes
Herança (Cont.) • Colocar as classes numa hierarquia de especialização IS-A • As variáveis/mensagens pertencentes à classe pessoas são herdadas pelas classes empregados e clientes • Hierarquia de classes Semelhante às associações ISA no modelo ER
Definição de Hierarquia de Classes class pessoas{string nome;string morada:};class clientes isa pessoas {int limite_crédito;};class empregados isa pessoas {date data_início;int salário;};class gerentes isa empregados {int num_gabinete,int número_de_conta_despesas,}; . . .
Exemplo de Hierarquia de Classes (Cont.) • A lista completa de variáveis associada à classe gerente é: • num_gabinete, número_de_conta_despesas: definidos localmente • data_início, salário: herdados de empregados • nome, morada: herdados de pessoas • A herança de métodos é semelhantes. • Todo o método duma classe (e.g. pessoas) pode ser invocado em todas as subclasses (e.g. empregados ou gerentes).
Herança Múltipla • Com herança múltipla, uma classe pode ter mais do que uma superclasse. • A relação classe/subclasse é representada por um grafo dirigido acíclico (DAG) • Especialmente útil quando há objectos que podem ser definidos de formas diversas, independentes entre si. • E.g. temporário/permanente é independente de gerente/secretaria/caixa • Criar uma subclasse para cada combinação • Não é necessário criar subclasses para as combinações que não são possíveis nos dados a modelas • Cada classe herda as variáveis e métodos de todas as suas superclasses • Pode haver conflito (ambiguidade) quando uma variável/mensagem com o mesmo nome é herdada de duas superclasses distintas A e B • Não há problema se a variável/mensagem tiver sido definida numa superclasse comum a A e B • Caso contrário: • flag assinalando erro, ou • renomear variáveis (A.N e B.N), ou • escolher uma delas.
Exemplo de Herança Múltipla DAG de classes
Mais exemplos de Herança Múltipla • Conceptualmente, um objecto pode pertencer a várias subclasses de uma mesma classe • E.g. uma pessoa pode ser simultaneamente cliente e empregado do banco • Pode usar-se herança múltipla para modelizar “papéis” dum objecto • No entanto, muito sistemas obrigam a quem cada objecto esteja sempre associado a uma classe mais específica • I.e. tem que haver uma classe à qual o objecto pertence que é subclasse de todas as outras classes a que o objecto pertence • Criar subclasse, e.g. cliente_empregado, para estas combinações • Quando há muitas combinações possíveis, criar tantas subclasses pode ser difícil de gerir
Identidade de Objectos • Um objecto mantém a sua identidade mesmo que os valores de todas as suas variáveis, e mesmo os seus métodos, mudem. • A identidade de objectos neste modelo é mais forte que no modelo relacional, ou em linguagens de programação. • Identidade por: • Valor – e.g. chaves primárias no modelo relacional. • Nome – dado pelo utilizador, como nas linguagens de programação. • Built-in – a identidade está built-in no modelo de dados. • O utilizador não precisa fornecer um identificador. • É a forma de identidade usada no modelo de objectos.
Identificadores de Objectos • Os Identificadores de Objectossão usados por objectos para identificar univocamente outros objectos • São únicos: • Não podem haver dois objectos com o mesmo identificador • Cada objecto tem apenas um identificador • E.g., numa inscrição o atributo num_aluno é um identificador de um objecto de alunos (em vez da inscrição conter o próprio aluno). • Podem ser • Gerados pela base de dados • externos (e.g. número de BI) • Os identificadores gerados automaticamente: • São mais fáceis de usar • Podem ser redundantes se já existe atributo único
Objectos Compostos • No design, cada componente pode conter outros componentes • Pode ser representado com objectos que contêm outros objectos – objectos compostos. • Os múltiplos níveis de composição de objectos formam uma hierarquia de composição • Os links devem ser interpretados como is-part-of, nãois-a. • Permite que os dados sejam vistos com detalhe diferente por diferente utilizadores.
Usos do modelo • Estes conceitos de objectos podem ser usados de diversas formas: • Usar apenas como ferramenta na fase de design, e na implementação usa-se, e.g., uma base de dados relacional • Semelhante ao uso que fizemos de diagramas ER (que depois se passavam para conjunto de relações) • Incorporar as noções de objectos no sistema que manipula a base de dados: • Linguagens persistentes – generalizam (com conceitos de persistência e colecções) linguagens de programação object-oriented para permitir lidar com bases de dados. • Sistemas objecto-relacional – adiciona tipos complexos e noções de objectos a linguagem relacional.
Linguagens Persistentes • Permitem criar e armazenar objectos em bases de dados , e usá-los directamente a partir da linguagem de programação (object-oriented, claro!) • Permite que os dados sejam manipulados directamente a partir do programa • Programas em que os dados ficam de uma sessão para outra. • sendo isto feito de forma transparente para o utilizador • Desvantagens: • Dada a expressividade das linguagens, é fácil cair em erros (de programação) que violam consistência dos dados. • Tornam muito difícil (senão impossível) optimização de pesquisas. • Não suportam formulação declarativa de perguntas (como acontece em bases de dados relacionais)
Persistência de Objectos • Há várias abordagens para tornar os objectos persistentes • Persistência por Classe – declara-se que todos os objectos duma classe são persistentes; simples mas inflexível. • Persistência por Criação – estender a sintaxe de criação de objectos, para se poder especificar se são ou não persistentes. • Persistência por Marcação – todo o objecto que se pretende que persista para além da execução do programa, é marcado antes do programa terminar. • Persistência por Reachability – declara-se uma raiz de objectos persistentes; os objectos que persistem são aqueles que se conseguem atingir (directa ou indirectamente) a partir dessa raiz. • Facilita a vida ao programador, mas põe um overhead grande na base de dados • Semelhante a garbage collection usado em Java
Identidade de Objectos • A cada objecto persistente é associado um identificador. • Há vários níveis de permanência da identidade de objectos: • Intraprocedure – a identidade persiste apenas durante a execução dum procedimento • Intraprogram – a identidade persiste apenas durante a execução dum programa ou pergunta. • Interprogram – a identidade persiste duma execução dum programa para outra, mas pode mudar se a forma de armazenar os dados for alterada • Persistente – a identidade persiste entre execuções de programas e entre reorganizações de dados; esta é o nível necessário para sistemas de bases de dados de objectos.
Identidade de Objectos e Apontadores • Em linguagens object-oriented os identificadores são apontadores em memória • Apontadores persistentes – persistem para além da execução de programas • Podem ser pensados como apontadores para a base de dados • E.g. especificam identificador de ficheiro, mais offset no ficheiro • Há que organizar apontadores por forma a que estes se mantenham quando há reorganizações da base de dados
Armazenamento e Acesso Como encontrar objectos numa base de dados? • Dar nomes a objectos (e aceder por nome) • Não se generaliza para grande número de objectos. • Normalmente dão-se nomes a classes, mas não a objectos. • Armazenar colecções de objectos (e.g. a nível de classe) e permitir que os programas iterem sobre essas colecções.
Sistemas C++ Persistente • O C++ permite que se adicione suporte para objectos persistentes, sem alterar a linguagem • Declarar uma classe Persistent_Object com atributos e métodos de suporte a persistência • Usar overloading para redefinir funções e operadores standard • Template classes ajudam a construir um sistemas de tipos de suporte a colecções e tipos persistentes. • Suporte a persistência sem estender a linguagem C++ é • fácil de implementar • complexo de usar • Há sistemas C++ Persistentes já definidos e implementados
Linguagem de Definição de Objectos (ODL) da ODMG • Object Database Management Group: consórcio industrial que definiu definir standards para bases de dados orientadas para objectos • Standards de linguagens de programação persistentes • Inclui standards para C++, Smalltalk e Java • ODMG-93 • ODMG-2.0 e 3.0 (extensão do 2.0 para Java) • O standard ODMG C++ não altera a linguagem C++ • Fornece funcionalidade para persistência via template classes e class libraries
Tipos ODMG • Template class d_Ref<class> usada para referências (apontadores persistentes) • Template class d_Set<class> usada para conjuntos de objectos. • Inclui métodos como insert_element(e) e delete_element(e) • Contém outras classes como d_Bag (conjuntos com duplicados), d_List e d_Varray (arrays de tamanho variável). • d_ version de muitos tipos standard, e.g. d_Long e d_string • A interpretação destes tipos é independente da plataforma • Dados são (dinamicamente) guardados na base de dados, e não em memória.
ODMG C++ ODL: Exemplo class Branch : public d_Object { …. } class Person : public d_Object { public: d_String name; // não se deve usar String! d_String address;}; class Account : public d_Object { private: d_Long balance; public: d_Long number;d_Set <d_Ref<Customer>> owners; int find_balance(); int update_balance(int delta);};
ODMG C++ ODL: Exemplo (Cont.) class Customer : public Person {public: d_Date member_from; d_Long customer_id; d_Ref<Branch> home_branch; d_Set <d_Ref<Account>> accounts; };
Implementação de Relações • Relações entre classes são implementadas com referências • Tipos especiais de referências obrigam à adição/remoção de links inversos. • Tipo d_Rel_Ref<Class, InvRef> é uma referência para Class, onde o atributo InvRef de Class é a referência inversa. • d_Rel_Set<Class, InvRef> é usado (de forma semelhante) para conjuntos de referências • O método de afectação (=) da classe d_Rel_Ref é overloaded • Usa a definição de tipos para, automaticamente, encontrar e actualizar o link inverso • Liberta o programador desta tarefa (complexa) • Elimina a possibilidade de links inconsistentes • O mesmo acontece para os métodos insert_element() e delete_element() da classe d_Rel_Set
Implementação de Relações: Exemplo extern const char _owners[ ], _accounts[ ]; class Account : public d_Object { …. d_Rel_Set <Customer, _accounts> owners;} class Customer : public Person { …. d_Rel_Set <Account, _owners> accounts;} // .. Como não se podem usar strings em templates …const char _owners= “owners”;const char _accounts= “accounts”;
Linguagem de Manipulação de Objecto (OML) ODMG C++ • Usa versões persistentes de operadores C++ d_Ref<Account> account = new(bank_db, “Account”) Account; • Guarda o objecto na base de dados, em vez de na memória. • O segundo argumento (“Account”) denota o nome usado na base de dados. • O operador -> quando aplicado a d_Ref<Account> começa por carregar o objecto em memória (se não estiver já lá) antes de aplicar a desreferenciação usual do C++.
ODMG C++OML: Funções • A classe d_Database fornece métodos para • Abrir um base de dados: open(databasename) • Dar nomes a objectos: set_object_name(object, name) • Procurar objectos por nome: lookup_object(name) • Renomear objectos: rename_object(oldname, newname) • Fechar um base de dados close() • A classe d_Object é herdada por todas as classes persistentes. • Tem métodos para guardar e apagar objectos • O método mark_modified() tem que ser chamado antes dum objecto ser modificado. • É automaticamente chamado sempre que um objecto é criado
ODMG C++ OML: Exemplo int create_account_owner(String name, String Address){ Database bank_db.obj;Database * bank_db= & bank_db.obj;bank_db =>open(“Bank-DB”);d.Transaction Trans;Trans.begin();d_Ref<Account> account = new(bank_db) Account;d_Ref<Customer> cust = new(bank_db) Customer;cust->name = name;cust->address = address;cust->accounts.insert_element(account);... Código para inicializar outros atributosTrans.commit(); }
ODMG C++ OML (Cont.) • Os objectos de uma classe são mantidos automaticamente na base de dados. • Para aceder a objectos duma classe:d_Extent<Customer> customerExtent(bank_db); • A classe d_Extent tem o métodod_Iterator<T> create_iterator()para criar um iterador sobre os objectos duma classe • Também fornece o método select(pred) que devolve um iterador sobre objectos que satisfazem um dado predicado pred. • Colecções (conjuntos, listas etc.) também fornecem o método create_iterator() method.
ODMG C++ OML: Exemplo de Iteradores int print_customers() {Database bank_db_obj;Database * bank_db = &bank_db_obj;bank_db->open (“Bank-DB”);d_Transaction Trans; Trans.begin ();d_Extent<Customer> all_customers(bank_db);d_Iterator<d_Ref<Customer>> iter;iter = all_customers–>create_iterator();d_Ref <Customer> p; while{iter.next (p)) print_customer (p); // Função definida noutro local Trans.commit(); }
Linguagem de Perguntas a Objecto (OQL) ODMG C++ • A linguagem declarativa OQL, parece-se com o SQL • Construir uma string com a pergunta e executar para obter um conjunto (bag pois pode conter duplicados) com os resultados d_Set<d_Ref<Account>> result;d_OQL_Query q1("select a from Customer c, c.accounts a where c.name=‘Jones’ and a.find_balance() > 100");d_oql_execute(q1, result);
Java Persistente • O ODMG-3.0 define extensão ao Java para persistência • Como o Java não suporta templates, tem que se estender a linguagem • Usa persistência por reachability • Coincide com o mecanismo de garbage collection do Java • Só um tipo de apontadores (para objectos persistentes e não persistentes) • Estar na base de dados ou em memória, é transparente para o programador • Uma classe é tornada persistente, executando um pós-processador sobre o código gerado pelo compilador do Java (versus pré-processador usado no C++) • Define tipos de colecções DSet, DBag, DList, etc. • Usa iteradores do Java