Skip to content

Tag: sql

Short urls with Glassfish+MySQL


Pipes, Creative Commons photo by flattop341.

1. The Problem

Internet is full of long urls and meaningless.

Long urls are difficult to remember or print, usually full of redundancy and low semantic. With short and meaningful urls you can avoid thes problems and even achieve profitable goals with SEO
SEO (search engine optimization) technics.

There are services like Tiny URL, Fancy URL, Moo URL and others. Although they solve part of the problems, they bring several others. Another problem is if you have a web site like example.com and use a third-party service for short urls you are losing part of your mind-share with your users and clients.

As an example, if a example.com company wants to promote a open work position would be preferable spread a example.com/jobs instead of a tinyurl.com/examplejobs, or even worst, a tinyurl.com/3i4i592 (meaningless hash).

2. Solution Approach

I created a little program called xort that can be placed on your own server and provide you own short maintening your base url.

I use a pipe abstraction. Each pipe redirects from a key url to an output url.

The idea is that you have xort installed and associated into your domain (preferably on /x). A pipe inside example.com would be like example.com/x/jobs.

3. Tools

All those tools are multi platform, open source and free.

3.1 Glassfish Application Server

Glassfish is an open source application server project led by Sun Microsystems for the Java Enterprise Edition (Java EE) platform. It’s very easy to install and run and have a very nice administration web interface where you can do from simple tasks like deploy a application to more complexes like clustering.


Glassfish Admin Console

To develop the application I’m using NetBeans 6.5 Beta that comes with Glassfish V3 prelude b15b. Netbeans also provides a integration of project, database and web server.

Nevertheless, Glassfish has no dependencies with any IDE and perfectly works by alone. If you need I wrote this post explaining how to install and deploy a application on Glassfish from scratch.

3.2 MySQL Relational Database

MySQL is a relational database management system and probably the most used database on internet (has more than 11 million installations). It’s also very easy to install and administer, through command line or many gui interfaces.

To install MySQL and JDBC driver on Ubuntu just run as root:

# apt-get install mysql-server libmysql-java

After installing and configuring it you can test the jdbc driver throught this servlet code. You can optionally register the MySQL on NetBeans to have a easier access to it thought the service tab.

At the command line you can invoke mysql command line interface and use MySql commands or SQL queries. I’ll login and create a database called xort:

$ mysql -u username -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.0.51a-3ubuntu5.3 (Ubuntu)

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.

mysql> create database xort;
Query OK, 1 row affected (0.06 sec)

You could also create this database by an SQL statement:

CREATE DATABASE xort;

To select the database xort:

mysql> use xort;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql>

Now we create a database called pipes with fields pin (pipe in) and pout (pipe out). They represent the input url and the output url of our pipe abstraction.

CREATE TABLE pipes (
   pin VARCHAR(255) NOT NULL,
   pout VARCHAR(255)
);

As we expect a lot of searches queries on this table, we can optionally create a index for it on pin field. This can reduce ours searches from O(n) to O(logn) (because pin’s will be ordered so don’t need to look all pipes, we can use logn algorithms like binary search).

CREATE INDEX pinindex ON pipes (pin);

Another trick to improve our speed is recycling connections through connection pools.

Creating a pool of MySQL connections on Glassfish is very easy. There’re two good tutorials on this subject:

And now we populate the database with some initial pipes.

INSERT INTO pipes VALUES ('blog','http://silveiraneto.net');
INSERT INTO pipes VALUES ('cejug','http://cejug.org/display/cejug/Home');
INSERT INTO pipes VALUES ('orkut','http://www.orkut.com.br/Main#Profile.aspx?rl=ls&uid=12443310329436634134');
INSERT INTO pipes VALUES ('glassfish','http://glassfish.dev.java.net');
INSERT INTO pipes VALUES ('mysql','http://dev.mysql.org');
INSERT INTO pipes VALUES ('twitter','http://twitter.com/silveira');
INSERT INTO pipes VALUES ('lab', 'http://maps.google.com/maps?f=q&geocode=&q=campus+do+pici&g=Fortaleza,+Brazil&ie=UTF8&t=h&ll=-3.745978,-38.574023&spn=0.002452,0.004823&z=18');
INSERT INTO pipes VALUES ('videos', 'http://br.youtube.com/user/NetoSilveira');
INSERT INTO pipes VALUES ('photos', 'http://flickr.com/photos/silveiraneto/');

4. Program

Basically we have just a program that implement this simple behavior:

  1. separate the key from the url.
  2. if the key is a pin from a pipe then redirect to that pout.
  3. else provide a way to create a new pipe.
  4. list all pipes.
  5. provide a way to remove a pipe.

To get the key we need to separate the proper part of the request uri:

String uri = request.getRequestURI();
String key = uri.substring(request.getContextPath().length()+1);

After that we check if it matches with a pin of some pipe. In this case we redirect user for the correspondent pout:

response.sendRedirect(pout);

Notice that using this approach we can connect a url to a extern or intern url (even to another pipe).

5. Download

Check out the xort project and sources at xort.dev.java.net:

Or grab sources and the current build with:

svn checkout https://xort.dev.java.net/svn/xort/trunk xort

Parameters can be passed by the the web.xml file:

   Set if users can add new pipes using the web interface.
allowNewPipes
true
 
   JDBC driver to use
driver
com.mysql.jdbc.Driver
 
   Username to login on the database.
username
root
 
   Password for the given username.
password
yourpassword
 
   JDBC path to database.
database
jdbc:mysql://localhost:3306/xort

Xort up and running:

Quem mais comenta no seu blog?

Uma brincadeira de mão na massa com SQL e as tabelas do WordPress.

Logomarca do WordPress

Você vai precisar de:

  • Um blog em WordPress num servidor próprio.
  • Uma lugar onde você possa se conectar ao banco de dados (provavelmente o MySQL). Um terminal SSH no seu servidor ou mesmo o PhpMyAdmin servem.

Se você tiver acesso por SSH no servidor onde está seu blog, chame o prompt do mysql assim:

$ mysql -u USUÁRIO -p -h URL_DO_BANCO DATABASE

Trocando USUÁRIO por seu login no mysql, URL_DO_BANCO por a url do seu banco (geralmente 127.0.0.1) e DATABASE por a base de dados (geralmente wordpress). Em seguida será perguntada a sua senha.

Uma vez conectado dentro do seu banco de dados você pode executar algumas queries legais.

Os 10 maiores comentaristas do seu blog: você seleciona da wp_comments (a tabela de comentários do WordPress) selecionando só os nomes e agrupando pelo email do autor e fazendo uma contagem que chamados de quantidade. Também é feito uma ordenação usando o campo contagem. Aqui eu supondo que a pessoa sempre coloque seu próprio email, mas as vezes mude o nome, o que realmente acontece.

SELECT comment_author AS autor, COUNT(*) AS quantidade
   FROM wp_comments
   GROUP BY `comment_author_email`
   ORDER BY quantidade DESC
   LIMIT 10
;

Usando isso lá no banco de dados do eupodiatamatando.com que tem uns 3 mil comentários, deu o seguinte:

+---------------------------------------------+------------+
| autor                                       | quantidade |
+---------------------------------------------+------------+
| Silveira                                    |        511 |
| 2007 Janeiro 21 » Eu Podia Ta Matando       |        174 |
| Kct                                         |        133 |
| Filho                                       |         91 |
| Dora                                        |         83 |
| Leonardo                                    |         67 |
| manero                                      |         58 |
| Esdras                                      |         52 |
| Marlany                                     |         51 |
| Roney Marques                               |         50 |
+---------------------------------------------+------------+
10 rows in set (0.12 sec)

Ou seja, em primeiro lugar deu eu mesmo, com 511 comentários. Em segundo, o próprio blog com seus pingbacks. O maior comentarista mesmo foi o comentarista que se identifica como Kct.

Os 10 posts mais comentados: É necessário fazer uma junção entre a tabela dos comentários (wp_comments) e a tabela dos posts (wp_posts) usando o ID do post.

SELECT wp_posts.post_title, COUNT(*) AS quantidade
   FROM wp_comments JOIN wp_posts
   ON wp_comments.comment_post_ID = wp_posts.ID
   GROUP BY wp_posts.ID
   ORDER BY quantidade DESC
   LIMIT 10
;

A saída que eu tive:

+-----------------------------------------+------------+
| post_title                              | quantidade |
+-----------------------------------------+------------+
| Sobre o vôo 3054                        |        104 |
| Chegou o boneco do Capitão Nascimento!  |         80 |
| Vamos trocar links?                     |         74 |
| O celular Linux já está a venda         |         64 |
| O Que o Emo disse pra Ema?              |         57 |
| Bichos grandes. Falsificações?          |         46 |
| Esse ainda tem muito pra upar           |         45 |
| Entenda Heroes                          |         42 |
| Aqui pro iPhone!                        |         40 |
| Ganhe créditos de graça no celular      |         39 |
+-----------------------------------------+------------+
10 rows in set (0.11 sec)

Qual o post você mais comentou: Basta colocar um WHERE e pegar o autor que você quer, no caso, Silveira (eu). Eu coloquei um limite de 10, para pegar só os 10 posts que eu mais comentei.

SELECT wp_posts.post_title, COUNT(*) AS quantidade
    FROM wp_comments JOIN wp_posts
    ON wp_comments.comment_post_ID = wp_posts.ID
    WHERE wp_comments.comment_author = 'Silveira'
    GROUP BY wp_posts.ID
    ORDER BY quantidade DESC
    LIMIT 10
;

O resultado no meu blog foi:

+---------------------------------------------+------------+
| post_title                                  | quantidade |
+---------------------------------------------+------------+
| Vamos trocar links?                         |         20 |
| Regnum, RPG online gratúito                 |         11 |
| Promoção: Estamos Dando 97 dólares!         |          7 |
| Aqui pro iPhone!                            |          6 |
| Vamos escrever um livro?                    |          6 |
| Democracy TV Player                         |          5 |
| Formatura, novidades                        |          5 |
| Como eu consegui cancelar minha conta na Oi |          5 |
| Chico Buarque em Fortaleza                  |          4 |
| Livro Python Guia de Bolso                  |          4 |
+---------------------------------------------+------------+
10 rows in set (0.02 sec)

Se você quiser ir mais fundo nas consultas eu recomendo dar uma olhada na sintaxe do select do Mysql.