Схема, валидация и антипаттерны
Почему «бессхемная» БД всё равно нуждается в схеме и как заставить базу её проверять.
MongoDB не навязывает схему, но схема всё равно есть — в коде приложения; база умеет проверять её через валидацию JSON Schema.
«Бессхемная» — это про гибкость, а не про хаос
Отсутствие принудительной схемы не значит, что структуру можно не продумывать. Приложение всё равно ожидает у пользователя поле email, а у заказа — items. Просто следить за этим теперь должны вы, а не CREATE TABLE. Гибкость удобна для эволюции (добавить поле — не миграция), но требует дисциплины.
Валидация схемы средствами базы
Чтобы база отвергала «битые» документы, на коллекцию вешают валидатор по стандарту JSON Schema. Опишем правила для users: обязательны name и email, возраст — целое число не меньше 0:
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "email"],
properties: {
name: { bsonType: "string" },
email: { bsonType: "string" },
age: { bsonType: "int", minimum: 0 }
}
}
}
})Теперь вставка документа без email или с отрицательным возрастом будет отклонена. Валидацию можно добавить и к существующей коллекции через collMod. Это страховка от ошибок приложения — но не замена продуманной модели данных.
Антипаттерн 1: безграничные массивы
Встраивать массив, который растёт без предела (все события пользователя, все сообщения чата), — ошибка. Документ имеет лимит 16 МБ, а большие массивы замедляют любые операции с документом. Такие данные выносят в отдельную коллекцию со ссылкой.
Антипаттерн 2: огромные документы и лишние поля
Не складывайте в документ всё подряд «про запас». Чем больше документ, тем дороже его читать и писать целиком. Храните то, что нужно реальным запросам.
Антипаттерн 3: мыслить таблицами
Самая частая ошибка переходящих с SQL — слепо переносить нормализованную схему: коллекция на каждую таблицу и $lookup вместо каждого JOIN. Документная модель раскрывается, когда вы проектируете под запросы и используете встраивание там, где оно уместно. Не «как было в SQL», а «как это читается».
Итог
- Схема в MongoDB существует — в приложении; база может её проверять через
$jsonSchema-валидацию. - Валидатор задают при
createCollection(или добавляют черезcollMod) — страховка от битых документов. - Антипаттерны: безграничные встроенные массивы, раздутые документы и «мышление таблицами».