Incompatibilidade de impedância relacional de objeto - Object–relational impedance mismatch

A incompatibilidade de impedância objeto-relacional é um conjunto de dificuldades conceituais e técnicas que são frequentemente encontradas quando um sistema de gerenciamento de banco de dados relacional (RDBMS) está sendo servido por um programa aplicativo (ou vários programas aplicativos) escrito em uma linguagem ou estilo de programação orientada a objetos , principalmente porque os objetos ou definições de classe devem ser mapeados para tabelas de banco de dados definidas por um esquema relacional.

O termo incompatibilidade de impedância relacional de objeto é derivado do termo de engenharia elétrica casamento de impedância .

Incompatibilidades

Objetos (instâncias) referenciam uns aos outros e, portanto, formam um gráfico no sentido matemático (uma rede incluindo loops e ciclos). Os esquemas relacionais são, em contraste, tabulares e baseados na álgebra relacional , que define tuplas heterogêneas vinculadas (agrupamentos de campos de dados em uma "linha" com tipos diferentes para cada campo).

Conceitos orientados a objetos

Encapsulamento

Os programas orientados a objetos são projetados com técnicas que resultam em objetos encapsulados , cuja representação interna pode ser ocultada. Em uma estrutura orientada a objetos, espera-se que as propriedades subjacentes de um determinado objeto não sejam expostas a nenhuma interface fora daquela implementada junto com o objeto. No entanto, a maioria das abordagens de mapeamento objeto-relacional expõe o conteúdo subjacente de um objeto para interagir com uma interface que a implementação do objeto não pode especificar. Conseqüentemente, esse mapeamento objeto-relacional viola o encapsulamento do objeto, uma vez que muitos mapeadores objeto-relacional geram automaticamente campos públicos correspondentes às colunas do banco de dados. Alguns frameworks usam técnicas de metaprogramação, evitando assim a violação do encapsulamento.

Acessibilidade

No pensamento relacional, o acesso "privado" versus "público" é relativo à necessidade. No modelo orientado a objetos (OO), é uma característica absoluta do estado dos dados. Os modelos relacional e OO freqüentemente têm conflitos sobre relatividade versus absolutismo de classificações e características.

Interface, classe, herança e polimorfismo

Em um paradigma orientado a objetos, os objetos têm interfaces que, juntas, fornecem o único acesso às partes internas desse objeto. O modelo relacional, por outro lado, utiliza variáveis ​​de relação derivadas ( visualizações ) para fornecer perspectivas e restrições variadas para garantir a integridade. Da mesma forma, os conceitos OOP essenciais para classes de objetos, herança e polimorfismo , não são suportados por sistemas de banco de dados relacionais.

Mapeamento para conceitos relacionais

Um mapeamento adequado entre os conceitos relacionais e os conceitos orientados a objetos pode ser feito se as tabelas do banco de dados relacional estiverem vinculadas a associações encontradas na análise orientada a objetos .

Diferenças de tipo de dados

Uma grande incompatibilidade entre as linguagens relacionais e OO existentes são as diferenças do sistema de tipos. O modelo relacional proíbe estritamente atributos por referência (ou ponteiros ), enquanto as linguagens OO adotam e esperam comportamento por referência. Os tipos escalares e sua semântica de operador podem ser muito diferentes entre os modelos, causando problemas no mapeamento.

Por exemplo, a maioria dos sistemas SQL oferece suporte a tipos de string com agrupamentos variados e comprimentos máximos restritos (tipos de texto abertos tendem a prejudicar o desempenho), enquanto a maioria das linguagens OO considera agrupamento apenas como um argumento para classificar rotinas e strings são intrinsecamente dimensionadas para a memória disponível. Um exemplo mais sutil, mas relacionado, é que os sistemas SQL geralmente ignoram o espaço em branco à direita em uma string para fins de comparação, enquanto as bibliotecas de string OO não. Normalmente não é possível construir novos tipos de dados como uma questão de restringir os valores possíveis de outros tipos primitivos em uma linguagem OO.

Diferenças estruturais e de integridade

Outra incompatibilidade tem a ver com as diferenças nos aspectos estruturais e de integridade dos modelos contrastados. Em linguagens OO, os objetos podem ser compostos de outros objetos - muitas vezes em um alto grau - ou se especializar a partir de uma definição mais geral. Isso pode tornar o mapeamento para esquemas relacionais menos direto. Isso ocorre porque os dados relacionais tendem a ser representados em um conjunto nomeado de variáveis ​​de relação globais não aninhadas. As próprias relações, sendo conjuntos de tuplas em conformidade com o mesmo cabeçalho (consulte cálculo relacional de tupla ), não têm uma contraparte ideal em linguagens OO. As restrições em linguagens OO geralmente não são declaradas como tal, mas se manifestam como uma lógica de proteção de levantamento de exceção em torno do código que opera em dados internos encapsulados. O modelo relacional, por outro lado, exige restrições declarativas em tipos escalares, atributos, variáveis ​​de relação e o banco de dados como um todo.

Diferenças manipulativas

As diferenças semânticas são especialmente aparentes nos aspectos manipulativos dos modelos contrastados, no entanto. O modelo relacional tem um conjunto intrínseco, relativamente pequeno e bem definido de operadores primitivos para uso na consulta e manipulação de dados, enquanto as linguagens OO geralmente lidam com consulta e manipulação por meio de acesso personalizado ou de nível inferior, caso e físico -operações imperativas específicas do caminho . Algumas linguagens OO têm suporte para sublinguagens de consulta declarativa , mas como as linguagens OO normalmente lidam com listas e talvez tabelas hash , as primitivas manipulativas são necessariamente distintas das operações baseadas em conjunto do modelo relacional.

Diferenças transacionais

Os aspectos de simultaneidade e transação também são significativamente diferentes. Em particular, as transações , a menor unidade de trabalho executada por bancos de dados, são muito maiores em bancos de dados relacionais do que quaisquer operações executadas por classes em linguagens OO. As transações em bancos de dados relacionais são conjuntos limitados dinamicamente de manipulações de dados arbitrários, enquanto a granularidade das transações em uma linguagem OO está normalmente no nível de atribuições individuais para campos de tipo primitivo. Em geral, as linguagens OO não têm analogia de isolamento ou durabilidade, portanto, atomicidade e consistência são garantidas apenas ao gravar em campos desses tipos primitivos.

Resolvendo incompatibilidade de impedância

Trabalhar em torno do problema de incompatibilidade de impedância para programas orientados a objetos começa com o reconhecimento das diferenças nos sistemas lógicos específicos que estão sendo empregados. A incompatibilidade é então minimizada ou compensada.

Arquiteturas alternativas

O problema de incompatibilidade de impedância relacional de objeto não é um problema universal entre OO e bancos de dados. Como o nome sugere, esse problema de impedância ocorre apenas com bancos de dados relacionais . A solução mais comum para esse problema é usar um banco de dados alternativo, como NoSQL ou banco de dados XML .

Minimização

Houve algumas tentativas de construir sistemas de gerenciamento de banco de dados orientados a objetos (OODBMS) que evitariam o problema de incompatibilidade de impedância. Eles têm tido menos sucesso na prática do que bancos de dados relacionais, no entanto, em parte devido às limitações dos princípios OO como base para um modelo de dados. Tem havido pesquisas realizadas para estender as capacidades semelhantes a bancos de dados de linguagens OO por meio de noções como memória transacional .

Uma solução comum para o problema de incompatibilidade de impedância é colocar em camadas o domínio e a lógica da estrutura. Nesse esquema, a linguagem OO é usada para modelar certos aspectos relacionais em tempo de execução, em vez de tentar o mapeamento mais estático. Os frameworks que empregam esse método normalmente terão um análogo para uma tupla, geralmente como uma "linha" em um componente de "conjunto de dados" ou como uma classe de "instância de entidade" genérica, bem como um análogo para uma relação. As vantagens desta abordagem podem incluir:

  • Caminhos simples para construir estruturas e automação em torno do transporte, apresentação e validação de dados de domínio.
  • Tamanho de código menor; tempos de compilação e carregamento mais rápidos.
  • Capacidade de alteração dinâmica do esquema .
  • Evita os problemas de espaço de nome e incompatibilidade semântica.
  • Verificação de restrição expressiva
  • Nenhum mapeamento complexo necessário

As desvantagens podem incluir:

  • Falta de verificações de "segurança" do tipo estático. Acessadores digitados às vezes são utilizados como uma forma de atenuar isso.
  • Possível custo de desempenho de construção e acesso em tempo de execução.
  • Incapacidade de utilizar nativamente aspectos OO exclusivos, como polimorfismo .

Compensação

A mistura de níveis de discurso dentro do código do aplicativo OO apresenta problemas, mas existem alguns mecanismos comuns usados ​​para compensar. O maior desafio é fornecer suporte de framework, automação de manipulação de dados e padrões de apresentação, dentro do nível de discurso em que os dados do domínio estão sendo modelados. Para resolver isso, reflexão e / ou geração de código são utilizadas. A reflexão permite que o código (classes) sejam endereçados como dados e, assim, fornece automação do transporte, apresentação, integridade, etc. dos dados. A geração aborda o problema abordando as estruturas de entidade como entradas de dados para ferramentas de geração de código ou linguagens de metaprogramação, que produzem as classes e a infraestrutura de suporte em massa. Ambos os esquemas podem ainda estar sujeitos a certas anomalias onde esses níveis de discurso se fundem. Por exemplo, classes de entidade geradas normalmente terão propriedades que mapeiam para o domínio (por exemplo, Nome, Endereço), bem como propriedades que fornecem gerenciamento de estado e outra infraestrutura de estrutura (por exemplo, IsModified).

Contenção

Foi argumentado, por Christopher J. Date e outros, que um SGBD verdadeiramente relacional não representaria tal problema, já que domínios e classes são essencialmente a mesma coisa. Um mapeamento nativo entre classes e esquemas relacionais é um erro de design fundamental; e que tuplas individuais dentro de uma tabela de banco de dados (relação) devem ser vistas como estabelecendo relacionamentos entre entidades; não como representações para as próprias entidades complexas. No entanto, essa visão tende a diminuir a influência e o papel da programação orientada a objetos, usando-a como pouco mais do que um sistema de gerenciamento de tipo de campo.

A incompatibilidade de impedância está na programação entre os objetos do domínio e a interface do usuário . Interfaces de usuário sofisticadas, para permitir que operadores, gerentes e outros não-programadores acessem e manipulem os registros no banco de dados, geralmente requerem conhecimento íntimo sobre a natureza dos vários atributos do banco de dados (além do nome e tipo). Em particular, é considerada uma boa prática (do ponto de vista da produtividade do usuário final) projetar interfaces de usuário de modo que a IU evite que transações ilegais (aquelas que causam a violação de uma restrição de banco de dados ) sejam inseridas; fazer isso requer que muito da lógica presente nos esquemas relacionais seja duplicada no código.

Certos frameworks de desenvolvimento de código podem aproveitar certas formas de lógica que são representadas no esquema do banco de dados (como restrições de integridade referencial), de modo que tais problemas sejam tratados de forma genérica e padrão por meio de rotinas de biblioteca, em vez de código ad hoc escrito em um caso -por caso.

Tem sido argumentado que o SQL , devido a um conjunto muito limitado de tipos de domínio (e outras supostas falhas), torna difícil a modelagem adequada de objetos e domínios; e que o SQL constitui uma interface com muitas perdas e ineficiente entre um SGBD e um programa de aplicação (seja escrito em um estilo orientado a objetos ou não). No entanto, o SQL é atualmente a única linguagem comum de banco de dados amplamente aceita no mercado; o uso de linguagens de consulta específicas do fornecedor é visto como uma prática ruim, quando evitável. Outras linguagens de banco de dados, como Business System 12 e Tutorial D , foram propostas; mas nenhum deles foi amplamente adotado por fornecedores de DBMS.

Nas versões atuais dos SGBDs "objeto-relacionais" convencionais, como Oracle e Microsoft SQL Server, o ponto acima pode não ser um problema. Com esses motores, a funcionalidade de um determinado banco de dados pode ser arbitrariamente estendida por meio de código armazenado (funções e procedimentos) escrito em uma linguagem OO moderna (Java para Oracle e uma linguagem Microsoft .NET para SQL Server), e essas funções podem ser chamadas por sua vez, em instruções SQL de maneira transparente: ou seja, o usuário não sabe nem se importa se essas funções / procedimentos não faziam originalmente parte do mecanismo de banco de dados. Paradigmas modernos de desenvolvimento de software são totalmente suportados: assim, pode-se criar um conjunto de rotinas de biblioteca que podem ser reutilizadas em vários esquemas de banco de dados.

Esses fornecedores decidiram oferecer suporte à integração de linguagem OO no back-end do DBMS porque perceberam que, apesar das tentativas do comitê ISO SQL-99 de adicionar construções procedimentais ao SQL, o SQL nunca terá o rico conjunto de bibliotecas e estruturas de dados que os programadores de aplicativos de hoje aceitam, e é razoável aproveitar isso o mais diretamente possível, em vez de tentar estender a linguagem SQL principal. Conseqüentemente, a diferença entre "programação de aplicativo" e "administração de banco de dados" agora está confusa: a implementação robusta de recursos, como restrições e gatilhos, pode muitas vezes exigir um indivíduo com habilidades de programação DBA / OO duplas ou uma parceria entre indivíduos que combinem essas habilidades . Esse fato também está relacionado à questão da "divisão de responsabilidades" abaixo.

Alguns, no entanto, apontariam que essa controvérsia é discutível devido ao fato de que: (1) RDBMSes nunca foram destinados a facilitar a modelagem de objetos, e (2) SQL geralmente só deve ser visto como uma interface "com perdas" ou "ineficiente" linguagem quando se está tentando alcançar uma solução para a qual os RDBMSs não foram projetados. O SQL é muito eficiente em fazer o que foi projetado para fazer, ou seja, consultar, classificar, filtrar e armazenar grandes conjuntos de dados. Alguns apontariam, adicionalmente, que a inclusão da funcionalidade de linguagem OO no back-end simplesmente facilita a má prática arquitetônica, pois admite lógica de aplicativo de alto nível na camada de dados, antitética ao RDBMS.

Aqui, a cópia "canônica" do estado está localizada. O modelo de banco de dados geralmente assume que o sistema de gerenciamento de banco de dados é o único repositório de estado com autoridade sobre a empresa; quaisquer cópias desse estado mantidas por um programa aplicativo são apenas isso - cópias temporárias (que podem estar desatualizadas, se o registro do banco de dados subjacente foi posteriormente modificado por uma transação). Muitos programadores orientados a objetos preferem ver as representações na memória dos próprios objetos como os dados canônicos e ver o banco de dados como um armazenamento de apoio e mecanismo de persistência.

Outro ponto de discórdia é a divisão adequada de responsabilidade entre programadores de aplicativos e administradores de banco de dados (DBA). Frequentemente, as mudanças necessárias no código do aplicativo (para implementar um novo recurso ou funcionalidade solicitado) exigem mudanças correspondentes na definição do banco de dados; na maioria das organizações, a definição do banco de dados é de responsabilidade do DBA. Devido à necessidade de manter um sistema de banco de dados de produção 24 horas por dia, muitos DBAs relutam em fazer alterações nos esquemas do banco de dados que consideram gratuitas ou supérfluas e, em alguns casos, recusam-se abertamente a fazê-lo. O uso de bancos de dados de desenvolvimento (além de sistemas de produção) pode ajudar um pouco; mas quando o aplicativo recém-desenvolvido "entrar no ar", o DBA precisará aprovar quaisquer alterações. Alguns programadores veem isso como intransigência; no entanto, o DBA é frequentemente considerado responsável se qualquer alteração na definição do banco de dados causar perda de serviço em um sistema de produção - como resultado, muitos DBAs preferem conter alterações de design no código do aplicativo, onde defeitos de design são muito menos prováveis ​​de ter consequências catastróficas .

Em organizações com um relacionamento não disfuncional entre DBAs e desenvolvedores, porém, o problema acima não deve se apresentar, já que a decisão de alterar um esquema de banco de dados ou não seria impulsionada apenas pelas necessidades de negócios: um novo requisito para persistir dados adicionais ou um o aumento de desempenho de um aplicativo crítico desencadearia uma modificação do esquema, por exemplo.

Diferenças filosóficas

As principais diferenças filosóficas entre os modelos OO e relacionais podem ser resumidas da seguinte forma:

  • Interfaces declarativas vs. imperativas  - o pensamento relacional tende a usar dados como interfaces, não comportamento como interfaces. Portanto, tem uma inclinação declarativa na filosofia de design em contraste com a inclinação comportamental do OO. (Alguns proponentes relacionais sugerem o uso de gatilhos, procedimentos armazenados, etc. para fornecer um comportamento complexo, mas este não é um ponto de vista comum).
  • Limite de esquema  - os objetos não precisam seguir um "esquema pai" para os atributos ou acessores que um objeto possui, enquanto as linhas da tabela devem seguir o esquema da entidade. Uma determinada linha deve pertencer a uma e apenas uma entidade. A coisa mais próxima em OO é a herança, mas geralmente é em forma de árvore e opcional. Os sistemas de banco de dados dinâmicos que permitem colunas ad hoc podem relaxar o limite do esquema, mas tais sistemas são raros atualmente ou sua classificação como "relacional" está em questão.
  • Regras de acesso  - Em bancos de dados relacionais, os atributos são acessados ​​e alterados por meio de operadores relacionais predefinidos, enquanto OO permite que cada classe crie sua própria interface e práticas de alteração de estado. O ponto de vista do "substantivo automanipável" de OO dá independência a cada objeto que o modelo relacional não permite. Este é um debate "padrões versus liberdade local". OO tende a argumentar que os padrões relacionais limitam a expressividade, enquanto os proponentes relacionais sugerem que a aderência à regra permite um raciocínio matemático mais abstrato, integridade e consistência de design.
  • Relação entre substantivos e verbos  - OO encoraja uma associação estreita entre verbos (ações) e os substantivos (entidades) sobre os quais as operações operam. A entidade fortemente ligada resultante contendo substantivos e verbos é normalmente chamada de classe ou, em análise OO, de conceito . Os projetos relacionais geralmente não presumem que haja algo natural ou lógico nessas associações estreitas (fora dos operadores relacionais).
  • Identidade do objeto  - Objetos (exceto os imutáveis) são geralmente considerados como tendo uma identidade única; dois objetos que por acaso têm o mesmo estado em um determinado momento não são considerados idênticos. As relações, por outro lado, não têm um conceito inerente a esse tipo de identidade. Dito isso, é uma prática comum fabricar "identidade" para registros em um banco de dados por meio do uso de chaves candidatas globalmente exclusivas ; embora muitos considerem isso uma prática ruim para qualquer registro de banco de dados que não tenha uma correspondência direta com uma entidade do mundo real. (Relações, como objetos, podem usar chaves de domínio se existirem no mundo externo para fins de identificação). Os sistemas relacionais, na prática, buscam e apoiam técnicas de identificação "permanentes" e inspecionáveis, enquanto as técnicas de identificação de objetos tendem a ser transitórias ou situacionais.
  • Normalização  - as práticas de normalização relacional são freqüentemente ignoradas por projetos OO. No entanto, isso pode ser apenas um mau hábito, em vez de um recurso nativo do OO. Uma visão alternativa é que uma coleção de objetos, interligados por meio de ponteiros de algum tipo, é equivalente a um banco de dados de rede ; que, por sua vez, pode ser visto como um banco de dados relacional extremamente desnormalizado .
  • Herança de esquema  - a maioria dos bancos de dados relacionais não oferece suporte à herança de esquema. Embora tal recurso possa ser adicionado em teoria para reduzir o conflito com OOP, os proponentes relacionais são menos propensos a acreditar na utilidade de taxonomias hierárquicas e subtipulação porque tendem a ver taxonomias baseadas em conjuntos ou sistemas de classificação como mais poderosos e flexíveis do que árvores. Os defensores OO apontam que os modelos de herança / subtipagem não precisam ser limitados a árvores (embora esta seja uma limitação em muitas linguagens OO populares, como Java ), mas as soluções OO não-árvore são vistas como mais difíceis de formular do que a variação baseada em conjunto. técnicas de gerenciamento sobre um tema preferidas por relacionais. No mínimo, eles diferem das técnicas comumente usadas em álgebra relacional.
  • Estrutura vs. comportamento  - OO se concentra principalmente em garantir que a estrutura do programa seja razoável (sustentável, compreensível, extensível, reutilizável, seguro), enquanto os sistemas relacionais se concentram em que tipo de comportamento o sistema de tempo de execução resultante tem (eficiência, adaptabilidade , tolerância a falhas, vivacidade, integridade lógica, etc.). Os métodos orientados a objetos geralmente assumem que o usuário principal do código orientado a objetos e suas interfaces são os desenvolvedores de aplicativos. Em sistemas relacionais, a visão dos usuários finais sobre o comportamento do sistema às vezes é considerada mais importante. No entanto, consultas relacionais e "visualizações" são técnicas comuns para apresentar informações em configurações específicas de aplicativos ou tarefas. Além disso, o relacional não proíbe a criação de estruturas ou tabelas locais ou específicas do aplicativo, embora muitas ferramentas de desenvolvimento comuns não forneçam diretamente esse recurso, presumindo que os objetos serão usados ​​em seu lugar. Isso torna difícil saber se a perspectiva relacional declarada de não desenvolvedor é inerente à relacional ou apenas um produto da prática atual e das suposições de implementação de ferramenta.
  • Relacionamentos de conjunto vs. gráfico  - O relacionamento entre diferentes itens (objetos ou registros) tende a ser tratado de forma diferente entre os paradigmas. Os relacionamentos relacionais são geralmente baseados em expressões idiomáticas tiradas da teoria dos conjuntos , enquanto as relações de objeto tendem a expressões idiomáticas adotadas da teoria dos grafos (incluindo árvores ). Embora cada um possa representar as mesmas informações que o outro, as abordagens que fornecem para acessar e gerenciar informações são diferentes.

Como resultado da incompatibilidade de impedância objeto-relacional, é freqüentemente argumentado por partidários de ambos os lados do debate que a outra tecnologia deve ser abandonada ou reduzida em escopo. Alguns defensores do banco de dados veem as linguagens "procedimentais" tradicionais como mais compatíveis com um RDBMS do que muitas linguagens OO; ou sugerir que um estilo menos OO deva ser usado. (Em particular, argumenta-se que os objetos de domínio de longa duração no código do aplicativo não deveriam existir; quaisquer objetos que existam deveriam ser criados quando uma consulta é feita e descartados quando uma transação ou tarefa é concluída). Por outro lado, alguns defensores do OO argumentam que mecanismos de persistência mais amigáveis ​​ao OO, como OODBMS , devem ser desenvolvidos e usados, e que a tecnologia relacional deve ser eliminada gradualmente. Muitos (senão a maioria) dos programadores e DBAs não possuem nenhum desses pontos de vista; e ver a incompatibilidade de impedância objeto-relacional como um mero fato da vida com o qual a tecnologia da informação tem que lidar.

Também é argumentado que o mapeamento O / R está valendo a pena em algumas situações, mas provavelmente está exagerado: ele tem vantagens além de desvantagens. Os céticos apontam que vale a pena pensar com cuidado antes de usá-lo, pois agregará pouco valor em alguns casos.

Veja também

Referências

links externos