JavaRush /Курси /SQL SELF /Типові помилки при роботі з даними

Типові помилки при роботі з даними

SQL SELF
Рівень 22 , Лекція 4
Відкрита

Робота з базою даних — як життя програміста: повна несподіванок. Навіть найдосвідченіший розробник може помилитися, наприклад, випадково видалити дані, спробувати вставити дублікат або порушити обмеження цілісності. Але важливо не лише уникати таких помилок, а й знати, як їх виправити, якщо раптом щось пішло не так. Давай розглянемо кілька найтиповіших помилок.

Помилка №1: Брак умови WHERE

Найкласичніша помилка, яку роблять новачки (і, якщо чесно, іноді навіть досвідчені деви), — це забути додати WHERE у запит на оновлення або видалення даних. Запити без WHERE оновлюють або видаляють усі рядки таблиці.

-- Приклад, як не треба робити:
UPDATE students SET status = 'graduated';

-- Або ось так:
DELETE FROM students;

Наслідки: уяви, що після такого запиту твоя таблиця students, де були всі дані про студентів, стала порожньою. І найнеприємніше — дані не повернути, якщо у тебе немає бекапу або не використовувалися транзакції (і навіть тоді це вже стрес).

Як уникнути: завжди додавай умови у запити UPDATE та DELETE, щоб чітко визначити, які рядки ти хочеш змінити або видалити.

-- Як треба робити:
UPDATE students
SET status = 'graduated'
WHERE year_of_study = 4;

DELETE FROM students
WHERE status = 'expelled';

Ще один лайфхак — перед видаленням завжди запускай SELECT, щоб переконатися, що умова налаштована правильно:

-- Спочатку перевіряємо:
SELECT * FROM students WHERE status = 'expelled';

-- Потім видаляємо:
DELETE FROM students WHERE status = 'expelled';

Помилка №2: Порушення унікальності даних (UNIQUE)

Якщо на таблицю накладено обмеження UNIQUE, то спроба вставити дублікат закінчиться помилкою.

-- Помилка через дублювання email:
INSERT INTO students (name, email) VALUES ('Otto Lin', 'otto.lin@email.com');
INSERT INTO students (name, email) VALUES ('Peter Pen', 'otto.lin@email.com');

Помилка:

ERROR: duplicate key value violates unique constraint "students_email_key"

Як уникнути: перед вставкою даних треба перевірити, чи немає вже рядка з такими ж значеннями.

-- Один із способів:
SELECT * FROM students WHERE email = 'otto.lin@email.com';

-- Або використати UPSERT:
INSERT INTO students (name, email)
VALUES ('Peter Pen', 'otto.lin@email.com')
ON CONFLICT (email) DO NOTHING;

Помилка №3: Порушення обмежень цілісності (FOREIGN KEY)

Уяви, у тебе є дві таблиці: students і enrollments, де student_id у таблиці enrollments пов'язаний зовнішнім ключем з id таблиці students. Якщо ти спробуєш вставити запис у enrollments, вказавши student_id, якого немає у students, отримаєш помилку.

INSERT INTO enrollments (student_id, course_id)
VALUES (999, 101); -- Помилка, бо student_id 999 не існує

Як уникнути?

  1. Завжди перевіряй наявність запису у батьківській таблиці перед вставкою у пов'язану таблицю:
SELECT * FROM students WHERE id = 999;
  1. Використовуй обмеження ON DELETE CASCADE, щоб записи у пов'язаних таблицях автоматично видалялися при видаленні запису з батьківської таблиці (але обережно).
CREATE TABLE enrollments (
    id SERIAL PRIMARY KEY,
    student_id INT REFERENCES students(id) ON DELETE CASCADE,
    course_id INT
);

Помилка №4: Невірні типи даних

При вставці або оновленні даних PostgreSQL суворо перевіряє сумісність типів. Якщо ти спробуєш вставити рядок у числове поле, отримаєш помилку.

-- Помилка через несумісність типів:
INSERT INTO students (id, name) VALUES ('abc', 'Alex Go');

Помилка:

ERROR: invalid input syntax for type integer

Як уникнути? Слідкуй за типами даних у значеннях, які вставляєш. Якщо дані приходять з форми користувача, обов'язково валідуй їх на стороні застосунку.

Помилка №5: Проблеми з паралельним доступом (витік даних)

Уяви, що двоє користувачів одночасно намагаються оновити один і той самий запис у таблиці. Без належної ізоляції транзакцій велика ймовірність конфліктів.

-- Користувач A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;

-- Користувач B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 1;

Як уникнути? Використовуй транзакції та рівні ізоляції, щоб запобігти одночасній зміні даних.

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

Помилка №6: Втрата даних через TRUNCATE

TRUNCATE видаляє всі рядки з таблиці без можливості відновлення, бо для цієї команди не передбачено підтримку ROLLBACK (вона не викликає тригери і виконується миттєво).

-- Видаляє все безповоротно:
TRUNCATE TABLE students;

Як уникнути: використовуй DELETE з умовою замість TRUNCATE, якщо треба зберегти можливість відкату.

BEGIN;
DELETE FROM students WHERE year_of_study = 1;
-- Якщо передумав:
ROLLBACK;

Помилка №7: Відсутність транзакцій для важливих операцій

Якщо виконується складна операція з кількох кроків, і посередині виникає помилка, дані можуть залишитися у неконсистентному стані.

-- Крок 1: додаємо студента
INSERT INTO students (name, email) VALUES ('Otto Lin', 'otto.lin@email.com');

-- Крок 2: записуємо його на курс
INSERT INTO enrollments (student_id, course_id) VALUES (LASTVAL(), 101); -- помилка

Як уникнути? Об'єднуй такі операції у транзакцію:

BEGIN;

INSERT INTO students (name, email) VALUES ('Іван Іванов', 'ivan.ivanov@email.com');
INSERT INTO enrollments (student_id, course_id) VALUES (LASTVAL(), 101);

COMMIT;

Якщо на будь-якому етапі виникне помилка, ти можеш відкотити зміни:

ROLLBACK;

Помилка №8: Випадкова робота з NULL

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

-- Це не спрацює:
SELECT * FROM students WHERE email = NULL;

Як уникнути? Використовуй IS NULL або IS NOT NULL:

SELECT * FROM students WHERE email IS NULL;

Типові помилки неминучі, але знаючи, як їх розпізнати і як їх уникати, ти зможеш працювати з даними безпечно й ефективно. PostgreSQL — суворий, але справедливий страж твоїх даних, і він завжди готовий повернути помилку, якщо щось не так. Просто пам'ятай: помилки — це не вороги, а вчителі.

1
Опитування
Вступ до транзакцій, рівень 22, лекція 4
Недоступний
Вступ до транзакцій
Вступ до транзакцій
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ