Image Image Image Image Image
Scroll to Top

Topo

tabelas

05

jan
2012

Sem Comentários

Em Blog
SQL

Por Allison

Uma tabela de relacionamento de muitos para muitos – resolvendo o problema de relação de exclusão

Em 05, jan 2012 | Sem Comentários | Em Blog, SQL | Por Allison

Começarei definindo o relacionamento de Muitos para Muitos MySQL (Experts podem pular para o próximo parágrafo).

O que é um relacionamento de Muitos para Muitos MySQL

Um relacionamento de Muitos para Muitos MySQL é um relacionamento que é multi-valorado em ambas as direções.

Esse tipo de relacionamento é auxiliado pelo uso de uma tabela de ligação. Por exemplo, uma Pergunta (Question) pode ter mais de uma Categoria (Categorie), e uma Categoria pode ter mais de uma Pergunta.

CREATE TABLE link (
   Question_id int unsigned NOT NULL,
   Category varchar(20),
   PRIMARY KEY  (`Question_id `,` Category`),
   KEY `category_question` (`Category`,`Question_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

+-------------+---------------+
| Question_id | Category      |
+-------------+---------------+
|  1          | Animals       |
|  1          | Business      |
|  1          | Vehicles      |
|  2          | Animals       |
|  3          | Business      |
|  3          | Vehicles      |
|  4          | Animals       |
|  4          | Vehicles      |
|  5          | Business      |
+-------------+---------------+

Essa é uma tabela de ligação chamada link, que nos ajuda a juntar relacionamentos entre as duas tabelas, Perguntas e Categorias.

Como podemos ver, essa tabela está refletindo um relacionamento de muitos para muitos (a pergunta 1 tem as categorias Animais, Negócios e Veículos – ‘Animals, Business and Vehicles’. A categoria Animais tem as perguntas 1, 2 e 4).

O que é o problema de relação de exclusão?

Dada uma tabela de relacionamento de muitos para muitos, como você é capaz de selecionar linhas que não tenham um relacionamento específico? Em termos do exemplo pergunta-categoria, essa pergunta é traduzida no seguinte:

Como você consegue selecionar (digamos as primeiras mil) perguntas que não têm a categoria Negócios. No nosso exemplo, queremos somente que os Question_id 2 e 4 sejam retornados.

Uma solução ruim

Uma solução ruim seria:

SELECT
DISTINCT Question_id
FROM
link
WHERE
Category <> "Business"
ORDER BY
Question_id DESC
LIMIT
1000;

Essa consulta irá funcionar se uma pergunta somente for permitida uma categoria. No nosso caso, como uma pergunta tem pelo menos uma categoria, desde que uma pergunta esteja associada à outra categoria que não seja Business, ela retornará. Portanto, o resultado dessa consulta é Question_id: 1, 2, 3, e 4 , que não satisfaz a relação de exclusão.

Primeira solução

SELECT
DISTINCT Question_id
FROM
link
WHERE
Question_id NOT IN (SELECT Question_id FROM link WHERE Category="Business")
ORDER BY
Question_id DESC
LIMIT
1000;

A consulta dependente interna (SELECT Question_id FROM link WHERE Category<>”Business”) tem um problema de desempenho – ela será executada pela menos mil vezes e, se ela não for rápida, os atrasos são multiplicados por um número que é, no mínimo, 1.000. Quando o método de acesso (o type field no EXPLAIN statement output) é index_subquery, um index de pesquisa de otimização é usado e um monte de sobrecarga é evitada.

Quando é ampla, a sub query está sendo reexecutada, como é feita para cada linha. Você deve verificar seus . You must check your EXPLAIN details.

Segunda solução

CREATE TEMPORARY TABLE not_wanted_Question_id (
UNIQUE KEY(Question_id)
) ENGINE=MEMORY
SELECT
DISTINCT Question_id
FROM
link
WHERE
Category="Business";

SELECT
DISTINCT link.Question_id
FROM
link
LEFT JOIN
not_wanted_Question_id nw ON (link.Question_id = nw.Question_id)
WHERE
nw.Question_id is NULL
ORDER BY
link.Question_id DESC
LIMIT
1000;

DROP TABLE not_wanted_Question_id;

O problema de execução de consultas internas múltiplas é reduzido a uma pesquisa uma única chave dentro de uma tabela na memória, que é basicamente uma pesquisa hash e é muito rápida. No entanto, a construção de perguntas indesejadas pode sair caro para tabelas grandes. Note que criar a tabela, selecionar e então soltar devem ser todos feitos juntos, para toda vez que você precisar dos resultados.

Terceira solução (a melhor em desempenho)

Esta é minha melhor solução para esse problema e com melhor desempenho para tabelas pesadas:

SELECT
 Question_id ,
 SUM(IF (Category="Business", 1, 0)) AS exclude
 FROM
 link
 GROUP BY
 Question_id DESC
 HAVING
 exclude=0
 LIMIT
 10000;

Isso funciona muito bem no nosso caso, porque temos um index no Question_id e colunas de categorias. A função SUM está contando o número de ocorrências indesejadas de categoria para cada Question_id na ordem e o statement Having está filtrando-os.

O LIMIT termina os cálculos assim que chega no número limite.

Texto original em ingles de Hazan Ilan, disponível em http://www.mysqldiary.com/a-many-to-many-relationship-table-solving-the-exclude-relation-problem/

Fonte: Hazan Ilan/IMasters

Tags | , , , , ,

25

dez
2011

Sem Comentários

Em Blog
Rails
Ruby

Por Allison

DataTables com RubyOnRails

Em 25, dez 2011 | Sem Comentários | Em Blog, Rails, Ruby | Por Allison

Introdução

Para quem não conhece ou não tem muita experiência com a utilização de plugins para Javascript, vamos mostrar a implementação básica do plugin para jQuery: o chamado DataTables.

DataTables é um plugin para jQuery que proporciona uma interação maior com a tabela do HTML. Em grossas palavras, ele transforma sua tabela em um componente mais útil adicionando como por exemplo: paginação e campo de busca.

Visão Geral

  • O artigo se baseia no exemplo disponível no github.
  • Para quem não está familiarizado, estou utilizando a gem HAML, que é apenas uma forma diferente de escrever HTML. Isso não irá interferir em nada a não ser o modo de escrever o HTML mesmo.
  • Estou considerando que você já tenha conhecimento de projetos RubyOnRails e que seu projeto já esteja utilizando o jQuery. Isso é estritamente necessário para que funcione o DataTables.

Obtendo o DataTables

O primeiro passo é fazer o download do plugin e adicionarmos ele em nossa aplicação. Basta clicar aqui para fazer o download.

Descompactando arquivos úteis

Após descompactar, voce irá notar que ele tem vários arquivos e nem todos serão úteis para nossa aplicação. Precisaremos apenas dos arquivos que se encontram no diretório media.

Copie este diretório para dentro do diretório javascripts da sua aplicação e renomeie para datatables.

Incluindo arquivos

Agora já temos os arquivos necessários para utilizar o DataTables. Porém, precisamos fazer a inclusão desses arquivos em nosso projeto.

Lembrando que devemos incluir os arquivos Javascript e os arquivos de CSS.

#css
= stylesheet_link_tag "/javascripts/datatables/css/demo_table.css"
#javascripts
= javascript_include_tag "datatables/js/jquery.dataTables.min.js"

Criando uma tabela

Sua tabela não pode ser criada de qualquer jeito. O DataTables necessita que sua tabela esteja conforme o exemplo abaixo.

%table.example
%thead
%tr
%th Id
%th Name
%tbody
%tr
%td 1
%td "Carro"
%tr
%td 2
%td "Moto"

Uma observação: é necessário que sua tabela possua as tags <thead> e <tbody>

Transformando a tabela em DataTables

Feito isso, agora vamos apenas chamar o método do DataTables que irá transformar a nossa tabela. Basicamente é pegarmos a tabela e chamarmos o método dataTable(). Deverá ficar similar ao exemplo abaixo:

-content_for :javascript do
:javascript
$("table.example").dataTable();

Pronto, já temos o DataTables funcionando. Muito simples. Ele possui melhores personalizações que você poderá ver no projeto de examplo que criei. O que foi dito acima é apenas o básico.

Informações sobre o exemplo

O exemplo que se encontra no meu github possui as seguintes características:

Ruby 1.9.2-p290
Rails 3.0.10
haml 3.1.2
jquery-rails 1.0.13
sqlite3
ffaker 1.8.1

Fonte: Adriano Todao/IMasters

Tags | , , , ,

22

nov
2011

Sem Comentários

Em Blog

Por Allison

MySQL 5.5.18 traz correções para problemas de replicação

Em 22, nov 2011 | Sem Comentários | Em Blog | Por Allison

A Oracle disponibilizou o MySQL 5.5.18, a última das atualizações regulares para a versão de produção do banco de dados open source. Na atualização, a Oracle tem marcado uma série de situações inseguras em replicação “statement-based”.

As declarações questionadas fazem referência ao resultado de uma instrução “select”, na qual a ordem não pode ser confiada. Sendo assim, a Oracle aconselha os utilizadores de “logging statement based” a consultar a documentação para obter mais orientações. O problema de replicação em que o master (mestre) podia enviar eventos danificados para os slaves (escravos) relacionados ao disco e ao log binário também foi corrigido.

Outras mudanças incluem melhorias para a biblioteca libedit junto com MySQL, remoção de alocação de memória desnecessária e liberação ao abrir tabelas, além de correções para falhas relacionadas com ARCHIVE e tabelas FEDERATED, e uma possível corrupção com o comando OPTIMIZE TABLE ao usar MyISAM.

Os desenvolvedores também fizeram o possível, em relação à utilização de RPM, para substituir qualquer versão instalada do MySQL com outra da mesma versão da família, por exemplo, quando houver a atualização da versão GPL para a versão comercial.

Todos os detalhes sobre essas mudanças estão disponíveis aqui, e o MySQL 5.5.18 pode ser baixado neste link.

Com informações de Under-Linux

Fonte: IMasters

Tags | , , , , , ,