Bases de dados OO
Sumário
 Conceitos gerais
 Exemplo do ObjectStore)







Arquitectura
Criação de objectos
Gestão da concorrência
Colecções
Perguntas
Índices
Associações
BDOO - 0
Perguntas
 acesso navegacional versus acesso associativo (por chave, etc.)
 optimizador de perguntas minimiza o número de objectos examinados
 para obter uma colecção dos elementos que satisfazem uma dada condição
os_Collection<E> &query(
char *type_string,
char *query_string,
os_database *schema_database = 0,
char *file_name = 0,
BD da colecção ou BD
do esquema da aplicação
os_unsigned_int32 line = 0,
ficheiro fonte e
linha do erro
os_boolean dups = query_dont_preserve_duplicates
elimina duplicados
) const
Pergunta típica:
expressão-de-colecção.query(
nome-do-tipo-dos-elementos,
pergunta,
a colecção resultante é
colocada na heap: eliminar
com delete()
BD-esquema)
BDOO - 1
Exemplo de uma pergunta
os_database *people_database;
os_Set<person*> *people;
…
os_Set<person*> &teenagers=
people->query(
"person*",
"this->age >= 13 && this->age <= 19",
people_database);
os_database *people_database;
os_Set<person*> *people;
• tipo dos elementos
• uma pergunta é uma expressão de controlo;
um elemento e satisfaz o critério de selecção se a expressão
de controlo avaliar para true quando e está ligado a this
• qualquer expressão de tipo int serve, desde que
- sem variáveis, só com membros dados
- funções, só strcmp(), strcoll(), comparadores com função
de ordem registada e funções que retornem um apontador
ou tipo aritmético e não tenham argumentos para além de this
…
os_Set<person*> &teenagers=
people->query(
"person*",
• this está implícito para os membros da classe
age >= 13 && age <= 19",
people_database);
BDOO - 2
Outras formas de pergunta
 elemento isolado (optimização)
E query_pick(char*, char*, os_database*) const
os_database *parts_database;
os_Set<part*> *parts;
…
part *part_number_411=
parts->query_pick(
query_pick <=> query + os_collection::pick()
"part*",
"part_number == 411",
parts_database);
 perguntas existenciais: forma semelhante, mas devolvem um os_int32, em vez de
elementos
BDOO - 3
Perguntas encaixadas
 nas três formas de pergunta é possível introduzir subperguntas
expressão-de-colecção[:expressão-int:]
expressão-de-colecção dá
um elemento da expressão principal e expressão-int o
critério de selecção para a pergunta encaixada
expressão-de-colecção[%expressão-int%]
//nesta forma só dá um elemento
 processamento de subperguntas semelhante, excepto que a colecção resultante é
convertida para inteiro; resultado vazio,dá falso, não vazio, verdade
os_database *db;
os_Set<part*> &a_set …;
a_set->query("part*", "children[:1:]",db);
• todos os componentes com filhos:
-
para cada elemento e em a_set tem-se que
e->children[:1:] devolve e->children o qual é
convertido para true se não estiver vazio e
portanto e fica no resultado
• a_set->query("part*", "!children[:1:]",db);
os_database *db;
part *a_part;
a_part->(descendents()->query("part*",
"children[:1:] &&
!children[:children:]",db);
• os componentes cujos filhos são
todos primitivos
• componentes sem filhos
BDOO - 4
Perguntas pré-analisadas
 partes da avaliação de uma pergunta
• análise da expressão
• ligação das variáveis livres e das referências de função, i.e., todos os identificadores
excepto membros
• interpretação efectiva da pergunta ligada
 se a mesma pergunta for executada várias vezes, vale a pena guardar o resultado da
análise num objecto da classe os_coll_query (pode ser criado com create, create_pick,
create_exists) pois a análise é uma fase pesada.
const os_coll_query &age_range_query=
—analisada
os_coll_query::create(
"person*",
"age >= *(int*)min_age_ptr && age <= *(int*)max_age_ptr,
db1);
int teenage_min_age=13, teenage_max_age =19;
os_bound_query teenage_range_query(
age_range_query.
—ligada
(os_keyword_arg("min_age_ptr", &teenage_min_age),
os_keyword_arg("max_age_ptr", &teenage_max_age) ) );
people.query(teenage_range_query);
— invocação
BDOO - 5
Bases de dados OO
Sumário
 Conceitos gerais
 Exemplo do ObjectStore)







Arquitectura
Criação de objectos
Gestão da concorrência
Colecções
Perguntas
Índices
Associações
BDOO - 6
Índices
 os índices servem para optimizar certos caminhos de acesso, obtendo comportamentos
melhores que linear nos casos em que é possível
a_set->query_pick("part*", "part_number==411", db1);
 especificar que se pretende o índice no conjunto a_set e que a chave do índice é o
membro part_number — usar os_collection::add_index();
• os_Set<part*> *a_set;
os_index_path &key_spec =
os_index_path::create("part*","part_number", db1);
a_set->add_index(key_spec




• para remover o índice: drop_index()
• qualquer acesso por este caminho resulta mais eficiente
caminhos que terminem em cadeias originam índices com a cadeia na chave
os outros caminhos que terminam em apontadores são optimizados por endereço
os índices têm que ser mantidos, quando há alterações de elementos que estão no
respectivo caminho — atrasa as actualizações; acelera as pesquisas, pelo que só se deve
usar índices quando não há muitas modificações
pode-se adicionar e eliminar índices durante a vida da colecção, conforme a conveniência;
o optimizador de perguntas adapta-se dinamicamente
BDOO - 7
Opções nos índices
 para testar a existência de índices (dois índices com o mesmo caminho são o mesmo)
• if(a_set->has_index(key_spec)) ...
• os_collection::get_indexes()
 podem ser utilizados caminhos complexos
• os_index_path::create("part*","(*responsible_engineers)[]->emp_id)
 o índice de número de componente para componente é implementado via tabelas de
dispersão — fica desordenado
 havendo pesquisas por gama em número de componente, convém que o índice esteja
ordenado — especificar a opção
a_set->add_index(a_path, os_index_path::ordered)
para implementar em árvores-B
 outras opções de criação incluem:
• allow_duplicates, no_duplicates, signal_duplicates — tratamento dos repetidos
• copy_key, point_to_key — tratamento da chave
BDOO - 8
Manutenção dos índices
 alterações nos objectos obrigam a corrigir os índices
 manutenção pode ser automática, semimanual ou manual;
 para a manutenção automática (e também para usar membros função nos caminhos) é
necessário adicionar no início da classe um membro especial:
• membro do tipo os_backptr (basta um por classe; pode ser herdado, simples)
class part{
public:
…
os_backptr b;
int id;
department *dept;
…
part();
~part(); }
• se membro declarado normalmente como value-type member-name é para indexar, usase a macro
os_indexable_member(class-name, member-name, value-type) member-name
• tem que se instanciar os corpos das respectivas funções
os_indexable_body(class-name, member-name, value-type,backptr-spec);
os_index(class,backptr-member); // = backptr-spec
BDOO - 9
Notas
 CUIDADO: nas macros não meter espaços junto aos argumentos
 o valor real de um membro dado indexável é um objecto contentor especial, que encapsula
o valor aparente
REAL
APARENTE
contentor
int
a_part->id.setvalue(411)
a_part->id = 411
f(a_part->id.getvalue())
f(a_part->id)
 conclusão: a manutenção dos índices fica praticamente automática; só nos locais onde se
perde a informação de tipo (printf) é necessário forçar o cast
printf("The idis %d \n", (int)(a_part->id));
 a manutenção dos índices nas inserções e remoções de colecções é automática
 a manutenção manual está a cargo de funções como make_link() e break_link()
BDOO - 10
Bases de dados OO
Sumário
 Conceitos gerais
 Exemplo do ObjectStore)







Arquitectura
Criação de objectos
Gestão da concorrência
Colecções
Perguntas
Índices
Associações
BDOO - 11
Integridade
A manutenção da integridade dos dados é um dos serviços mais valiosos de um SGBD
Exemplo estruturas de dados com nós
Lista duplamente ligada
Árvore
Grafo
• como representar em termos de classes?
• os três exemplos podem ser vistos como casos particulares da representação de uma
relação binária entre nós
BDOO - 12
Membros inversos
 representação da relação binária através da inclusão de um membro em cada uma das
classes envolvidas na associação
• o problema é manter a consistência, pois a informação dos dois lados não é
independente: os dois membros representam a relação e a sua inversa
•
ObjectStore garante a manutenção automática do sincronismo entre membros
declarados como inversos
• o código que usa membros inversos está escrito como se eles fossem normais
 a manutenção dos inversos é feita através de uma classe embebida que encapsula os
apontadores, de forma a interceptar as respectivas alterações e manter a integridade
referencial
• é necessário incluir os ficheiros ostore.hh, coll.hh, relat.hh
• existem três interfaces para a classe associação(ex: componentes e peças)
- other = some->container; // membro de dados simples
- other = some->container.getvalue(); // associação
- other = some->get_container(); // funcional
- some->container = other; // membro de dados simples
- some->container.setvalue(other); // associação
- some->set_container(other); // funcional
BDOO - 13
Definição das associações
 definem-se as associações e usam-se macros para os respectivos corpos
• definições
- os_relationship_1_1 um-para-um
- os_relationship_1_m um-para-muitos
- os_relationship_m_1 muitos-para-um
- os_relationship_m_m muitos-para-muitos
• macros para os corpos respectivos
- os_rel_1_1_body um-para-um
- os_rel_1_m_body um-para-muitos
- os_rel_m_1_body muitos-para-um
- os_rel_m_m_body muitos-para-muitos
• argumentos: classe do membro, membro, classe do membro inverso, membro inverso,
tipo do membro (as macros dos corpos não têm este argumento)
os_relationship_1_m(person, employer, company, employees, company*) employer
 as alterações num membro nem sempre provocam alterações no inverso: só nestes casos é
obrigatório:
- associação um-um
- associação um-muitos, colecção não aceita duplicados
- associação muitos-muitos, ambas as colecções permitem (proibem) duplicados
BDOO - 14
Associações um-um
Lista duplamente ligada: cada nó tem um seguinte e um anterior, declarados com inversos
#include <ostore/relat.hh>
class node
{
public:
os_relationship_1_1(node,next,node,previous,node*) next;
os_relationship_1_1(node,previous,node, next,node*) previous;
node(){};
};
os_rel_1_1_body(node,next,node,previous);
os_rel_1_1_body(node, previous,node, next);
main(){
objectstore::initialize();
os_collection::initialize();
node* n1 = new node();
node* n2 = new node();
n1->next = n2; //actualiza auto. n2->previous
printf("n1 (%x) --> (%x)\n",n1,n1.next.get_value();
printf("n2 (%x) --> (%x)\n",n2,n2.previous.get_value();
BDOO - 15
Comentários
 responsabilidade: sobrecarga do operador =() e dos operadores de coerção
n1->next = n2->next;
é interpretado como
n1->next.operator=(n2->next.operator node*() );
printf precisa de coerção, porque não tem informação prototípica nos argumentos
printf("The value is %x\n, (node*)n1->next)
BDOO - 16
Associações muitos-um
Árvore: cada nó tem um só pai (excepto a raiz) e zero ou mais filhos
#include <ostore/relat.hh>
class node
{
public:
os_relationship_1_m(node,parent,node,children,node*) parent;
os_relationship_m_1(node,children,node, parent,os_collection) children;
node(){};
};
os_rel_1_m_body( node,parent,node,children );
os_rel_m_1_body( node,children,node, parent );
main(){
objectstore::initialize();
os_collection::initialize();
node* n1 = new node();
node* n2 = new node();
n1->children.insert( n2); //actualiza auto. n2->parent
// daria o mesmo ter escrito n2->parent=n1
BDOO - 17
Download

ObjectStore 4