Você está na página 1de 64

FACULDADE DE TECNOLOGIA DE ITAQUAQUECETUBA

JOSÉ AUGUSTO MEIRA DA ROCHA

ANÁLISE DO DESEMPENHO DO OPERADOR


DE EXPRESSÃO REGULAR NO MYSQL

ITAQUAQUECETUBA, SP
2012
FACULDADE DE TECNOLOGIA DE ITAQUAQUECETUBA
JOSÉ AUGUSTO MEIRA DA ROCHA

ANÁLISE DO DESEMPENHO DO OPERADOR


DE EXPRESSÃO REGULAR NO MYSQL

Trabalho para obtenção do grau de Tecnólogo no


curso Informática para Gestão de Negócios sob
Titulação do Prof. Luciano Deluqui Vasques.

ITAQUAQUECETUBA, SP
2012
JOSÉ AUGUSTO MEIRA DA ROCHA
ANÁLISE DO DESEMPENHO DO OPERADOR
DE EXPRESSÃO REGULAR NO MYSQL

Trabalho de Conclusão de Curso apresentado ao curso de Informática


para a Gestão de Negócios da Faculdade de Tecnologia de
Itaquaquecetuba como parte de requisitos para a conclusão de curso.

Aprovado em

BANCA EXAMINADORA

_________________________
Prof°.
Instituição - Sigla

_________________________
Prof°.
Instituição - Sigla

_________________________
Prof°.
Instituição - Sigla
AGRADECIMENTOS

Agradeço aos contribuintes do estado de São Paulo, aos mestres, funcionários, e


colegas da FATEC Itaquaquecetuba, por proporcionarem a gratificante experiência acadêmica
que ora finda.
GLOSSÁRIO

Bit – A menor unidade de informação num computador.


Octeto – Grupo de oito bits.
Query – Uma consulta a um SGBD.
Record set – Conjunto de linhas produzidas por uma “query”.
LISTA DE ABREVIATURAS

AEF –Autômatos de Estados Finitos ou Autômatos Finitos.


CEP – Código de endereçamento postal.
CNPJ – Cadastro nacional de pessoas jurídicas.
CPF – Cadastro de pessoas físicas.
ER – Expressão regular.
GNU GPL – GNU General Public License. Licença que permite cópia e uso livre de
programas.
LIFO – Last In First Out, ou pilha. Estrutura de dados em que o último elemento a entrar é o
primeiro a sair.
LR – linguagem regular.
MEF – Máquina de Estados Finitos ou Autômato Finito.
mT – Máquina de Turing.
SGBD – Sistema gerenciador de base de dados.
UML – Unified Modeling Language
web – Termo informal para designar a rede internet.
LISTA DE TABELAS

Tabela 1: Relação entre os elementos do jogo Pedra-Papel-Tesoura ....................................... 19


Tabela 2: Classificação dos níveis gramaticais de Chomsky, seus modelos geradores e
reconhecedores ...................................................................................................... 26
Tabela 3: Especificações técnicas do computador onde se executaram os testes .................... 32
Tabela 4: Programas utilizados durante a pesquisa. ................................................................. 32
Tabela 5: Comandos aceitos pelo programa Fullfiller.............................................................. 33
LISTA DE ILUSTRAÇÕES

Figura 1: Exemplos de grafos ................................................................................................... 20


Figura 2: Grafo dirigido da relação “bate”. .............................................................................. 20
Figura 3: Diagrama de transição............................................................................................... 22
Figura 4: Autômato reconhecedor de cadeias de letras que têm as vogais em sequência ........ 22
Figura 5: Representação esquemática da máquina de Turing .................................................. 23
Figura 6: Os níveis gramaticais da hierarquia de Chomsky ..................................................... 26
Figura 7: Representação esquemática dos principais modelos de base de dados ..................... 29
Figura 8: Diagramas UML das classes do Fullfiller ................................................................. 34
Gráfico 1: Comparação entre LIKE, REGEXP, REGEXP BINARY e a razão entre eles ....... 37
Gráfico 2: Tempos de formas equivalentes de LIKE e de REGEXP ....................................... 38
Gráfico 3: Uso de classe comparado ao uso da união no REGEXP ......................................... 38
Gráfico 4: Uso de REGEXP BINARY combinado com uso de classe. ................................... 39
Gráfico 5: Tempos de execução de REGEXP e REGEXP BINARY, cadeia de 64 octetos .... 39
Gráfico 6: Tempos de execução de REGEXP e REGEXP BINARY, cadeias de 255 octetos 40
Gráfico 7: Comparação entre LIKE, REGEXP e REGEXP BINARY em cadeias extensas. .. 41
LISTA DE SÍMBOLOS

Γ letra grega gama, maiúscula.


∆ letra grega delta, maiúscula.
δ letra grega delta, minúscula.
Ε letra grega épsilon, maiúscula.
ε letra grega épsilon, minúscula.
Σ letra grega sigma, maiúscula.
σ letra grega sigma, minúscula.
∪ união.
∩ interseção.
⊂ contém.
⊃ está contido.
⊆ contém ou é igual.
⊇ está contido ou é igual.
∅ conjunto vazio.
> maior.
< menor.
≥ maior ou igual.
≤ menor ou igual.
∃ existe.
∄ não existe.
∈ é elemento de, ou pertence.
∉ não é elemento de, ou não pertence.
* kleene star.
+ adição.
× multiplicação.
∕ divisão.
→ se ... então.
∀ para todo.
| tal que.
… repetição.
≠ diferente.
= igual.
⇒ implica.
RESUMO

O propósito desta pesquisa foi observar o desempenho, sob diversas condições, do


operador de expressões regulares do sistema gerenciador de banco de dados MySQL, o
REGEXP. Para auxiliar nesta tarefa, desenvolveu-se uma ferramenta capaz de gerar tabelas
com conteúdo aleatório em linguagens regulares e executar testes cronometrados, entre outras
funcionalidades. Este programa chamou-se de Fullfiller. O desempenho de variadas
combinações de argumentos do REGEXP foi comparado, bem como o desempenho de
argumentos equivalentes do operador LIKE e do REGEXP. Criou-se um conjunto de
consultas ao MySQL, estas consultas foram executadas, e os tempos de execução foram
cronometrados, tabulados, e analisados. Verificou-se que o LIKE tem desempenho superior
ao REGEXP quando a expressão regular é simples, chegando a duas centenas de vezes mais
rápido ao operar sobre cadeias extensas, com milhões de octetos; que o desempenho do LIKE
é inferior quando a expressão regular é complexa; que o uso da palavra chave BINARY no
REGEXP altera drasticamente para melhor o desempenho; e que a quantidade de linhas não
tem influência sobre o desempenho do REGEXP.

PALAVRAS CHAVE: REGEXP. Expressão Regular. MySQL.


RESUMEN

El propósito de esta investigación es observar, bajo diversas condiciones, el


desempeño del operador de expresiones regulares del sistema de gestión de base de datos
MySQL: REGEXP. Para ayudar en esta tarea, se desarrolló una herramienta capaz de generar
tablas con contenido aleatorio en lenguajes regulares y realizar pruebas cronometradas, entre
otras funciones. Este programa se llamó Fullfiller. Se comparó el rendimiento de varias
combinaciones de argumentos de REGEXP, así como el desempeño de argumentos
equivalentes del operador LIKE y del operador REGEXP. Se creó un conjunto de consultas a
MySQL, estas consultas fueron ejecutadas y los tiempos de ejecución fueron cronometrados,
tabulados y analizados. Se encontró que LIKE tiene un rendimiento superior a REGEXP
cuando la expresión regular es simple, llegando a ser dos cientos de veces más rápido para
operar con cadenas largas con millones de octetos. Sin embargo, el desempeño del mismo no
es óptimo cuando la expresión regular es compleja. También se encontró que el uso de la
palabra clave BINARY mejora drásticamente el desempeño de REGEXP y que la cantidad de
líneas no influye en el rendimiento de REGEXP.

PALABRAS CLAVE: REGEXP. expresión regular. MySQL.


ABSTRACT

The purpose of this study is to observe the performance of regular expressions


operator of MySQL database management system: the REGEXP, under diverse conditions. A
tool was developed to aid in this task which was able to generate tables with random content
in regular language and run chronometer tests, among other functions. This program was
called the Fulfiller. Various argument combinations of REGEXP and LIKE were compared. A
set of MySQL queries were created and executed, and those execution times were recorded
and analyzed. The analysis revealed that LIKE performed better than REGEXP when the
regular expressions are simple. When operating over large strings with millions of bytes,
LIKE performs up to two hundred times faster. However, in complex situations, LIKE's
performance is poor. The keyword BINARY drastically improves the REGEXP's
performance and the number of lines have no impact on REGEXP performance.

KEY WORDS: REGEXP. Regular expressions. MySQL.


SUMÁRIO

INTRODUÇÃO ........................................................................................................................ 14
1 REFERENCIAL TEÓRICO .......................................................................................... 17
1.1 Noções Básicas .............................................................................................................. 17
1.1.1 Conjuntos ................................................................................................................... 17
1.1.2 Sequências e tuplas .................................................................................................... 18
1.1.3 Funções e relações ..................................................................................................... 18
1.1.4 Grafos ......................................................................................................................... 19
1.2 Computabilidade............................................................................................................ 20
1.2.1 Autômatos .................................................................................................................. 21
1.2.1.1 Autômatos finitos ................................................................................................... 21
1.2.1.2 Autômatos finitos determinísticos.......................................................................... 23
1.2.1.3 Autômatos finitos não determinísticos ................................................................... 23
1.2.1.4 Autômato com Pilha ............................................................................................... 23
1.2.2 Máquina de Turing..................................................................................................... 23
1.3 Conceitos de Linguagem ............................................................................................... 24
1.3.1 Símbolo, Alfabeto, Cadeia ......................................................................................... 24
1.3.2 Linguagem ................................................................................................................. 25
1.3.3 Linguagens formais .................................................................................................... 25
1.3.4 Linguagens Regulares ................................................................................................ 26
1.3.5 Expressões Regulares ................................................................................................ 27
1.3.6 Sintaxe ....................................................................................................................... 27
1.4 Equivalência entre ER e AF .......................................................................................... 27
1.5 Conceitos de Base de Dados.......................................................................................... 28
1.5.1 Sistemas gerenciadores de bases de dados relacionais (SGBDR) ............................. 29
1.5.2 A linguagem SQL ...................................................................................................... 30
2 METODOLOGIA.......................................................................................................... 31
2.1 Ambiente de desenvolvimento e testes .......................................................................... 31
2.1.1 Computador ............................................................................................................... 31
2.1.2 Programas .................................................................................................................. 32
2.1.3 Ferramenta Fullfiller .................................................................................................. 33
2.1.4 Base de dados ............................................................................................................. 35
2.2 Execução dos testes ....................................................................................................... 36
3 RESULTADOS ............................................................................................................. 37
4 CONCLUSÃO ............................................................................................................... 42
5 SUGESTÕES ................................................................................................................ 43
REFERÊNCIAS ....................................................................................................................... 44
14

INTRODUÇÃO

Quando se lida com texto eletrônico, com frequência se necessita verificar a


ocorrência de algum padrão, se ele está de acordo com determinadas regras de escrita. As
placas dos veículos terrestres no Brasil, por exemplo, tem a forma xxxyyyy, onde x pode ser
qualquer letra de A a Z maiúscula e y pode ser qualquer número de 0 a 9. Podem-se
estabelecer padrões para números de CEP, de CPF ou de CNPJ, para endereços reais e
virtuais, números de telefone etc., de acordo com a necessidade.
O confronto do texto com o padrão mostra a conformidade ou desconformidade
daquele em relação a este e permite atribuir valor àquele, que passa a ser válido ou inválido.
Em qualquer caso pode-se aceitar ou rejeitar a informação, tratando-a da maneira apropriada.
Este método de validação, ou de “casamento” do texto com o padrão, pode ser usado
em mineração de dados, em validação de campos de formulários na web, como validação de
colunas ou condição de seleção de registros em um banco de dados, como ferramenta de
busca e/ou substituição de cadeias em editores de texto etc. De fato, quase toda linguagem de
programação, sistema gerenciador de bases de dados (SGBD) ou programa aplicativo
atualmente trazem em si recursos que permitem processar texto por meio de padrões
empregando, para isso, a singela linguagem regular.
As linguagens regulares (LR) são o instrumento próprio para exprimir tais padrões.
Apesar de ocuparem o nível mais baixo na escala de complexidade de linguagens formais
(CHOMSKY, 1959, tradução do pesquisador), têm sua importância reconhecida nas ciências
devido à capacidade de estabelecerem esse tipo de padrão.
As LR integram o conjunto das linguagens formais e, portanto, são computáveis.
Logo, uma máquina pode decidir se determinada cadeia é expressão de uma LR. Pode-se
construir um autômato que aceite expressões cuja sintaxe esteja de acordo com a especificada
e as rejeite em caso contrário. Tais autômatos formam a base das funções embutidas nos
programas citados acima.
O MySQL, o SGBD de código livre mais difundido e utiliazado no mundo,
implementa o recurso de ER e este trabalho tem por fim examinar o desempenho deste
instrumento, chamado de operador REGEXP.
No capítulo 1 se faz uma revisão das teorias envolvidas no assunto. Da Matemática
se rememoram a teoria dos conjuntos, funções e relações, e grafos; da Ciência da Computação
15

se revê a noção de computabilidade, de autônomos, da máquina de Turing e de bases de


dados; da Linguística se mencionam as idéias de símbolo, de alfabeto, de linguagem, se
apresenta o conceito de linguagem formal e das linguagens regulares.
No capítulo 2 se explica como foi feita a experiência; se descreve o ambiente dos
testes, os programas envolvidos, a ferramenta Fullfiller; se comenta a base de dados sobre a
qual o trabalho foi executado, a geração dos dados e a execução dos testes.
No capítulo 3 se apresentam os resultados obtidos.
No capítulo 4 se oferecem as conclusões a que se chegou a partir da análise dos
resultados.
No capítulo 5 se sugerem caminhos para a continuação e aprofundamento do
trabalho ora iniciado.
Nas referências se relacionam as publicações e autores que serviram de base ao
trabalho.

Tema

O operador de expressão regular REGEXP no SGBD MySQL.

Objetivos

Objetivo geral

A intenção primeira desta pesquisa é conhecer o comportamento do operador de


expressões regulares no MySQL, o REGEXP.

Objetivos específicos

Criar uma ferramenta auxiliar cuja função será automatizar a execução dos testes de
desempenho do operador REGEXP, que poderá ser usada para testar ER e para geração
automática de dados de teste.
Comparar o desempenho do operador REGEXP com do operador LIKE.
Examinar o desempenho de variadas combinações de argumentos do operador
REGEXP.
16

Problema da Pesquisa

Como é o desempenho do operador REGEXP no MySQL?

Hipótese

Se mensurarmos o desempenho do operador REGEXP sob variadas condições de


uso, obteremos informações que poderão ser usadas para otimizar as consultas que o utilizam
no MySQL.

Justificativa

As teorias e métodos de administração, desde Taylor, Ford e Fayol, têm objetivado a


racionalização dos processos e a maximização do aproveitamento dos recursos disponíveis às
organizações. O resultado deste trabalho pode contribuir para isto, levando ao uso mais
eficiente do SGBD MySQL e, como consequência, à economia de recursos computacionais e
de tempo.
17

1 REFERENCIAL TEÓRICO

Neste capítulo se apresentam os elementos teóricos que embasam todos os


algoritmos de processamento de ER: a Computabilidade, a Máquina de Turing, os Autômatos
Finitos, e a sua inter-relação. São mostradas, com apoio da teoria Linguística, as idéias das
linguagens regulares e das Expressões Regulares. Apresenta, também, uma breve história das
ER, seus elementos componentes e sua sintaxe.

1.1 Noções Básicas

Aqui se apresentam as definições teóricas necessárias ao entendimento deste


capítulo. Vêm principalmente da Matemática (teoria dos Conjuntos, Lógica relacional), mas
também da Linguística.

1.1.1 Conjuntos

Conjuntos finitos podem ser especificados pela enumeração de seus elementos entre
chaves. Por exemplo, {0, 1} denota o alfabeto de símbolos 0 e 1. Outra especificação
possível para conjuntos é por meio de uma regra de formação:

{x | P(x)}

lida como "o conjunto dos objetos x tais que P(x) é verdade" onde P(x) é alguma
afirmação sobre objetos x, ou ainda

{x in A | P(x)}

lida como "o conjunto dos x em A tais que P(x) é verdade" (HOPCROFT et al.,
1979, p.5).
As operações normais definidas para os conjuntos (HOPCROFT et al., 1997, p.5):
1) A ∪ B, a união de A com B, é:

{x | x está em A ou x está em B}.

2) A ∩ B, a interseção de A com B, é:

{x | x está em A e x está em B}.


18

3) A−B, a diferença entre A e B, é:

{x | x está em A e x não está em B}.

4) A×B, o produto cartesiano de A e B, é o conjunto de pares ordenados dos


elementos a em A e dos b em B.
5) 2A o conjunto potência A, é o conjunto de todos os subconjuntos A.

1.1.2 Sequências e tuplas

Uma sequência de objetos é uma lista destes objetos em alguma ordem.


Normalmente designa-se uma sequência escrevendo a lista entre parênteses. A sequência 7,
21, 57, por exemplo, é escrita (7, 21, 57). Numa sequência, ao contrário dos conjuntos, a
ordem e a repetição dos elementos é importante. As sequências, assim como os conjuntos,
podem ser finitas ou infinitas. Sequências finitas também são chamadas de tuplas. Uma
sequência com k elementos é uma k-tupla. Sequências com dois elementos são 2-tuplas,
também chamada de pares (SIPSER, 2006, p. 6, tradução do pesquisador).

1.1.3 Funções e relações

Funções são essenciais à matemática. Uma função estabelece uma relação entrada-
saída, ou seja, recebe uma entrada e produz uma saída. A mesma entrada produzirá sempre a
mesma saída (SIPSER, 2006, p. 7, tradução do pesquisador). Se f é uma função que recebe a
e devolve b, escreve-se

f(a) = b.

Uma função é também chamada de mapeamento. Diz-se da função acima que ela
mapeia a em b.
Por exemplo, a função de valor absoluto abs toma um número x como entrada e
devolve x se x for positivo e –x se x for negativo, então abs(2) = abs(-2) = 2.
O conjunto de possíveis valores de entradas de uma função é chamado de domínio e
o conjunto das saídas é chamado de imagem. A notação para se dizer que f é uma função com
domínio D e imagem R é

f: D ⟶ R.
19

Pode-se descrever uma função de várias maneiras. Uma maneira é com um


procedimento para computar uma saída a partir de uma entrada específica. Outra maneira é
com uma tabela que lista todas as entradas possíveis e dá a saída para cada entrada.
Quando o domínio de uma função f é Al×…×Ak para conjuntos Al, …, Ak, a entrada
de f é uma k-tupla (a1, a2 , ... , ak) e chama-se ai os argumentos da função. Se k é 1, f tem
um único argumento e é chamada de unária. Se k é 2, f é uma função binária.
Um predicado ou propriedade é uma função cuja imagem é {VERDADEIRO,
FALSO}. Por exemplo, seja par uma propriedade que é VERDADE se a entrada for um
número par e FALSO se a entrada for um número ímpar, então par(4) = VERDADE e
par(5) = FALSO.
Uma propriedade cujo domínio é um conjunto de k-tuplas A×…×A é chamada de
relação, relação k-aria, ou relação k-aria em A. A relação binária é um caso comum de
relação 2-ária.
Por exemplo, no jogo infantil Pedra-Papel-Tesoura, dois jogadores escolhem
simultaneamente um membro do conjunto {PEDRA, PAPEL, TESOURA} e indicam sua
escolha com um sinal manual. Se as escolhas forem as mesmas, o jogo reinicia. Se as escolhas
forem diferentes, um jogador ganha, de acordo com a Tabela 1.

Tabela 1: Relação entre os elementos do jogo Pedra-Papel-Tesoura

bate pedra papel tesoura

pedra FALSO FALSO VERDADE

papel VERDADE FALSO FALSO

tesoura FALSO VERDADE FALSO


Fonte: Sipser (2006, p.13, tradução do pesquisador)

1.1.4 Grafos

Um grafo não dirigido, ou simplesmente grafo, é um conjunto de pontos chamados


de nodos ou vértices que podem estar conectados por linhas chamadas de arestas (Figura 1); o
número de arestas em determinado nodo é o grau deste nodo; entre dois nodos pode haver só
uma aresta (SIPSER, 2006, p.10, tradução do pesquisador).
20

Figura 1: Exemplos de grafos


Fonte: Sipser (2006, p.10, tradução do pesquisador)

Um grafo dirigido, ou dígrafo, “(...) é um conjunto finito não vazio de vértices e um


conjunto de pares ordenados de vértices distintos em que cada aresta (v,w) possui uma
única direção de v para w. (v,w) é divergente de v e convergente a w” (PIMENTEL, 2011).

Figura 2: Grafo dirigido da relação “bate”.


Fonte: Sipser (2006, p.13, tradução do pesquisador)

1.2 Computabilidade

Alguns problemas podem ser resolvidos por meio de algoritmos enquanto outros não
podem. Saber que um problema é algoritmicamente insolúvel é útil porque isso mostra que o
problema deve ser simplificado (RUS, 2006, tradução do pesquisador).
A computabilidade é uma propriedade dos conjuntos pela qual se pode determinar se
algo é membro ou não de um conjunto, em um numero finito de passos (ROWE, 2010,
tradução do pesquisador).
Uma tarefa será computável se for possível especificar uma sequência de instruções,
chamadas de procedimento ou algoritmo, que resultarão no completamento da tarefa quando
for executada por alguma máquina (BARKER-PLUMMER, 2011, tradução do pesquisador).
21

Estes procedimentos, modelos matemáticos, auxiliam o trabalho de determinar o


pertencimento de algo a algum conjunto ou, em outras palavras, determinar a computabilidade
de uma tarefa. Os autômatos e a máquina de Turing são exemplos destes modelos (RANGEL,
p. 2-2).

1.2.1 Autômatos

Também chamada de teoria da linguagem, a teoria dos autômatos, é um extenso


corpo de conhecimento desenvolvido em torno da definição e reconhecimento de padrões.
Suas definições e técnicas básicas são partes essenciais da ciência da computação (ULLMAN,
c.10, tradução do pesquisador).
A teoria dos autômatos trata das definições e propriedades de modelos matemáticos
de computação aplicados a várias áreas da ciência da computação. Um destes modelos,
chamado de autômato finito (AF), é usado no processamento de texto, em compiladores, e no
projeto de “hardware”. Outro, chamado de gramática livre de contexto, é usado em linguagens
de programação e em inteligência artificial (SIPSER, 2006, p.3, tradução do pesquisador).

1.2.1.1 Autômatos finitos

Autômato finito (AF), ou máquina de estados finitos, é um modelo matemático de


computação (HARVEY, 1997, tradução do pesquisador).
Associa-se aos AF um grafo dirigido, chamado diagrama de transição, cujos vértices
correspondem aos estados do AF. Se há uma transição do estado q para o estado p, causada
pela entrada a, então há uma aresta rotulada a, do estado q para o estado p, no diagrama de
transição. O AF aceita uma cadeia x se a sequência de transições correspondentes aos
símbolos de x leva do estado inicial a um estado de aceitação (HOPCROFT, 1979, p.16,
tradução do pesquisador).
22

Figura 3: Diagrama de transição


Fonte: HOPCROFT, 1979, p.18, tradução do pesquisador

Um AF recebe uma cadeia de caráteres conhecida como sequência de entrada. Ele


começa no estado inicial, pronto para ler o primeiro caráter da sequência de entrada.
Dependendo desse caráter, ele faz uma transição, talvez para o mesmo estado, talvez para
outro estado. A transição é ditada pelo grafo do autômato. O autômato então lê o segundo
caráter e faz a transição apropriada e assim por diante (ULLMAN et al. 1994, sec.10.2,
tradução do pesquisador).
Figura 4Na Figura 4 vemos um AF, representado por um grafo. Este AF recebe como
entrada uma cadeia e aceita essa cadeia se ela tiver as cinco vogais na sequência aeiou, não
importando se há outros caracteres entre uma e outra vogal.

Figura 4: Autômato reconhecedor de cadeias de letras que têm as vogais em sequência


Fonte: ULLMAN, 1994

Os AF podem ser Determinísticos ou Não Determinísticos, mas diz-se que são


equivalentes se aceitam como entrada o mesmo conjunto de cadeias. Um autômato
determinístico é, tecnicamente, um não-determinístico sem múltiplas transições para um
símbolo. (ULLMAN, 1994, tradução do pesquisador).
23

1.2.1.2 Autômatos finitos determinísticos

Os autômatos ditos determinísticos (AFD) têm uma propriedade importante: para


cada estado s e qualquer caractere x de entrada, há no máximo uma transição de saída do
estado s que contemple x (ULLMAN, 1994, c.10, tradução do pesquisador).

1.2.1.3 Autômatos finitos não determinísticos

Permite-se aos AFN ter, saindo de um estado, duas ou mais transições contendo o
mesmo símbolo. Um autômato determinístico é, tecnicamente, um não-determinístico sem
múltiplas transições para um símbolo. Qualquer conjunto aceito por um AFN também pode
ser aceito por um AFD. (ULLMAN, 1994, c.10, tradução do pesquisador).

1.2.1.4 Autômato com Pilha

O autômato com pilha (AP) é análogo ao AFN acrescido de uma memória auxiliar,
uma estrutura do tipo pilha ou LIFO (do inglês Last In First Out), onde o último a entrar é o
primeiro a sair (PALAZZO, 2008a).

1.2.2 Máquina de Turing

Os AF são modelos bons para dispositivos com pouca memória, os AP são modelos
bons para dispositivos com memória ilimitada, do tipo pilha, mas ambos têm capacidade
limitada para algumas tarefas. A máquina de Turing (mT), um tipo de máquina de estado
descrita em 1937 por Alan Turing, é um modelo matemático muito mais poderoso. Um
dispositivo computacional abstrato simples, similar a um AF, com memória irrestrita e
ilimitada (SIPSER, 2006, p.137, tradução do pesquisador).

Figura 5: Representação esquemática da máquina de Turing


Fonte: Sipser (2006, p.138, tradução do pesquisador)
24

A mT usa uma fita infinita como memória, tem uma cabeça que pode ler e escrever
símbolos e mover-se livremente ao longo da fita. Ao iniciar, a fita tem inscrita a cadeia de
entrada e nada mais. Ela memoriza informação escrevendo na fita, pode ler o que escreveu,
voltando a cabeça sobre o escrito. A máquina continua computando até entrar em um estado
de aceitação ou rejeição, quando então pára. Funcionará eternamente se nunca entrar num dos
estados (SIPSER, 2006, p.138, tradução do pesquisador).

1.3 Conceitos de Linguagem

Os conceitos apresentados a seguir prestam-se a um esclarecimento ligeiro sobre a


teoria linguística a fim de elucidar os pontos que esta tem em comum com o tema da pesquisa.

1.3.1 Símbolo, Alfabeto, Cadeia

Símbolo é uma entidade abstrata que não se deve definir formalmente da qual letras e
dígitos são exemplos comuns (HOPCROFT, 2001, tradução do pesquisador).
Um alfabeto é qualquer conjunto finito não vazio, cujos elementos são chamados de
símbolos. Normalmente as letras gregas maiúsculas Σ e Γ são usadas para designar alfabetos
(SIPSER, 2006, tradução nossa).
Hopcroft (1979, tradução do pesquisador) dá alguns exemplos de alfabetos:
Σ1={0,1};
Σ2={a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z};
Γ={0,1,x,y,z}.
Uma cadeia sobre um alfabeto é uma sequência finita de símbolos desse alfabeto,
escritos um ao lado de outro, sem vírgulas separando. Sendo Σ1 = {0,1}, 01001 é uma
cadeia sobre Σl e sendo Σ2 = {a, b, c, . . , z}, abracadabra é uma cadeia sobre Σ2. Se w é
uma cadeia sobre Σ, o tamanho de w, denotado por |w|, é o número de símbolos que ela
contém. Uma cadeia de tamanho zero, chamada de cadeia vazia e representada por ε, é
equivalente ao zero em um sistema numérico e é a identidade para a operação de
concatenação, ou seja εw=wε=w. Se w tem um tamanho n, pode-se escrever w = w1w2…wn, em
que cada wi ∈ Σ. O inverso de w, escrito wR, é a cadeia obtida de w tomada em ordem inversa,
isto é, wnwn-1…w1. Uma cadeia z é uma subcadeia de w se z aparece consecutivamente em w.
Por exemplo, cad é uma subcadeia de abracadabra. Se tivermos uma cadeia x de
25

tamanho m e uma cadeia y de tamanho n, a concatenação de x e y, escrita xy, é a cadeia


obtida pela justaposição da cadeia y ao final da cadeia x, como em x1…xmyl…yn. Para denotar
a concatenação de uma cadeia com ela mesma várias vezes, escreve-se xk, onde k significa o
número de vezes. Uma cadeia x é um prefixo de uma cadeia y se existe uma cadeia z tal que
xz = y e, se x ≠ y, diz-se que x é um prefixo próprio de y (SIPSER, 2006, tradução nossa).

1.3.2 Linguagem

Uma linguagem é um conjunto de sentenças de tamanho finito construídas sobre um


alfabeto de símbolos (CHOMSKY, 1959, P.137, tradução do pesquisador).
Hopcroft (1979, tradução do pesquisador), define linguagem como um conjunto de
cadeias. O conjunto vazio, ∅, e o conjunto consistido pela cadeia vazia {ε} também são
linguagens. O conjunto dos palíndromos – cadeias que podem ser lidas direta ou
invertidamente – sobre o alfabeto {0,1} é uma linguagem infinita da qual
ε,0,1,00,11,010, e 1101011 são membros. Os conjuntos de todas as cadeias
construídas sobre um alfabeto fixo Σ também são linguagens, denotas Σ*. Por exemplo, se
Σ={a}, então Σ*={ε,a,aa,aaa,…}; se Σ={0,1}, então Σ*={ε,0,1,00,01,10,
11,000,…}.

1.3.3 Linguagens formais

Uma linguagem formal, ensina Ramos (2010), “(...) é um conjunto, finito ou infinito,
de cadeias de comprimento finito, formadas pela concatenação de elementos de um alfabeto
finito e não-vazio.”
Chomsky (1959, p.142) define quatro níveis gramaticais com regras de formação
progressivamente restritivas, partindo do nível 0 – sem restrições – até o nível 3, o mais
restrito. Cada nível define uma linguagem respectiva.
26

Figura 6: Os níveis gramaticais da hierarquia de Chomsky


Fonte: PALAZZO (2008b)

A tabela abaixo relaciona os quatro níveis gramaticais idealizados por Chomsky com
os modelos de gramática e modelos reconhecedores de sentenças.

Tabela 2: Classificação dos níveis gramaticais de Chomsky, seus modelos geradores e reconhecedores

Tipo Classe de linguagens Modelo de Gramática Modelo de reconhecedor


0 Recursivamente Irrestrita Máquina de Turing
enumeráveis
1 Sensíveis ao contexto Sensível ao contexto Máquina de Turing c/ fita
limitada
2 Livres de Contexto Livre de contexto Autômato de pilha
3 Regulares Linear (direita ou esquerda) Autômato finito
Fonte: RAMOS (2010a, p.5)

1.3.4 Linguagens Regulares

O estudo das linguagens regulares, para Palazzo (2008b), pode ser abordado através
de 3 diferentes formalismos: operacional ou reconhecedor (AF), axiomático ou gerador
(Gramática Regular), e denotacional (ER), que também pode ser considerado gerador.
27

1.3.5 Expressões Regulares

Uma ER é uma fórmula algébrica cujo valor é um padrão, que consiste de um


conjunto de cadeias, chamado de linguagem da expressão (NELSON, 1999, tradução do
pesquisador).
As ER surgiram do trabalho de Rudolph Carnap sobre a sintaxe da lógica; foram
transformadas por McCulloch e Pitts em cálculos lógicos de redes neurais; tomadas por John
von Neumann para a descrição do computador EDVAC, e mais tarde para sua teoria dos
autômatos; formalizadas e batizadas como “expressões regulares” pelo matemático Stephen
Kleene; foram usadas para projetar diagramas de estado para circuitos por Janusz
Brzozowski; implementadas em programas pela primeira vez por Ken Thompson (que detém
uma patente pelo uso de ER em comparação de padrões); e estão embutidas em quase toda
linguagem de programação atualmente em uso (KELTY, 2008, p.4, tradução do pesquisador).
ER são a ferramenta certa, úteis e poderosas, para tarefas de processamento,
manipulação e reformatação de texto estruturado e fazem parte do arsenal de ferramentas de
manipulação de texto e dados que permite algum controle sobre o atual ambiente
informacional, saturado de símbolos (KELTY, 2008, p.5, tradução do pesquisador).
Os operandos possíveis numa ER são: caráteres de um alfabeto sobre o qual a ER
está definida, variáveis cujos valores são qualquer padrão definido por uma ER, ε e ∅. Os
operadores são: a união, a concatenação e o fecho de Kleene. O fecho tem a precedência
mais alta, seguido pela concatenação, seguida pela união (NELSON, 1999, tradução do
pesquisador)

1.3.6 Sintaxe

Na gramática de uma língua, sintaxe é a parte que trata de “(...) dispor as palavras
para formar as orações, as orações para formar os períodos e parágrafos, e estes para formar o
discurso.” (MICHAELIS), ou seja, “Parte da linguística que se dedica ao estudo das regras e
dos princípios que regem a organização dos constituintes das frases.” (PRIBERAM).

1.4 Equivalência entre ER e AF

Um Autômato Finito descreve uma linguagem e é equivalente a uma ER, já que uma
ER é a formalização algébrica de um Autômato Finito (RODRIGUES, 2009). As linguagens
28

aceitas por um AF são precisamente as linguagens denotadas por ER (HOPCROFT, 1979,


tradução do pesquisador). Estas idéias são também encontradas em Nelson (1999, tradução do
pesquisador), que afirma que ER e AF têm força expressiva equivalente, pois para toda
expressão regular R há um correspondente autômato finito que aceita o conjunto de cadeias
geradas por R e para cada autômato finito A existe uma expressão regular correspondente que
gera o conjunto de cadeias aceitas por A.

1.5 Conceitos de Base de Dados

Os programas de computador na década de sessenta processavam dados por lotes


(batch), lendo-os sequencialmente em arquivos armazenados em fita magnética. Usualmente
um arquivo denominado mestre, que continha as informações principais, era combinado com
outro denominado movimento, que continha as informações de atualização, gerando um novo
mestre atualizado. Este modo de operar facilitava a redundância, ou seja, uma informação
podia estar em mais de um arquivo ao mesmo tempo (PARÉ, 2005, tradução do pesquisador).
Com o surgimento de linhas de comunicação, de terminais, e de discos magnéticos
que permitiam acesso direto aos dados, os programas passaram a ser escritos de forma a
permitir que várias pessoas fizessem consultas e atualizações on-line e simultâneas aos
arquivos. Precisaram-se redesenhar as estruturas de armazenamento antigas, criando novas
que permitissem acesso on-line eficiente e que eliminassem a redundância. Estes conjuntos de
arquivos com estruturas complexas, compartilhados por vários processos de forma
simultânea, foram chamados inicialmente de Bancos de Dados e depois, no início dos anos
setenta, de Bases de Dados (BD). Estas eram mais complexas do que os sistemas de arquivos
e exigiram que novos programas fossem desenvolvidos. Surgem, então, os Sistemas
Gerenciadores de Bases de Dados (SGDB). Estes podem ser agrupados em modelos conforme
o conjunto de componentes ou ferramentas que proporcionam (PARÉ, 2005, tradução do
pesquisador).
O modelo hierárquico foi idealizado na década de sessenta e está em uso até hoje.
Baseia-se no paradigma do pai/filho, no qual cada pai pode ter vários filhos mas cada filho
pode ter só um pai. A visualização desta estrutura compara-se a uma árvore invertida: a raiz
na parte superior e galhos se subdividindo em vários níveis. O modelo em rede é similar ao
hierárquico, mas sem a restrição de só um pai para cada filho. Nele, é permitido a cada filho
ter mais de um pai. Pode ser visualizado como várias árvores compartilhando alguns galhos.
29

O modelo relacional surge a seguir para resolver problemas que havia nos modelos anteriores.
(KRIEGEL; TRUKHNOV, 2003, p.12, tradução do pesquisador).

Figura 7: Representação esquemática dos principais modelos de base de dados


Fonte: PARÉ, 2005

1.5.1 Sistemas gerenciadores de bases de dados relacionais (SGBDR)

O conceito de uma base de dados relacional e da SQL foi apresentado pelo Dr.
Edward Frank Codd, que trabalhava para a IBM como pesquisador, em seu trabalho “A
Relational Model of Data for Large Shared Data Banks” (Um modelo relacional de dados
para grandes bancos de dados compartilhados) em 1970. Este modelo baseava-se na
independência entre dados e a forma como eram armazenados e em uma linguagem não
procedural de alto nível para acessar estes dados (KRIEGEL; TRUKHNOV, 2003, p.22,
tradução do pesquisador). A proposta de Codd imediatamente atraiu a atenção devido a sua
simplicidade e fundamentação matemática. Ela usava o conceito de relação matemática e
tinha base teórica na teoria dos conjuntos e na lógica dos predicados de primeira ordem
(ELMASRI; NAVATHE, 2011, p.59, tradução do pesquisador).
30

1.5.2 A linguagem SQL

As instruções em SQL dividem-se em quatro grupos de linguagem, segundo sua


função: comandos para definição dos dados, a DDL (data definition language), comandos
para manipulação dos dados, a DML (data manipulation language), comandos para controle
dos dados, a DCL (data control language), e um grupo cujo único componente é o comando
SELECT, para consultas aos dados, a DQL (data query language). (KRIEGEL; TRUKHNOV,
2003, tradução do pesquisador).
31

2 METODOLOGIA

Fizeram-se dois conjuntos de teste. Em um, o desempenho do operador REGEXP é


comparado ao desempenho do operador LIKE e no outro, as comparações são feitas entre os
argumentos do operador REGEXP.
A palavra chave BINARY determina a sensibilidade do REGEXP à caixa (maiúscula
ou minúscula) do caráter. O uso de BINARY torna a operação sensível à caixa.
No primeiro conjunto os argumentos dos dois operadores são equivalentes, ou seja,
cada operador faz o mesmo tipo de busca para produzir os mesmos resultados. Os argumentos
são simples, já que a sintaxe da linguagem aceita pelo LIKE é extremamente simples. Os
testes deste grupo serviram para identificar as situações em que um operador tem vantagem
sobre o outro.
Os testes do segundo conjunto comparam argumentos – as próprias ER – do
REGEXP. Permitiram estabelecer, entre ER equivalentes, quais tem melhor desempenho.
Todas as medições foram relativas ao tempo de execução do comando SELECT
COUNT(*). Desta maneira, o resultado – o “record set” – foi uniforme e de tamanho mínimo,
sempre com uma só informação: a quantidade de linhas encontradas.
As medições poderão ter erro intrínseco ao método de medição adotado, cujo rigor
achou-se adequado à situação.

2.1 Ambiente de desenvolvimento e testes

Usou-se na pesquisa, para execução dos testes, um computador PC tipo desktop


controlado pelo sistema operacional Windows XP, o banco de dados MySQL e a linguagem
Java. O ambiente de desenvolvimento integrado NetBeans IDE serviu para construção do
programa Fullfiller. Este, serviu-se do gerador de cadeias Xeger que, por sua vez, usa o
dk.brics.automaton.

2.1.1 Computador

A tabela seguinte é relativa ao computador onde se executaram os testes e contém as


informações técnicas mais relevantes:
32

Tabela 3: Especificações técnicas do computador onde se executaram os testes


Item Descrição
Sistema Operacional Windows XP Professional Service Pack 3 (build 2600)
Português (Brasil)
Instalado em: 27/5/2010 23:08:42
Modelo Desktop
Processador 2,93 gHz Intel Core 2 Duo
64 kB memória cache primária
3072 kB memória cache secundária
sem hyper-thread
Placa mãe Intel Corporation DG31PR AAE58249-306
Bus Clock: 1066 MHz
Memória instalada 2036 MB disponível
Volumes locais c: (NTFS no drive 0), 500 GB total, 342 GB livre, 7.200 rpm.
d: (NTFS no drive 1), 262 GB total, 160 GB livre, 7.200 rpm.
Fonte: o próprio pesquisador.

2.1.2 Programas

Excetuando-se o SO, que é propriedade da Microsoft Corporation, todos os


programas são de uso livre e/ou são de código aberto.
A tabela seguinte relaciona os programas envolvidos na pesquisa com o uso que
tiveram no decorrer do trabalho.

Tabela 4: Programas utilizados durante a pesquisa.

Recurso Ver. Função


MySQL 5.5.16 Objeto dos testes.
Java 1.7.0 Codificar a ferramenta Fullfiller
NetBeans 6.9.1 Fornecer o ambiente de desenvolvimento do Fullfiller
dk.brics.automaton 1.11-8 Implementar os automatos necessários ao programa Xeger
Xeger 1.0 Gerar cadeias randômicas
Belarc Advisor 8.1.16 Fornecer informações sobre o ambiente computacional
LibreOffice calc 3.2.0 Tabular os resultados e auxiliar na elaboração dos gráficos
Fullfiller 0.1 Facilitar a execução dos testes, automatizando-os
Asta Community 6.6.3 Facilitar a criação do diagrama UML de classes
Fonte: o próprio pesquisador.
33

O MySQL usa a implementação de ER de Henry Spencer, conforme o padrão POSIX


1003.2 e chama as operações permitidas pelo LIKE de ER normais, enquanto as operações
executadas pelo REGEXP são chamadas de estendidas.

2.1.3 Ferramenta Fullfiller

Ao longo do trabalho, o banco de dados deveria ser repetidamente criado e os dados


de teste repetidamente gerados. Da mesma forma, durante as medições de desempenho ou
execução dos testes propriamente dita, variadas combinações de comandos e argumentos de
comandos deveriam ser usadas diversas vezes para determinar as composições que melhor
representassem o comportamento do SGBD.
A fim de facilitar essas tarefas se idealizou e se escreveu, na linguagem Java, uma
aplicação que permitiu a automação desses processos repetitivos. Combinações de coluna,
operador, argumento, e grandeza puderam ser feitas sem que houvesse alteração do código
fonte da aplicação. O Fullfiller tem uma interface por linha de comando, lê um arquivo
“script” com ações a tomar e as executa. Pode se conectar com o BD, emitir comandos no
sistema operacional, criar linhas nas tabelas com produções sobre uma ER, executar e
cronometrar os testes, e gerar um arquivo no formato CSV com os resultados.

Tabela 5: Comandos aceitos pelo programa Fullfiller.

Comando Função Argumento


nome Informar uma ER para geração de nomes Uma ER
emai Informar uma ER para geração de endereços Uma ER
de e-mail
text Informar uma ER para geração de cadeias de Uma ER
caráteres
test Informar uma combinação de tabela do BD, Nome da tabela, nome da coluna,
coluna da tabela, o operador de ER e o operador, argumento do operador
argumento do operador.
user Informar o nome do usuário no MySQL Nome do usuário registrado no BD
pass Informar a senha do usuário no MySQL Senha do usuário registrada no BD
comm Executar um comando do sistema Comando a ser executado
operacional
crea Disparar a criação do BD O nível de grandeza do banco
exec Disparar a execução dos testes A quantidade de vezes que um
comando de teste deve ser
executado
34

# Usado no início de uma linha, permite que Um comentário


se escreva comentários no arquivo de
parâmetros
Fonte: o próprio pesquisador.

O Fullfiller compõe-se de cinco classes concretas: a classe principal, Fullfiller; a


classe Chronometer, que provê funções para a medição dos tempos; a classe DbFunctions,
que fornece facilidades para a conexão com o SGBD e para a execução de “queries”; a classe
InOut, que trata das operações sobre o arquivo de “script”, o arquivo de saída padrão, e o
arquivo de resultados; e a classe Script, responsável por executar os comandos contidos no
arquivo de script.

Figura 8: Diagramas UML das classes do Fullfiller


Fonte: o próprio pesquisador.
35

O arquivo de script pode conter os comandos relacionados na Tabela 5 e somente


aqueles.
Uma linha em branco ou o final do arquivo encerra a lista de comandos.
Uma linha de comando tem o seguinte formato: o comando, um caráter de controle
GS (ASCII 29, Group Separator), o argumento do comando, um caráter de GS.
O argumento dos comandos “nome”, “email”, “texto”, é uma ER que deve obedecer
a sintaxe aceita pelo Xeger (Anexo 1).
O argumento do comando “test” é composto de quatro partes, separadas pelo caráter
VT (ASCII 9, Vertical Tab), a saber: o nome da tabela em que o teste será feito, o nome da
coluna desta tabela, o operador (LIKE ou REGEXP), e o argumento do operador. Este é uma
ER que deve obedecer a sintaxe do MySQL (MySQL, p.781).
O argumento do comando “exec” determina quantas vezes um teste deve ser
executado. O objetivo da repetição de um teste é diminuir o erro de medição obtendo uma
média. Este erro é devido à imprecisão dos recursos de cronometragem disponíveis.
O código fonte do Fullfiller é aberto e seu uso disciplinado pela licença GNU GPL.
Encontra-se no Apêndice 2 e está disponível no sítio Source Forge no endereço
sourceforge.net/projects/Fullfiller/. Os testes aqui apresentados poderão ser reproduzidos se
conforme instruções no Anexo forem baixando-se a pasta “dist” que está no endereço
sourceforge.net/projects/Fullfiller/dist, que contém o programa Fullfiller executável, os
“scripts” de criação do banco e do conjunto de testes, e as bibliotecas necessárias.

2.1.4 Base de dados

Imaginou-se um banco de dados com duas tabelas que se distinguem pela quantidade
de colunas e pelo tamanho das cadeias que cada coluna comporta. A tabela “ficha” tem quatro
colunas: com tamanho que varia de 16 octetos à cerca de 255 octetos e uma coluna para a
chave primária. A tabela “texto” tem uma coluna que comporta uma cadeia de até 5.000.000
octetos e uma coluna para a chave primária. A chave primária nas tabelas “ficha” e “texto”
tem caráter funcional, e não será objeto dos testes.
O tamanho da cadeia da coluna “conteúdo” da tabela “texto” é 1.000.000 octetos na
grandeza 0, 2.000.000 octetos na grandeza 1 e assim por diante até a grandeza 4 com
5.000.000 octetos. Em qualquer grandeza, tem as cadeias “.primeiracadeia.” no inicio e
“.ultimacadeia.” no final.
36

Escreveu-se um script de criação do BD gravado em arquivo e executado pelo


Fullfiller. O conteúdo deste arquivo é exposto no Apêndice 1.
Para verificar o comportamento do MySQL em função da quantidade de linhas, se
variou o tamanho da tabela A segundo a regra expressa pela fórmula

L = C × 10n

onde L é o numero de linhas, C é o número de combinações das 26 letras maiúsculas do


alfabeto oficial do Brasil tomadas 3 a 3, cujo resultado é 17.576, e n é um número inteiro
positivo, chamado de grandeza da tabela. Desta forma, a tabela A tem 17.576 na grandeza 0,
175.760 na grandeza 1, 1.757.600 na grandeza 2, 17.576.000 linhas na grandeza 3,
175.760.000 linhas na grandeza 4.
O conjunto de caráteres, o alfabeto sobre o qual se trabalhará, será o ANSI devido a
sua simplicidade, tamanho reduzido, e por utilizar apenas um octeto para armazenar um
caráter.

2.2 Execução dos testes

Foram desativados todos os programas não relacionados com o funcionamento do


Windows, do MySQL, ou do Java a fim de reduzir ao mínimo a interferência de processos
alheios aos testes no momento da execução das medições.
Escolheu-se não executar os testes no nível de grandeza 4, pois, baseados nos tempos
de execução das grandezas de zero a 3, projetou-se um tempo de cerca de duzentas horas para
terminar. O nível de grandeza 3 também não foi considerado porque, por motivo não
determinado e fora de nosso domínio de conhecimento, os tempos foram, em média, oito
vezes maiores que nas grandezas anteriores, comprometendo as medições. Assim, a bateria de
testes foi executada nas grandezas de 0 a 2.
O resultado fornecidos pelo Fullfiller, no formato CSV, foram organizados por uma
planilha de cálculo.
37

3 RESULTADOS

Fez-se três tipos de comparação: do operador LIKE contra o REGEXP, do REGEXP


em si, e por grandeza do banco e de cadeias.
Dentre as combinações de tamanho das cadeias, operador, grandeza da tabela, e
tamanho da coluna testadas, escolheu-se algumas que melhor representavam o
comportamento dos comandos.
O gráfico 1 mostra tempos médios de execução de buscas equivalentes. Nota-se que
REGEXP BINARY é, em média, 40% mais demorado que LIKE, mas ambos têm
desempenhos lineares e constantes, independente do argumento; que o REGEXP chega a ser
quase 2,5 vezes mais lento que o LIKE; que REGEXP insensível à caixa pode tempos de
execução até duas vezes maior; e que o uso do meta-caráter “.” aumenta o tempo de
processamento do REGEXP.

Gráfico 1: Comparação entre LIKE, REGEXP, REGEXP BINARY e a razão entre eles
Fonte: o próprio pesquisador, 2012

Quando a complexidade das expressões aumenta, a riqueza da sintaxe de uma ER faz


diferença comparada à sintaxe restrita do LIKE. Se vê no Gráfico 2 um exemplo disto. Para o
REGEXP basta a ER ‘^[A-Z]’ para definir todas as cadeias iniciadas por uma letra
38

maiúscula. Para obter o mesmo efeito com o LIKE devemos repeti-lo vinte e seis vezes, uma
vez para cada letra, unidas pelo operador lógico OR.
Em geral, o uso de BINARY faz o REGEXP ficar mais rápido. Veja-se no gráfico 1
que os tempos de REGEXP insensível à caixa são até duas vezes maiores.

Gráfico 2: Tempos de formas equivalentes de LIKE e de REGEXP


Fonte: o próprio pesquisador, 2012

No Gráfico 3 aparece o uso de classes comparado ao uso do operador união “|”.


Nota-se que no caso da classe os resultados são lineares e constantes. O operador de união ou
alternância, chegou a ser até três vezes mais demorado.

Gráfico 3: Uso de classe comparado ao uso da união no REGEXP


Fonte: o próprio pesquisador, 2012
39

O uso de BINARY não modificou os tempos quando usado em combinação com


classes, como visto no Gráfico 4.

Gráfico 4: Uso de REGEXP BINARY combinado com uso de classe.


Fonte: o próprio pesquisador, 2012

Examinando-se a comparação entre REGEXP sensível e insensível à caixa operando


sobre uma coluna com tamanho de 64 caráteres, visto no Gráfico 5, conclui-se que a variação
para maior do tamanho da cadeia do argumento faz o REGEXP insensível ficar cerca de doze
vezes mais lento e que ‘.*’ deixa o REGEXP insensível mais demorado, mas não afeta
REGEXP BINARY.

Gráfico 5: Tempos de execução de REGEXP e REGEXP BINARY, cadeia de 64 octetos


Fonte: o próprio pesquisador, 2012
40

No teste mostrado pelo Gráfico 6, semelhante ao anterior, mas desta vez sobre uma
coluna de 255 caráteres, vê-se que os tempos quando se usa BINARY são lineares e
constantes. A razão entre a operação do REGEXP sensível e insensível à caixa chegou a seis,
o que comprovou os resultados obtidos antes.

Gráfico 6: Tempos de execução de REGEXP e REGEXP BINARY, cadeias de 255 octetos


Fonte: o próprio pesquisador, 2012

Os dados apresentados no Gráfico 7 referem-se à operações na coluna valor com


tamanho de três milhões de octetos. Quando o tamanho da cadeia chega à casa dos milhões de
octetos as diferenças entre LIKE e REGEXP se acentuam.
41

Gráfico 7: Comparação entre LIKE, REGEXP e REGEXP BINARY em cadeias extensas.


Fonte: o próprio pesquisador, 2012
42

4 CONCLUSÃO

Conclui-se que LIKE é mais rápido quando se trata de padrões simples. Isto pode ser
visto nos gráficos 1 e 7. Portanto sempre que a sintaxe permitir o LIKE deve ser usado.
Deve-se usar REGEXP BINARY sempre que possível. Os dados mostrados nos
gráficos 5 e 6 comprovam esta afirmação.
Deve-se dar preferência ao uso de classes quando esta puder substituir a união. É o
que mostram os dados do gráfico 3.
Use-se o curinga (“.”) só quando necessário, pois ele causa uma perda de
performance. O gráfico 1 apresenta dados que embasam esta orientação.
43

5 SUGESTÕES

Sugere-se, para desenvolvimento futuro, que o programa Fullfiller seja modificado e


aprimorado de forma a se tornar um aplicativo mais versátil, gerador de dados aleatórios para
preenchimento de colunas em bases de dados e como instrumento de “benchmarking”.
Seria interessante que os mesmos testes fossem feitos em outros computadores,
outros sistemas operacionais e outros bancos de dados.
Já que apenas uma ínfima parcela de combinações foi testada nesta pesquisa, se
sugere que mais testes sejam feitos.
44

REFERÊNCIAS

BARKER-PLUMMER, David. Turing Machines. The Stanford Encyclopedia of Philosophy.


Spring 2011. http://plato.stanford.edu/archives/spr2011/entries/turing-machine/. Acesso em:
17/8/2011 23:13.

CHOMSKY, Noam. On Certain Formal Properties of Grammars, Information and Control,


Volume 2, N.2, June 1959. p. 137-167. ISSN 0019-9958.

______. Three Models for the Description of Language, IRE Transactions on Information
Theory, Vol. 2, N. 3. Sept. 1956, p. 113-124. ISSN: 0096-1000.

Dicionário Priberam da Língua Portuguesa, Significado de Sintaxe. Lisboa: Priberam,


2011. <http://www.priberam.pt/dlpo/default.aspx?pal=sintaxe>. Acesso em: 25/3/2012 14:10.

ELMASRI, Ramez; NAVATHE, Shamkant. Fundamentals of database systems. 6th ed.


Boston: Addison-Wesley, 2011. ISBN 13: 978-0-136-08620-8

HOPCROFT, John E.; ULLMAN, Jeffrey D. Introduction to Automata Theory,


Languages and Computation. Reading: Addison-Wesley, 1979.

HOPCROFT, John E.; MOTWANI, Rajeev; ULLMAN, Jeffrey D. Introduction to


Automata Theory, Languages and Computation. 2nd ed. Reading: Addison-Wesley, 2001.

KELTY, Christopher M. Logical Instruments: Regular Expressions, AI and thinking about


thinking. Los Angeles: University of California, Department of Information Studies and the
Center for Society and Genetics, Dec. 2008.

KRIEGEL, Alex; TRUKHNOV, Boris M. SQL Bible. Indianapolis: Wiley, 2003.


ISBN:0764525840.

MySQL 5.5 Reference Manual. 21678th rev. Redwood City: Oracle, July 2010.

NELSON, Randal. Regular Expressions. <http://www.cs.rochester.edu/u/nelson/courses/csc


_173/fa/re.html>. Acesso em: 03/08/2011 22:31.

______. Finite Automata and Regular Expressions. <http://www.cs.rochester.edu/u/


nelson/courses /csc_173/fa/re.html>. Acesso em: 03/08/2011 22:31.

PALAZZO, Luiz A M. Linguagens Livres de Contexto. Pelotas: UCPEL, Maio 2008a.


Material de apoio.
45

______. Linguagens Regulares e Autômatos Finitos. Pelotas: UCPEL, Maio 2008b.


Material de apoio.

______. Máquina de Turing - Linguagens Sensíveis ao Contexto e Enumeráveis


Recursivamente. Pelotas: UCPEL, Maio 2007. Material de apoio.

PARÉ, Rafael Camps, et al. Bases de datos. Barcelona: Fundació per a la Universitat Oberta
de Catalunya, mayo 2005.

PIMENTEL, Graça. SCE183 - Algoritmos e Estruturas de Dados 2. Instituto de Ciências


Matemáticas e de Computação Departamento de Computação e Estatística.
<http://www.icmc.usp.br/manuals/sce183/gfmaria.html>. Acesso em: 26/9/2011 19:10.

RAMOS, M.V.M., NETO, J.J., VEGA, I.S. Linguagens Formais: Teoria, Modelagem e
Implementação. São Paulo: Bookman, 2009.

RANGEL, José Lucas. Linguagens Formais. Departamento de Informática, INF 1626 -


Linguagens Formais e Autômatos. Rio de Janeiro: PUC-RJ, jul. 1999.

RODRIGUES, Maria Rosália Dinis. Teoria da Computação. Universidade do Aveiro.


Aveiro: UA, 2009. Material de apoio.

ROWE, Denis. FOLDOC – Free On-line Dictionary Of Computing. <http://foldoc.org/>


Acessado em 12/09/2011 19:00

RUS, Teodor. Computation Theory - Decidability. The University of Iowa, Department of


Computer Science. Iowa City: 2006. Material de apoio.

SIPSER, Michael. Introduction to the Theory of Computation. Boston: Thomson, 2006.


ISBN 0-534-95097-3.
46

APÊNDICES

Apêndice 1 –Script para criação da base de dados e das tabelas

Este é o conteúdo do arquivo criabd.sql usado no “script” dos testes.

CREATE DATABASE IF NOT EXISTS `tcc`;

USE `tcc`;

DROP TABLE IF EXISTS ficha;


DROP TABLE IF EXISTS texto;

CREATE TABLE `ficha` (


`id` bigint(11) NOT NULL AUTO_INCREMENT,
`placa` char(8) DEFAULT NULL,
`nome` char(64) DEFAULT NULL,
`email` char(255) DEFAULT NULL,
PRIMARY KEY (`id`)
)
ENGINE=MyISAM
AUTO_INCREMENT=0
DEFAULT CHARSET=ascii
COMMENT='Tabela que contem placas, nomes e emails';

CREATE TABLE `texto` (


`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`valor` longtext,
PRIMARY KEY (`id`)
)
ENGINE=MYISAM
AUTO_INCREMENT=0
DEFAULT CHARSET=ascii
COMMENT='Tabela que contem textos extensos';
47

Apêndice 2 – Código fonte do Fullfiller

Classe Fullfiller
package fullfiller;

/**
* Provide facilities to automatically create, populate and execute queries on
* databases. Can act as an auxiliary tool on benchmarking commands on MySQL.
* Distributed under GNU GPL license. {@link http://www.gnu.org/copyleft/gpl.html}
*
* @version 0.2
* @author Jose Augusto Meira da Rocha {@link mailto:jose.rocha@fatec.sp.gov.br}
* @author Fatec Itaquaquecetuba {@link
http://www.centropaulasouza.sp.gov.br/Fatec/Escolas/Itaquaquecetuba.html}
* @author Fatec Itaquaquecetuba {@link mailto:dir.fatecitaqua@centropaulasouza.sp.gov.br}
*/
public class Fullfiller {

public static void main(String[] args) {

Chronometer chrono = new Chronometer();


Script script = new Script();
Dbfunctions dataBase = new Dbfunctions();
InOut io = new InOut(args[0]);

io.redirectStandardOut();
io.eventWrite("Start running Fullfiller", chrono.getElapsedSec());
chrono.start();
script.parseScript(io);
dataBase.conect(script.getMysqlUser(), script.getMysqlPass());
dataBase.useDb(script.getMysqlSchema());
script.runScript(io, dataBase);
chrono.stop();
io.eventWrite("End running Fullfiller", chrono.getElapsedSec());
System.exit(0);
}
}

Classe Chronometer
package fullfiller;

/**
* Provide facilities to measure execution times.
* Distributed under GNU GPL license. {@link http://www.gnu.org/copyleft/gpl.html}
*
* @version 0.2
* @author Jose Augusto Meira da Rocha {@link mailto:jose.rocha@fatec.sp.gov.br}
* @author Fatec Itaquaquecetuba {@link
http://www.centropaulasouza.sp.gov.br/Fatec/Escolas/Itaquaquecetuba.html}
* @author Fatec Itaquaquecetuba {@link mailto:dir.fatecitaqua@centropaulasouza.sp.gov.br}
*/

public class Chronometer {


private long miliStart, miliEnd;

public void start(){


miliStart = System.currentTimeMillis();
miliEnd = miliStart;
}

public void stop(){


miliEnd = System.currentTimeMillis();
}

public long getElapsed(){


return miliEnd-miliStart;
}

public float getElapsedSec(){


return (float)getElapsed()/1000f;
48
}
}

Classe Dbfunctions
package fullfiller;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
* Provide data base functionalities.
* Distributed under GNU GPL license. {@link http://www.gnu.org/copyleft/gpl.html}
*
* @version 0.2
* @author Jose Augusto Meira da Rocha {@link mailto:jose.rocha@fatec.sp.gov.br}
* @author Fatec Itaquaquecetuba {@link
http://www.centropaulasouza.sp.gov.br/Fatec/Escolas/Itaquaquecetuba.html}
* @author Fatec Itaquaquecetuba {@link mailto:dir.fatecitaqua@centropaulasouza.sp.gov.br}
*/
public class Dbfunctions {
private Connection connection = null;
private PreparedStatement preparedStat = null;
private ResultSet resultSet = null;
private Statement statement = null;
public Integer queryResultLines = 0;
public float queryElapsed = 0f;

/**
* Get a connection to MySQL.
*
* @param script
*/
public void conect(String user, String pass){
String conn = "jdbc:mysql://localhost/?" +
"user=" + user + "&" +
"password=" + pass;

try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(conn);
} catch (SQLException e) {
System.err.println("Error connecting to DB: " + e.getMessage());
System.exit(1);
} catch (Exception e) {
System.err.println("Error connecting to DB: " + e.getMessage());
System.exit(1);
}
}

public void useDb(String schema){


try {
statement = connection.createStatement();
resultSet = statement.executeQuery("use " + schema + ";");
} catch (SQLException e){
System.err.println("Error preparing command: " + e.getMessage());
System.exit(1);
}
}

public void createPrepComm(String comm){


try {
preparedStat = connection.prepareStatement(comm);
} catch (SQLException e){
System.err.println("Error preparing command: " + e.getMessage());
System.exit(1);
}
}

public void executePrepComm(String[] param){


try {
49
for (int i = 0; i < param.length; i++) {
preparedStat.setString(i+1, param[i]);
}
preparedStat.executeUpdate();
}catch (SQLException e){
System.err.println ("Insert failed: "+e.getMessage());
System.exit(1);
}
}

public void execQuery(){


try {
Chronometer cronoQuery = new Chronometer();
cronoQuery.start();
resultSet = preparedStat.executeQuery();
cronoQuery.stop();
resultSet.first();
queryResultLines = resultSet.getInt(1);
queryElapsed = cronoQuery.getElapsed();
} catch (SQLException es){
System.err.println("Error executing query. " + es.getMessage());
System.exit(1);
}
}
}

Classe InOut
package fullfiller;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
* Provide functionalities to deal with files.
* Distributed under GNU GPL license. {@link http://www.gnu.org/copyleft/gpl.html}
*
* @version 0.2
* @author Jose Augusto Meira da Rocha {@link mailto:jose.rocha@fatec.sp.gov.br}
* @author Fatec Itaquaquecetuba {@link
http://www.centropaulasouza.sp.gov.br/Fatec/Escolas/Itaquaquecetuba.html}
* @author Fatec Itaquaquecetuba {@link mailto:dir.fatecitaqua@centropaulasouza.sp.gov.br}
*/
public final class InOut {

File stdoutFile; // This file gets the standard output stream


BufferedReader scriptBuffReader = null;
BufferedWriter resultBuffWriter = null;
private SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private String scriptName;
public String line;

/**
* Create a buffer reader for the script file.
*/
public void openScriptFile(){
try {
scriptBuffReader = new BufferedReader(new FileReader(new File(scriptName)));
}catch (IOException e){
System.err.print("Error opening script file: "+e.getMessage());
System.exit(1);
}
}

/**
* Closes the script buffer reader.
*/
public void closeScriptFile(){
try {
scriptBuffReader.close();
}catch (IOException e){
System.err.print("Error closing script file:"+e.getMessage());
System.exit(1);
}
}
50

/**
* Create a buffer writer for the result file.
*/
public void openResultFile(){
try {
resultBuffWriter = new BufferedWriter(new FileWriter(new File("result.csv"),
true));
}catch (IOException e){
System.err.print("Error opening result file: "+e.getMessage());
System.exit(1);
}
}

public void closeResultFile(){


try{
resultBuffWriter.close();
}catch(IOException e){
System.err.print("Error closing result file: "+e.getMessage());
System.exit(1);
}
}

/**
* Redirects the standard output, in order to get and preserve outputs into
* a file.
*/
public void redirectStandardOut(){
stdoutFile = new File("FFlog.log");
try{
PrintStream ps = new PrintStream(new FileOutputStream(stdoutFile));
System.setOut(ps);
}catch (IOException e){
System.err.println ("Error redirecting standard Out: "+e.getMessage());
System.exit(1);
}
}

/**
* Write a message on result file.
*
* @param line The message to be wrote.
*/
public void outputResult(String line){
try{
resultBuffWriter.write(line);
resultBuffWriter.newLine();
}catch (IOException e){
System.err.println("Error writing result: "+e.getMessage());
System.exit(1);
}
}

/**
* Read a line from the script file.
*
* @return the line read
*/
public String readScript(){
try {
if (scriptBuffReader.ready()){
return scriptBuffReader.readLine();
}
}catch (IOException e){
System.err.println ("Error reading script file: "+e.getMessage());
System.exit(1);
}
return "";
}

/**
* Issue a message on standard output.
*
* @param event The event that happend.
* @param segs The duration (in seconds) of the event.
*/
51
public void eventWrite(String event, float segs){
System.out.printf("%s "+event+" (%.4fs)\n",
formato.format(Calendar.getInstance().getTime()), segs);
}

/**
* Constructor of the class.
* @param file Script file name.
*/
public InOut(String file) {
setScriptName(file);
}

public String getScriptName() {


return scriptName;
}

public void setScriptName(String scriptName) {


this.scriptName = scriptName;
}

Classe Script
package fullfiller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ListIterator;
import nl.flotsam.xeger.Xeger;

/**
* Provide functions to parse the script and run commands on it.
* Distributed under GNU GPL license. {@link http://www.gnu.org/copyleft/gpl.html}
*
* @version 0.2
* @author Jose Augusto Meira da Rocha {@link mailto:jose.rocha@fatec.sp.gov.br}
* @author Fatec Itaquaquecetuba {@link
http://www.centropaulasouza.sp.gov.br/Fatec/Escolas/Itaquaquecetuba.html}
* @author Fatec Itaquaquecetuba {@link mailto:dir.fatecitaqua@centropaulasouza.sp.gov.br}
*/
public class Script {

private ArrayList<String> Mails = new ArrayList<>();


private ArrayList<String> Names = new ArrayList<>();
private ArrayList<String> Texts = new ArrayList<>();
private ArrayList<String> Tests = new ArrayList<>();
private ArrayList<String> Actions = new ArrayList<>();
private ArrayList<Integer> counterName = new ArrayList<>();
private ArrayList<Integer> counterEmail = new ArrayList<>();
private ArrayList<Integer> counterText = new ArrayList<>();
public HashMap<String, Integer> counterLines = new HashMap<>();
private Iterator<String> iterAction;
private String mysqlSchema = "";
private String mysqlUser = "";
private String mysqlPass = "";
private String command = "";
private String argument = "";
private String argCampos[] = null;
private int scriptLine;
boolean scriptError = false;

public void parseScript(InOut io){


io.openScriptFile();
String line;
scriptLine = 0;
while (true){
++scriptLine;
line = io.readScript();
if (line.equals("")){
52
break;
}
processCommand(line);
}
if (scriptError){
help();
System.exit(1);
}
io.closeScriptFile();
}

private void processCommand(String arg){


argCampos = arg.split(String.valueOf((char)29));

command = argCampos[0];
if (command.startsWith("#") || command.equals("")){
return;
}
argument = argCampos[1];
switch (command){
case "name":
setNames(argument);
return;
case "emai":
setMails(argument);
return;
case "text":
setTexts(argument);
return;
case "test":
setTests(argument);
return;
case "crea":
case "comm":
case "exec":
setActions(arg);
return;
case "sche":
setMysqlSchema(argument);
return;
case "user":
setMysqlUser(argument);
return;
case "pass":
setMysqlPass(argument);
return;
default:
System.err.println("");
System.err.println("Unrecognized command '" + command + "' on line " +
scriptLine);
scriptError = true;
}
}

private void runTests(InOut io, Dbfunctions dbFuncs, int repet){


String strQuery, linha;
long somaMilis = 0;
float media;
int contador = 0;

contaLinhas(dbFuncs);
Chronometer chrono = new Chronometer();
io.openResultFile();
io.eventWrite("Executing tests", chrono.getElapsedSec());

chrono.start();

for (Iterator<String> it = Tests.iterator(); it.hasNext();) {


String teste[] = it.next().split("\t");
strQuery = "SELECT count(*) FROM ";
strQuery += teste[0]; // tabela
strQuery += " WHERE ";
strQuery += teste[1]; // coluna
strQuery += " ";
strQuery += teste[2]; // operador
strQuery += " '";
strQuery += teste[3]; // ER
53
strQuery += "'";
somaMilis = 0;

dbFuncs.createPrepComm(strQuery);
for (int i=0; i<repet; i++){
dbFuncs.execQuery();
somaMilis += dbFuncs.queryElapsed;
}
media = ((float)somaMilis / (float)repet);

linha = ++contador + ";" + // linha


dbFuncs.queryResultLines + ";" + // registros
media + ";" + // média
(media / (float)counterLines.get(teste[0]) * 1000f) + ";" + // micro
s/linha
somaMilis + ";" + // ms
repet + ";" + // repet
counterLines.get(teste[0]) + ";" + // count
strQuery; // query
io.outputResult(linha);
}
chrono.stop();
io.eventWrite("End of tests", chrono.getElapsedSec());
io.closeResultFile();
}

public void runScript(InOut io, Dbfunctions dbFuncs){


int level = 0;
int repet = 0;
iterAction = Actions.iterator();
Chronometer runChrono = new Chronometer();
io.eventWrite("Executing script " + io.getScriptName(), runChrono.getElapsedSec());
runChrono.start();

while (iterAction.hasNext()){
String action[] = iterAction.next().split(String.valueOf((char)29));
command = action[0];

switch (command){
case "crea":
level = Integer.parseInt(action[1]);
geraTabelaFicha(io, dbFuncs, level);
geraTabelaTexto(io, dbFuncs, level);
break;
case "comm":
argument = action[1];
runOsCommand(io, argument);
break;
case "exec":
repet = Integer.parseInt(action[1]);
runTests(io, dbFuncs, repet);
break;
default:
System.err.println ("Error executing script:" + command);
System.exit(1);
}
}
runChrono.stop();
io.eventWrite("Script executed", runChrono.getElapsedSec());
}

private void runOsCommand(InOut io, String argument){


String osCommand = null;
Chronometer chrono = new Chronometer();
io.eventWrite("Executing command " + argument, chrono.getElapsedSec());
chrono.start();
try {
osCommand = "cmd /c " + argument;
Process runCommand = Runtime.getRuntime().exec(osCommand);
BufferedReader stdError = new BufferedReader(new
InputStreamReader(runCommand.getErrorStream()));
String errLine = stdError.readLine();
if (errLine != null) {
System.err.println("Error reading sql script: "+errLine);
System.exit(1);
}
}
54
catch (IOException e) {
System.err.println("Error creating database: "+e.getMessage());
System.exit(1);
}
chrono.stop();
io.eventWrite("Command executed", chrono.getElapsedSec());
}

private void geraTabelaFicha(InOut io, Dbfunctions dbFuncs, int niv){


char a;
char b;
char c;
int ind = 0;
int contaProducao = 0;
String column[] = {"", "", ""};
Chronometer chrono = new Chronometer();
ArrayList<Xeger> nameGenerator = new ArrayList<>();
ArrayList<Xeger> emailGenerator = new ArrayList<>();

for (Iterator<String> it = Names.iterator(); it.hasNext();) {


nameGenerator.add(new Xeger(it.next()));
counterName.add(0);
}
for (Iterator<String> it = Mails.iterator(); it.hasNext();) {
emailGenerator.add(new Xeger(it.next()));
counterEmail.add(0);
}

io.eventWrite("Populating table ficha at level " + niv + ".", chrono.getElapsedSec());


chrono.start();
dbFuncs.createPrepComm("INSERT INTO ficha (placa, nome, email) VALUES(?, ?, ?);");

for (int x=0;x<(Math.pow(10, niv));x++){


for (int i=65;i<91;i++){
a = (char)i;
for (int j=65;j<91;j++){
b = (char)j;
for (int k=65;k<91;k++){
c = (char)k;
column[0] = "" + a + b + c + Integer.toString(10000+x).substring(1,5);
contaProducao++;
ind = contaProducao%nameGenerator.size();
column[1] = nameGenerator.get(ind).generate();
counterName.set(ind, counterName.get(ind)+1);
ind = contaProducao%emailGenerator.size();
column[2] = emailGenerator.get(ind).generate();
counterEmail.set(ind, counterEmail.get(ind)+1);
dbFuncs.executePrepComm(column);
}
}
}
}
chrono.stop();
io.eventWrite("Table ficha filled with "+(int)(17576*Math.pow(10, niv))+" lines.",
chrono.getElapsedSec());
System.out.printf("%9.0f expressions of language Lp0([A-Z]{3}[0-9]{4})\n",
17576*Math.pow(10, niv));

for (ListIterator<String> it = Names.listIterator(); it.hasNext();) {


System.out.printf("%9d expressions of language Ln%d(%s)\n",
counterName.get(it.nextIndex()), it.nextIndex(), it.next());
}
for (ListIterator<String> it = Mails.listIterator(); it.hasNext();) {
System.out.printf("%9d expressions of language Le%d(%s)\n",
counterEmail.get(it.nextIndex()), it.nextIndex(), it.next());
}
}

private void geraTabelaTexto(InOut io, Dbfunctions dbFuncs, int niv){


String column[] = {""};
int maxLen = (niv + 1) * 1000000;
int textGenerator = 0;
Chronometer chrono = new Chronometer();
ArrayList<Xeger> geradorTexto = new ArrayList<>();

chrono.start();
for (Iterator<String> it = Texts.iterator(); it.hasNext();) {
55
geradorTexto.add(new Xeger(it.next()));
counterText.add(0);
}
io.eventWrite("Filling table Texto at level " + niv, chrono.getElapsedSec());
dbFuncs.createPrepComm("INSERT INTO texto (conteudo) VALUES(?);");

column[0] = ".primeiracadeia.";
for (int i=0; column[0].length()<maxLen; i++){
textGenerator = i%geradorTexto.size();
column[0] += geradorTexto.get(textGenerator).generate();
counterText.set(textGenerator, counterText.get(textGenerator)+1);
}
column[0] += ".ultimacadeia.";

dbFuncs.executePrepComm(column);
chrono.stop();
io.eventWrite("Table Texto filled with 1 line of around "+maxLen+" bytes.",
chrono.getElapsedSec());
for (ListIterator<String> it = Texts.listIterator(); it.hasNext();) {
System.out.printf("%9d expressions of language Lt%d(%s)\n",
counterText.get(it.nextIndex()), it.nextIndex(), it.next());
}
}

public void contaLinhas(Dbfunctions dbFuncs){


counterLines.clear();
for (Iterator<String> it = Tests.iterator(); it.hasNext();) {
String teste[] = it.next().split("\t");
if (!counterLines.containsKey(teste[0])){
dbFuncs.createPrepComm("SELECT count(*) FROM " + teste[0] + ";");
dbFuncs.execQuery();
counterLines.put(teste[0],dbFuncs.queryResultLines);
}
}
}

private void help(){


System.err.println("");
System.err.println("Use of Fullfiller:");
System.err.println("java -Xss64M -jar fullfiller.jar scriptfile");
System.err.println("Options on file 'scriptfile' (each on a single line):");
System.err.println("# = comment");
System.err.println("comm = execute OS command");
System.err.println("crea = create DB [default level 0]");
System.err.println("emai = regular expression for emails [default '']");
System.err.println("exec = execute tests");
System.err.println("name = regular expression for names [default '']");
System.err.println("pass = user password [default '']");
System.err.println("sche = schema name on MySQL");
System.err.println("test = test to be done");
System.err.println("text = regular expression for text [default '']");
System.err.println("user = user on DB [default '']");
System.err.println("");
}

private void setMails(String regexp) {


Mails.add(regexp);
}

private void setNames(String regexp) {


Names.add(regexp);
}

private void setTexts(String regexp) {


Texts.add(regexp);
}

private void setTests(String regexp) {


Tests.add(regexp);
}

private void setActions(String regexp) {


Actions.add(regexp);
}

public String getMysqlSchema() {


return mysqlSchema;
56
}

public void setMysqlSchema(String mysqlSchema) {


this.mysqlSchema = mysqlSchema;
}

public String getMysqlUser() {


return mysqlUser;
}

public void setMysqlUser(String mysqlUser) {


this.mysqlUser = mysqlUser;
}

public String getMysqlPass() {


return mysqlPass;
}

public void setMysqlPass(String mysqlPass) {


this.mysqlPass = mysqlPass;
}

}
57

Apêndice 3 – Instruções para reproduzir os testes.

Os pré-requisitos para executar os testes são, em tese, um computador com a


máquina virtual Java e o MySQL instalados.
Deve-se descarregar os arquivos do endereço http://sourceforge.net/projects/fullfiller
/files/dist/ e salvar localmente mantendo a mesma estrutura. Abrir uma janela de comandos e
ir para o diretório onde foi salvo o Fullfiller. Executar o programa emitindo o comando “java
–jar fullfiller.jar script.txt”.
A pasta “dist” contém o programa Fullfiller executável, os “scripts” de criação do
banco e do conjunto de testes, e as bibliotecas necessárias.
58

Apêndice 4 – Relação dos comandos executados nos testes.

Ord Tabela Coluna Operador / argumento


1 ficha placa LIKE 'AAA'
2 ficha placa LIKE 'AAA%'
3 ficha placa LIKE '%AAA%'
4 ficha placa LIKE 'AAA____'
5 ficha placa LIKE 'AAA0000'
6 ficha placa LIKE '%0'
7 ficha placa LIKE '______0'
8 ficha placa LIKE '_______'
9 ficha placa LIKE 'A%' OR placa LIKE 'B%' OR placa LIKE 'C%' OR placa LIKE 'D%' OR placa
LIKE 'E%' OR placa LIKE 'F%' OR placa LIKE 'G%' OR placa LIKE 'H%' OR placa
LIKE 'I%' OR placa LIKE 'J%' OR placa LIKE 'K%' OR placa LIKE 'L%' OR placa
LIKE 'M%' OR placa LIKE 'N%' OR placa LIKE 'O%' OR placa LIKE 'P%' OR placa
LIKE 'Q%' OR placa LIKE 'R%' OR placa LIKE 'S%' OR placa LIKE 'T%' OR placa
LIKE 'U%' OR placa LIKE 'V%' OR placa LIKE 'W%' OR placa LIKE 'X%' OR placa
LIKE 'Y%' OR placa LIKE 'Z%'
10 ficha placa REGEXP '^AAA$'
11 ficha placa REGEXP '^AAA'
12 ficha placa REGEXP 'AAA'
13 ficha placa REGEXP '^AAA....'
14 ficha placa REGEXP 'AAA0000'
15 ficha placa REGEXP '0$'
16 ficha placa REGEXP '......0'
17 ficha placa REGEXP '.......'
18 ficha placa REGEXP '^A.*'
19 ficha placa REGEXP '^AA.*'
20 ficha placa REGEXP '^AAA.*'
21 ficha placa REGEXP BINARY '^AAA$'
22 ficha placa REGEXP BINARY '^AAA'
23 ficha placa REGEXP BINARY 'AAA'
24 ficha placa REGEXP BINARY '^AAA....'
25 ficha placa REGEXP BINARY 'AAA0000'
26 ficha placa REGEXP BINARY '9$'
27 ficha placa REGEXP BINARY '......9'
28 ficha placa REGEXP BINARY '.......'
29 ficha placa REGEXP BINARY '^A.*'
30 ficha placa REGEXP BINARY '^AA.*'
31 ficha placa REGEXP BINARY '^AAA.*'
32 ficha placa REGEXP '^[^A-Y].*'
33 ficha placa REGEXP '^[A-Y].*'
34 ficha placa REGEXP '^[Z].*'
35 ficha placa REGEXP '^[^Z].*'
36 ficha placa REGEXP '^[A-Z].*'
37 ficha placa REGEXP '^[A-Z].*[0-9]$'
38 ficha placa REGEXP '^[A-Z]{3}.*[0-9]$'
39 ficha placa REGEXP '^[A-Z]{3}[0-9]{4}'
40 ficha placa REGEXP '^[A]'
41 ficha placa REGEXP '^[A-B]'
42 ficha placa REGEXP '^[A-C]'
43 ficha placa REGEXP '^[A-D]'
44 ficha placa REGEXP '^[A-E]'
45 ficha placa REGEXP '^[A-F]'
46 ficha placa REGEXP '^[A-G]'
47 ficha placa REGEXP '^[A-H]'
48 ficha placa REGEXP '^[A-I]'
49 ficha placa REGEXP '^[A-J]'
50 ficha placa REGEXP '^[A-K]'
51 ficha placa REGEXP '^[A-L]'
52 ficha placa REGEXP '^[A-M]'
53 ficha placa REGEXP '^[A-N]'
54 ficha placa REGEXP '^[A-O]'
55 ficha placa REGEXP '^[A-P]'
56 ficha placa REGEXP '^[A-Q]'
57 ficha placa REGEXP '^[A-R]'
58 ficha placa REGEXP '^[A-S]'
59 ficha placa REGEXP '^[A-T]'
60 ficha placa REGEXP '^[A-U]'
61 ficha placa REGEXP '^[A-V]'
62 ficha placa REGEXP '^[A-W]'
63 ficha placa REGEXP '^[A-X]'
64 ficha placa REGEXP '^[A-Y]'
65 ficha placa REGEXP '^[A-Z]'
59

Ord Tabela Coluna Operador / argumento


66 ficha placa REGEXP BINARY '^[A-B]'
67 ficha placa REGEXP BINARY '^[A-G]'
68 ficha placa REGEXP BINARY '^[A-J]'
69 ficha placa REGEXP BINARY '^[A-M]'
70 ficha placa REGEXP BINARY '^[A-P]'
71 ficha placa REGEXP BINARY '^[A-S]'
72 ficha placa REGEXP BINARY '^[A-V]'
73 ficha placa REGEXP BINARY '^[A-Y]'
74 ficha placa REGEXP '^(A)'
75 ficha placa REGEXP '^(A|B)'
76 ficha placa REGEXP '^(A|B|C)'
77 ficha placa REGEXP '^(A|B|C|D)'
78 ficha placa REGEXP '^(A|B|C|D|E)'
79 ficha placa REGEXP '^(A|B|C|D|E|F)'
80 ficha placa REGEXP '^(A|B|C|D|E|F|G)'
81 ficha placa REGEXP '^(A|B|C|D|E|F|G|H)'
82 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I)'
83 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J)'
84 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K)'
85 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L)'
86 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M)'
87 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N)'
88 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O)'
89 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P)'
90 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q)'
91 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R)'
92 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S)'
93 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T)'
94 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U)'
95 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V)'
96 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W)'
97 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X)'
98 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y)'
99 ficha placa REGEXP '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z)'
100 ficha placa REGEXP BINARY '^(A|B)'
101 ficha placa REGEXP BINARY '^(A|B|C|D)'
102 ficha placa REGEXP BINARY '^(A|B|C|D|E|F)'
103 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H)'
104 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J)'
105 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L)'
106 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N)'
107 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P)'
108 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R)'
109 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T)'
110 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V)'
111 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X)'
112 ficha placa REGEXP BINARY '^(A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z)'
113 ficha nome LIKE 'Jose Silva'
114 ficha nome LIKE '%Jose Silva%'
115 ficha nome LIKE 'Jose %Silva%'
116 ficha nome LIKE '%Jose %Silva%'
117 ficha nome REGEXP '^Jose Silva$'
118 ficha nome REGEXP 'Jose Silva'
119 ficha nome REGEXP 'Jose .*Silva'
120 ficha nome REGEXP BINARY '^Jose Silva$'
121 ficha nome REGEXP BINARY 'Jose Silva'
122 ficha nome REGEXP BINARY 'Jose .*Silva'
123 ficha nome LIKE 'Mariquinha Carolyn da Santanowsky'
124 ficha nome LIKE '%Mariquinha Carolyn da Santanowsky%'
125 ficha nome REGEXP '^Mariquinha Carolyn da Santanowsky$'
126 ficha nome REGEXP 'Mariquinha Carolyn da Santanowsky'
127 ficha nome REGEXP 'Mariquinha Carolyn da Santanowsky.*'
128 ficha nome REGEXP BINARY '^Mariquinha Carolyn da Santanowsky$'
129 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Santanowsky'
130 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Santanowsky.*'
131 ficha nome REGEXP 'Mar'
132 ficha nome REGEXP 'Mariqu'
133 ficha nome REGEXP 'Mariquinh'
134 ficha nome REGEXP 'Mariquinha C'
135 ficha nome REGEXP 'Mariquinha Caro'
136 ficha nome REGEXP 'Mariquinha Carolyn'
137 ficha nome REGEXP 'Mariquinha Carolyn da'
138 ficha nome REGEXP 'Mariquinha Carolyn da Sa'
139 ficha nome REGEXP 'Mariquinha Carolyn da Santa'
140 ficha nome REGEXP 'Mariquinha Carolyn da Santanow'
60

Ord Tabela Coluna Operador / argumento


141 ficha nome REGEXP 'Mar.*'
142 ficha nome REGEXP 'Mariqu.*'
143 ficha nome REGEXP 'Mariquinh.*'
144 ficha nome REGEXP 'Mariquinha C.*'
145 ficha nome REGEXP 'Mariquinha Caro.*'
146 ficha nome REGEXP 'Mariquinha Carolyn.*'
147 ficha nome REGEXP 'Mariquinha Carolyn da.*'
148 ficha nome REGEXP 'Mariquinha Carolyn da Sa.*'
149 ficha nome REGEXP 'Mariquinha Carolyn da Santa.*'
150 ficha nome REGEXP 'Mariquinha Carolyn da Santanow.*'
151 ficha nome REGEXP BINARY 'Mar'
152 ficha nome REGEXP BINARY 'Mariqu'
153 ficha nome REGEXP BINARY 'Mariquinh'
154 ficha nome REGEXP BINARY 'Mariquinha C'
155 ficha nome REGEXP BINARY 'Mariquinha Caro'
156 ficha nome REGEXP BINARY 'Mariquinha Carolyn'
157 ficha nome REGEXP BINARY 'Mariquinha Carolyn da'
158 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Sa'
159 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Santa'
160 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Santanow'
161 ficha nome REGEXP BINARY 'Mar.*'
162 ficha nome REGEXP BINARY 'Mariqu.*'
163 ficha nome REGEXP BINARY 'Mariquinh.*'
164 ficha nome REGEXP BINARY 'Mariquinha C.*'
165 ficha nome REGEXP BINARY 'Mariquinha Caro.*'
166 ficha nome REGEXP BINARY 'Mariquinha Carolyn.*'
167 ficha nome REGEXP BINARY 'Mariquinha Carolyn da.*'
168 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Sa.*'
169 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Santa.*'
170 ficha nome REGEXP BINARY 'Mariquinha Carolyn da Santanow.*'
171 ficha nome REGEXP 'a'
172 ficha nome REGEXP 'ab'
173 ficha nome REGEXP 'abc'
174 ficha nome REGEXP 'abcd'
175 ficha nome REGEXP 'abcde'
176 ficha nome REGEXP 'abcdef'
177 ficha nome REGEXP 'abcdefg'
178 ficha nome REGEXP 'abcdefgh'
179 ficha nome REGEXP 'abcdefghi'
180 ficha nome REGEXP 'abcdefghij'
181 ficha nome REGEXP 'abcdefghijk'
182 ficha nome REGEXP 'abcdefghijkl'
183 ficha nome REGEXP 'abcdefghijklm'
184 ficha nome REGEXP 'abcdefghijklmn'
185 ficha nome REGEXP 'abcdefghijklmno'
186 ficha nome REGEXP 'abcdefghijklmnop'
187 ficha nome REGEXP 'abcdefghijklmnopq'
188 ficha nome REGEXP 'abcdefghijklmnopqr'
189 ficha nome REGEXP 'abcdefghijklmnopqrs'
190 ficha nome REGEXP 'abcdefghijklmnopqrst'
191 ficha nome REGEXP 'abcdefghijklmnopqrstu'
192 ficha nome REGEXP 'abcdefghijklmnopqrstuv'
193 ficha nome REGEXP 'abcdefghijklmnopqrstuvw'
194 ficha nome REGEXP 'abcdefghijklmnopqrstuvwx'
195 ficha nome REGEXP 'abcdefghijklmnopqrstuvwxy'
196 ficha nome REGEXP 'abcdefghijklmnopqrstuvwxyz'
197 ficha nome REGEXP BINARY 'ab'
198 ficha nome REGEXP BINARY 'abcd'
199 ficha nome REGEXP BINARY 'abcdef'
200 ficha nome REGEXP BINARY 'abcdefgh'
201 ficha nome REGEXP BINARY 'abcdefghij'
202 ficha nome REGEXP BINARY 'abcdefghijkl'
203 ficha nome REGEXP BINARY 'abcdefghijklmn'
204 ficha nome REGEXP BINARY 'abcdefghijklmnop'
205 ficha nome REGEXP BINARY 'abcdefghijklmnopqr'
206 ficha nome REGEXP BINARY 'abcdefghijklmnopqrst'
207 ficha nome REGEXP BINARY 'abcdefghijklmnopqrstuv'
208 ficha nome REGEXP BINARY 'abcdefghijklmnopqrstuvwx'
209 ficha nome REGEXP BINARY 'abcdefghijklmnopqrstuvwxyz'
210 ficha nome REGEXP 'ab.*'
211 ficha nome REGEXP 'abcd.*'
212 ficha nome REGEXP 'abcdef.*'
213 ficha nome REGEXP 'abcdefgh.*'
214 ficha nome REGEXP 'abcdefghij.*'
215 ficha nome REGEXP 'abcdefghijkl.*'
61

Ord Tabela Coluna Operador / argumento


216 ficha nome REGEXP 'abcdefghijklmn.*'
217 ficha nome REGEXP 'abcdefghijklmnop.*'
218 ficha nome REGEXP 'abcdefghijklmnopqr.*'
219 ficha nome REGEXP 'abcdefghijklmnopqrst.*'
220 ficha nome REGEXP 'abcdefghijklmnopqrstuv.*'
221 ficha nome REGEXP 'abcdefghijklmnopqrstuvwx.*'
222 ficha nome REGEXP 'abcdefghijklmnopqrstuvwxyz.*'
223 ficha nome REGEXP BINARY 'ab.*'
224 ficha nome REGEXP BINARY 'abcd.*'
225 ficha nome REGEXP BINARY 'abcdef.*'
226 ficha nome REGEXP BINARY 'abcdefgh.*'
227 ficha nome REGEXP BINARY 'abcdefghij.*'
228 ficha nome REGEXP BINARY 'abcdefghijkl.*'
229 ficha nome REGEXP BINARY 'abcdefghijklmn.*'
230 ficha nome REGEXP BINARY 'abcdefghijklmnop.*'
231 ficha nome REGEXP BINARY 'abcdefghijklmnopqr.*'
232 ficha nome REGEXP BINARY 'abcdefghijklmnopqrst.*'
233 ficha nome REGEXP BINARY 'abcdefghijklmnopqrstuv.*'
234 ficha nome REGEXP BINARY 'abcdefghijklmnopqrstuvwx.*'
235 ficha nome REGEXP BINARY 'abcdefghijklmnopqrstuvwxyz.*'
236 ficha email REGEXP 'a'
237 ficha email REGEXP 'ab'
238 ficha email REGEXP 'abc'
239 ficha email REGEXP 'abcd'
240 ficha email REGEXP 'abcde'
241 ficha email REGEXP 'abcdef'
242 ficha email REGEXP 'abcdefg'
243 ficha email REGEXP 'abcdefgh'
244 ficha email REGEXP 'abcdefghi'
245 ficha email REGEXP 'abcdefghij'
246 ficha email REGEXP 'abcdefghijk'
247 ficha email REGEXP 'abcdefghijkl'
248 ficha email REGEXP 'abcdefghijklm'
249 ficha email REGEXP 'abcdefghijklmn'
250 ficha email REGEXP 'abcdefghijklmno'
251 ficha email REGEXP 'abcdefghijklmnop'
252 ficha email REGEXP 'abcdefghijklmnopq'
253 ficha email REGEXP 'abcdefghijklmnopqr'
254 ficha email REGEXP 'abcdefghijklmnopqrs'
255 ficha email REGEXP 'abcdefghijklmnopqrst'
256 ficha email REGEXP 'abcdefghijklmnopqrstu'
257 ficha email REGEXP 'abcdefghijklmnopqrstuv'
258 ficha email REGEXP 'abcdefghijklmnopqrstuvw'
259 ficha email REGEXP 'abcdefghijklmnopqrstuvwx'
260 ficha email REGEXP 'abcdefghijklmnopqrstuvwxy'
261 ficha email REGEXP 'abcdefghijklmnopqrstuvwxyz'
262 ficha email REGEXP BINARY 'ab'
263 ficha email REGEXP BINARY 'abcd'
264 ficha email REGEXP BINARY 'abcdef'
265 ficha email REGEXP BINARY 'abcdefgh'
266 ficha email REGEXP BINARY 'abcdefghij'
267 ficha email REGEXP BINARY 'abcdefghijkl'
268 ficha email REGEXP BINARY 'abcdefghijklmn'
269 ficha email REGEXP BINARY 'abcdefghijklmnop'
270 ficha email REGEXP BINARY 'abcdefghijklmnopqr'
271 ficha email REGEXP BINARY 'abcdefghijklmnopqrst'
272 ficha email REGEXP BINARY 'abcdefghijklmnopqrstuv'
273 ficha email REGEXP BINARY 'abcdefghijklmnopqrstuvwx'
274 ficha email REGEXP BINARY 'abcdefghijklmnopqrstuvwxyz'
275 ficha email REGEXP 'ab.*'
276 ficha email REGEXP 'abcd.*'
277 ficha email REGEXP 'abcdef.*'
278 ficha email REGEXP 'abcdefgh.*'
279 ficha email REGEXP 'abcdefghij.*'
280 ficha email REGEXP 'abcdefghijkl.*'
281 ficha email REGEXP 'abcdefghijklmn.*'
282 ficha email REGEXP 'abcdefghijklmnop.*'
283 ficha email REGEXP 'abcdefghijklmnopqr.*'
284 ficha email REGEXP 'abcdefghijklmnopqrst.*'
285 ficha email REGEXP 'abcdefghijklmnopqrstuv.*'
286 ficha email REGEXP 'abcdefghijklmnopqrstuvwx.*'
287 ficha email REGEXP 'abcdefghijklmnopqrstuvwxyz.*'
288 ficha email REGEXP BINARY 'ab.*'
289 ficha email REGEXP BINARY 'abcd.*'
290 ficha email REGEXP BINARY 'abcdef.*'
62

Ord Tabela Coluna Operador / argumento


291 ficha email REGEXP BINARY 'abcdefgh.*'
292 ficha email REGEXP BINARY 'abcdefghij.*'
293 ficha email REGEXP BINARY 'abcdefghijkl.*'
294 ficha email REGEXP BINARY 'abcdefghijklmn.*'
295 ficha email REGEXP BINARY 'abcdefghijklmnop.*'
296 ficha email REGEXP BINARY 'abcdefghijklmnopqr.*'
297 ficha email REGEXP BINARY 'abcdefghijklmnopqrst.*'
298 ficha email REGEXP BINARY 'abcdefghijklmnopqrstuv.*'
299 ficha email REGEXP BINARY 'abcdefghijklmnopqrstuvwx.*'
300 ficha email REGEXP BINARY 'abcdefghijklmnopqrstuvwxyz.*'
301 texto valor LIKE '.primeiracadeia.%'
302 texto valor LIKE '%.primeiracadeia.%'
303 texto valor LIKE '%.ultimacadeia.'
304 texto valor LIKE '%.ultimacadeia.%'
305 texto valor REGEXP '^\.primeiracadeia\.'
306 texto valor REGEXP '\.primeiracadeia\.'
307 texto valor REGEXP '\.ultimacadeia\.$'
308 texto valor REGEXP '\.ultimacadeia\.'
309 texto valor REGEXP BINARY '^\.primeiracadeia\.'
310 texto valor REGEXP BINARY '\.primeiracadeia\.'
311 texto valor REGEXP BINARY '\.ultimacadeia\.$'
312 texto valor REGEXP BINARY '\.ultimacadeia\.'
313 texto valor LIKE 'o rato roeu a roupa do rei de roma'
314 texto valor LIKE '%o rato roeu a roupa do rei de roma%'
315 texto valor REGEXP '^o rato roeu a roupa do rei de roma$'
316 texto valor REGEXP 'o rato roeu a roupa do rei de roma'
317 texto valor REGEXP BINARY '^o rato roeu a roupa do rei de roma$'
318 texto valor REGEXP BINARY 'o rato roeu a roupa do rei de roma'
319 texto valor REGEXP 'a'
320 texto valor REGEXP 'ab'
321 texto valor REGEXP 'abc'
322 texto valor REGEXP 'abcd'
323 texto valor REGEXP 'abcde'
324 texto valor REGEXP 'abcdef'
325 texto valor REGEXP 'abcdefg'
326 texto valor REGEXP 'abcdefgh'
327 texto valor REGEXP 'abcdefghi'
328 texto valor REGEXP 'abcdefghij'
329 texto valor REGEXP 'abcdefghijk'
330 texto valor REGEXP 'abcdefghijkl'
331 texto valor REGEXP 'abcdefghijklm'
332 texto valor REGEXP 'abcdefghijklmn'
333 texto valor REGEXP 'abcdefghijklmno'
334 texto valor REGEXP 'abcdefghijklmnop'
335 texto valor REGEXP 'abcdefghijklmnopq'
336 texto valor REGEXP 'abcdefghijklmnopqr'
337 texto valor REGEXP 'abcdefghijklmnopqrs'
338 texto valor REGEXP 'abcdefghijklmnopqrst'
339 texto valor REGEXP 'abcdefghijklmnopqrstu'
340 texto valor REGEXP 'abcdefghijklmnopqrstuv'
341 texto valor REGEXP 'abcdefghijklmnopqrstuvw'
342 texto valor REGEXP 'abcdefghijklmnopqrstuvwx'
343 texto valor REGEXP 'abcdefghijklmnopqrstuvwxy'
344 texto valor REGEXP 'abcdefghijklmnopqrstuvwxyz'
345 texto valor REGEXP BINARY 'ab'
346 texto valor REGEXP BINARY 'abcd'
347 texto valor REGEXP BINARY 'abcdef'
348 texto valor REGEXP BINARY 'abcdefgh'
349 texto valor REGEXP BINARY 'abcdefghij'
350 texto valor REGEXP BINARY 'abcdefghijkl'
351 texto valor REGEXP BINARY 'abcdefghijklmn'
352 texto valor REGEXP BINARY 'abcdefghijklmnop'
353 texto valor REGEXP BINARY 'abcdefghijklmnopqr'
354 texto valor REGEXP BINARY 'abcdefghijklmnopqrst'
355 texto valor REGEXP BINARY 'abcdefghijklmnopqrstuv'
356 texto valor REGEXP BINARY 'abcdefghijklmnopqrstuvwx'
357 texto valor REGEXP BINARY 'abcdefghijklmnopqrstuvwxyz'
358 texto valor REGEXP 'ab.*'
359 texto valor REGEXP 'abcd.*'
360 texto valor REGEXP 'abcdef.*'
361 texto valor REGEXP 'abcdefgh.*'
362 texto valor REGEXP 'abcdefghij.*'
363 texto valor REGEXP 'abcdefghijkl.*'
364 texto valor REGEXP 'abcdefghijklmn.*'
365 texto valor REGEXP 'abcdefghijklmnop.*'
63

Ord Tabela Coluna Operador / argumento


366 texto valor REGEXP 'abcdefghijklmnopqr.*'
367 texto valor REGEXP 'abcdefghijklmnopqrst.*'
368 texto valor REGEXP 'abcdefghijklmnopqrstuv.*'
369 texto valor REGEXP 'abcdefghijklmnopqrstuvwx.*'
370 texto valor REGEXP 'abcdefghijklmnopqrstuvwxyz.*'
371 texto valor REGEXP BINARY 'ab.*'
372 texto valor REGEXP BINARY 'abcd.*'
373 texto valor REGEXP BINARY 'abcdef.*'
374 texto valor REGEXP BINARY 'abcdefgh.*'
375 texto valor REGEXP BINARY 'abcdefghij.*'
376 texto valor REGEXP BINARY 'abcdefghijkl.*'
377 texto valor REGEXP BINARY 'abcdefghijklmn.*'
378 texto valor REGEXP BINARY 'abcdefghijklmnop.*'
379 texto valor REGEXP BINARY 'abcdefghijklmnopqr.*'
380 texto valor REGEXP BINARY 'abcdefghijklmnopqrst.*'
381 texto valor REGEXP BINARY 'abcdefghijklmnopqrstuv.*'
382 texto valor REGEXP BINARY 'abcdefghijklmnopqrstuvwx.*'
383 texto valor REGEXP BINARY 'abcdefghijklmnopqrstuvwxyz.*'
64

ANEXOS

Anexo 1 - A linguagem regular aceita por xeger.

regexp ::= unionexp


|
unionexp ::= interexp | unionexp (union)
|
interexp ::= concatexp & interexp (intersection) [OPTIONAL]
|
concatexp ::= repeatexp concatexp (concatenation)
|
repeatexp ::= repeatexp
| ? (zero or one occurrence)
| * (zero or more occurrences)
| + (one or more occurrences)
| {n} (n occurrences)
| {n,} (n or more occurrences)
| {n,m} (n to m occurrences, including both)
|
complexp ::= ~ complexp (complement) [OPTIONAL]
|
charclassexp ::= [charclasses] (character class)
| [^charclasses] (negated character class)
|
charexp ::= <Unicode character> (a single non-reserved character)
| \<Unicode character> (a single character)
|
simpleexp ::= charexp
| . (any single character)
| # (the empty language) [OPTIONAL]
| @ (any string) [OPTIONAL]
| "<Unicode string without double-quotes> " (a string)
| ( ) (the empty string)
| (unionexp) (precedence override)
| <<identifier>>(named automaton) [OPTIONAL]
| <n-m> (numerical interval) [OPTIONAL]
|
charclass ::= charexp - charexp (character range, including end-points)
|
charclasses ::= charclass charclasses
|

Fonte: http://code.google.com/p/xeger/wiki/XegerLimitations

Você também pode gostar