Какую базу данных выбрать: MySQL vs PostgreSQL

Отличный вопрос для холивара. Но не будем. Опубликована статья Why favor PostgreSQL over MariaDB / MySQL, автор которой рассматривает обе СУБД с позиции бережного отношения к данным и приходит к выводу, что для серьезных проектов подходит PostgreSQL, а MySQL — вообще не вариант.

Пример превосходства PosgreSQL над MySQL

Например, создадим таблицу и для одного из полей зададим тип numeric(4, 2) — четыре разряда под хранение всего числа и два разряда после запятой. А потом попытаемся вставить число, которое не соответствует описанию. И что вы думаете? Нет проблем!


CREATE TABLE data (
id integer NOT NULL,
data numeric(4, 2)
);

INSERT INTO data VALUES (1, 1234.5678);
Query OK, 1 row affected, 1 warning (0.01 sec)

SELECT * FROM data;
+—-+——-+
| id | data |
+—-+——-+
| 1 | 99.99 |
+—-+——-+

1 row in set (0.00 sec)

В ручном режиме мы увидим (возможно) предупреждение (1 warning) попытаемся догадаться, о чем оно и восстановить прежнее значение. Но предупреждение легко пропустить. Если вы пишете приложение, имеющее дело с хранением финансовых данных, такие ошибки будут стоить очень дорого.

PostgreSQL бережет ваши данные и ведет себя более серьезно:


INSERT INTO data VALUES (1, 1234.5678);
ERROR: numeric field overflow
DETAIL: A field with precision 4, scale 2 must round to an absolute value less than 10^2.

Нам просто не дадут сделать ошибку. Более того, в сообщении будет содержаться детализация: какое именно ограничение мы нарушили и какой максимальный размер числа задан. Так-то вот.

А теперь немного мистики. Помните, мы описали, что поле id для MySQL не должно быть NULL? Пробуем:


UPDATE data SET id = NULL WHERE id = 1;
Query OK, 1 row affected, 1 warning (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 1

SELECT * FROM data;
+—-+——+
| id | data |
+—-+——+
| 0 | 99.99 |
+—-+——+

1 row in set (0.00 sec)

Удивительно, но несмотря на явный запрет (NOT NULL), СУБД MySQL разрешила-таки обновить поле, причем установила его значение в 0, хотя о нуле мы вообще ничего не говорили. 0 и NULL — совершенно разные сущности. 0 — это число. NULL — это особый индикатор, говорящий нам о том, что мы не знаем, какое число содержится в этом поле. И совсем необязательно это 0. Таким образом, СУБД опять приписала от себя случайное значение в нашу базу. Если в вашем приложении будет такая же ошибка, то MySQL поможет этой ошибке долго оставаться необнаруженной. А что же PostgreSQL? Тут всё чётко:


UPDATE data SET id = NULL WHERE id = 1;
ERROR: null value in column „id“ violates not-null constraint

NULL в столбце id нарушает явно заданное ограничение, поэтому значение изменено не будет.

Остальные примеры можно найти в оригинальной статье.