Суворий режим MySQL і чому він повинен бути включений - Leonid Shevtsov

MySQL має такий спеціальний режим, призначений для введення в базу неправильних даних. Наприклад, щоб замість 20000000000 вставляти в INT-полі 2147483647 . Або наповнювати базу неіснуючими датами. Або обрізаними рядками. Ну чи мало для чого цей режим може тобі стати в нагоді.

Цей режим називається “звичайний режим”. W. T. F?

Хоча це з першого погляду здається божевільним, така поведінка має історичну причину.

Двигун MyISAM, колишній стандартним двигуном MySQL до недавніх пір, не підтримує транзакції. Якщо відвалювався один із “нібито атомарного” набору запитів, база (загалом) втрачала цілісність. Порівняно з такою небезпекою запис до бази невірних значень виявився найменшим злом.

Суворий режим

З великого списку режимів MySQL нас цікавить режим STRICT_TRANS_TABLES. Він забороняє те, про що я розповідав вище, та кидає помилки на будь-які неправильні дані.

Говорячи мовою запитів,

Зрозуміло, після такої зміни потрібно прогнати тести (якщо вони є), чи хоча б стежити за помилками (оскільки вони з'являться).

Щоб завжди використовувати цей режим у Ruby on Rails 3 (я не розумію, чому він не включається автоматично), достатньо покласти такий код кудись в ініціалізатори:

Про що я?

Вчора я довго шукав, чому в тестах не працював плагін bounces-handler. Це було тому, що Rails не підтримують тип INT UNSIGNED , який використовувався плагіном для зберігання CRC32. І не просто не підтримують, а записують замість нього у схему знаковий INT. Оскільки rake db:test:prepare завантажує саме схему, то у тестовому оточенні контрольні суми не влазили у рамки знакового поля та в базівиявлялося сміття.

Це було останньою краплею.

Мораль 1: не використовуй INT UNSIGNED з Rails

Мораль 2: у всіх полів має бути валідація

Як мінімум, у всіх полів, які вводять користувач. Якщо людина вводить рядок, перевір, чи вона не надто довга. Якщо число - перевір, чи воно входить у допустимий інтервал. 500 помилка ніколи не буде адекватною відповіддю на неправильні дані.