Por que não usar o MySQL?

Antes de entrar no assunto deste artigo gostaria de esclarecer que reconheço a importância do MySQL para o mundo dos bancos de dados, para o movimento open source, para milhares de sites que o utilizam como repositório de dados e para sistemas de grande sucesso, como o Wordpress, que são totalmente baseados no MySQL.

No ano passado, por exemplo, a Uber trocou o PostgreSQL pelo MySQL, então não serei eu a dizer que o MySQL (ou seu fork recente, o MariaDB) são ruins. Longe disso.

A minha restrição ao MySQL é quanto a um mecanismo muito importante de garantia da integridade dos dados: as “check constraints“.

Você já sabe que as check constraints são uma “última linha de defesa” contra a inserção de dados inválidos no banco de dados. Eu as considero muito importantes pois nunca confio 100% nas checagens que os desenvolvedores colocam nas interfaces gráficas. Ora, se a regra de negócio é nunca aceitar idades maiores de 99 anos em um determinado campo, essa regra também deve ser verificada no banco de dados através de uma check constraint.

E o problema é que, por incrível que pareça, o MySQL não implementa check constraints! Veja o que está escrito na documentação do MySQL 5.7: “The CHECK clause is parsed but ignored by all storage engines.” Sim, é verdade… veja com seus próprios olhos esse print da documentação do MySQL:

Sem as check constraints, se o desenvolvedor esquecer alguma checagem na interface gráfica, seu banco de dados poderá armazenar dados errados em relação à regra de negócio estabelecida. Veja o seguinte exemplo:

MySQL [(none)]> CREATE DATABASE teste;
Query OK, 1 row affected (0.04 sec)

MySQL [(none)]> USE teste;
Database changed

MySQL [teste]> CREATE TABLE teste ( 
            ->   idade INT CHECK (idade < 100)
            -> );
Query OK, 0 rows affected (0.09 sec)

MySQL [teste]> INSERT INTO teste (idade) VALUES (300);
Query OK, 1 row affected (0.05 sec)

MySQL [teste]> SELECT * FROM teste;
+-------+
| idade |
+-------+
|   300 |
+-------+
1 row in set (0.00 sec)

MySQL [teste]> DROP TABLE teste;
Query OK, 0 rows affected (0.07 sec)

MySQL [teste]> DROP DATABASE teste;
Query OK, 0 rows affected (0.02 sec)

MySQL [(none)]> exit
Bye

Como você pôde observer no exemplo acima, a tabela “teste” foi definida com um atributo “idade” que deveria aceitar somente valores menores do que 100 anos, mas um usuário distraído inseriu a idade de 300 e o RDBMS aceitou alegremente, sem nem reclamar. Você confiaria em um RDBMS que aceita valores que você explicitamente mandou ele não aceitar?

Para comparação, a história é bem diferente com o PostgreSQL:

postgres=# CREATE DATABASE teste;
CREATE DATABASE

postgres=# \c teste;
You are now connected to database "teste" as user "postgres".

teste=# CREATE TABLE teste (
teste(# idade INT CHECK (idade < 100)
teste(# );
CREATE TABLE

teste=# INSERT INTO teste (idade) VALUES (300);
ERROR:  new row for relation "teste" violates check constraint "teste_idade_check"
DETAIL:  Failing row contains (300).

teste=# SELECT * FROM teste;
idade
-------
(0 rows)

teste=# DROP TABLE teste;
DROP TABLE

teste=# \c postgres
You are now connected to database "postgres" as user "postgres".

postgres=# DROP DATABASE teste;
DROP DATABASE

postgres=# \q

O PostgreSQL não deixou o usuário distraído inserir o valor de 300 na idade e retornou um belo código de erro. Esse tipo de segurança é fundamental em RDBMS e é por isso que para aplicações críticas eu não recomendo o MySQL.

E o MariaDB? Bem, até pouco tempo atrás o MariaDB também não implementava as check constraints mas, FELIZMENTE, isso mudou a partir da versão 10.2.1 (liberada em 2016-07-04) e o MariaDB passou a suportar as check constraints.

Até o FAQ do MariaDB mudou a resposta de “Unfortunately, at the moment we don’t have any immediate plans of implementing CHECK constraints” para “Check constraints have been supported since MariaDB 10.2.1”.

Por isso, se você precisar de um banco de dados capaz de implementar check constraints (que são absolutamente essenciais em minha opinião), esqueça o MySQL! Ou então use o MariaDB mais recente.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *