Зачем моделировать данные: на бытовом примере
Этот курс про моделирование данных. Но прежде чем учиться его делать, надо понять простую вещь: зачем оно вообще нужно. Ответ проще, чем кажется, и его лучше всего увидеть на бытовом примере, без единого технического термина. Поэтому начнём не с базы данных, а с обычной таблицы, которую мог бы вести кто угодно в записной книжке или в Excel.
Таблица, которую завёл бы каждый
Представь, что ты ведёшь небольшой магазин и хочешь записывать заказы. Самый естественный первый шаг — завести один список, куда складываешь всё подряд: кто заказал, что заказал, по какой цене, какой у клиента телефон. Получается одна большая таблица, где каждая строка — это один заказ.
| Заказ | Клиент | Телефон клиента | Товар | Цена |
|---|---|---|---|---|
| 1 | Анна | 8-900-111 | Чайник | 2000 |
| 2 | Борис | 8-900-222 | Кружка | 500 |
| 3 | Анна | 8-900-111 | Кружка | 500 |
| 4 | Анна | 8-900-111 | Чайник | 2000 |
На первый взгляд всё хорошо: понятно, удобно, всё в одном месте. Именно так начинают почти все. И именно здесь прячется проблема, которая со временем вырастает в большую головную боль.
Где прячется проблема: дубли
Посмотри внимательно на столбец «Телефон клиента». Анна сделала три заказа — и её телефон записан три раза. Это и есть дубль: один и тот же факт («телефон Анны — 8-900-111») хранится в нескольких местах. Пока заказов мало, это незаметно. Но дубли создают вполне конкретные неприятности.
Что будет, если телефон Анны поменяется. Анна сменила номер. Теперь надо найти все строки с Анной и поправить телефон в каждой. Три строки — ещё ничего. А если заказов триста? Достаточно пропустить одну строку — и у тебя в таблице два разных телефона одного человека. Какой из них правильный? Непонятно. Данные начали врать.
Это главная беда дублей: они расходятся. Пока факт записан в одном месте, он либо верный, либо нет. Когда тот же факт записан в десяти местах, рано или поздно часть копий обновят, а часть забудут — и теперь невозможно понять, где правда.
Что будет, если новый клиент ещё ничего не заказал. К тебе обратился новый клиент, Виктор, оставил телефон, но пока ничего не купил. Куда его записать? В таблице строка — это заказ. Нет заказа — некуда вписать клиента. Получается, чтобы запомнить телефон Виктора, надо выдумать несуществующий заказ. Абсурд.
Что будет, если удалить заказ. Борис сделал ровно один заказ, и ты его удаляешь (скажем, заказ отменили). Вместе со строкой исчезает и единственное место, где был записан телефон Бориса. Удалив заказ, ты случайно стёр контакт клиента. Ты не хотел — так получилось само.
Заметь: ни в одном из трёх случаев таблица не выдала ошибку и не предупредила тебя. Она послушно сделала то, что ты попросил, и тихо испортила данные. Беду ты заметишь сильно позже — когда позвонишь клиенту по неправильному номеру.
В чём корень: один факт записан много раз
У всех трёх бед одна причина. Мы свалили в одну таблицу две разные вещи: данные о заказах и данные о клиентах. А это разные сущности. Заказов у одного клиента может быть много, а клиент при этом один. Когда мы держим их вместе, телефон клиента поневоле дублируется в каждом его заказе — и начинаются проблемы.
Решение напрашивается само: разделить. Завести два отдельных списка.
Список клиентов — каждый клиент записан ровно один раз:
| Клиент | Телефон |
|---|---|
| Анна | 8-900-111 |
| Борис | 8-900-222 |
Список заказов — вместо имени и телефона клиента в каждой строке просто ссылка на клиента (например, его имя как метка):
| Заказ | Клиент | Товар | Цена |
|---|---|---|---|
| 1 | Анна | Чайник | 2000 |
| 2 | Борис | Кружка | 500 |
| 3 | Анна | Кружка | 500 |
| 4 | Анна | Чайник | 2000 |
Теперь телефон Анны записан один раз. Поменялся номер — правишь одну строку, и всё. Новый клиент без заказов? Просто добавляешь его в список клиентов. Удалил заказ? Клиент на месте, его телефон никуда не делся. Три беды исчезли одним движением — мы просто разложили данные по правильным полкам.
Запомни это ощущение: «один факт — в одном месте». Это сердце почти всего, чем мы будем заниматься в курсе. Когда каждый факт хранится ровно один раз, его невозможно случайно рассогласовать с самим собой.
Что такое модель данных
То, что мы только что сделали — решили, какие будут списки, что в каждом из них хранится и как они связаны — и называется моделированием данных. А результат этого решения — модель данных.
Удобнее всего думать о модели как о чертеже. Прежде чем строить дом, архитектор рисует чертёж: где стены, где двери, как комнаты соединены между собой. Строитель потом возводит дом строго по чертежу. Точно так же, прежде чем складывать данные в базу, мы рисуем чертёж: какие будут таблицы, что лежит в каждой и как они связаны. А база потом хранит данные строго по этому чертежу.
Хороший чертёж дома экономит силы и деньги: ошибку на бумаге исправить легко, а переделывать уже построенную стену — дорого и долго. С данными ровно так же. Поправить чертёж, пока он на бумаге — минута. Перестроить структуру, когда в базе уже тысячи записей и от неё зависит работающее приложение — это большая и рискованная работа. Поэтому моделировать выгодно заранее, а не «по ходу».
Иногда дубли добавляют специально и осознанно — например, чтобы какой-то отчёт строился быстрее. Это нормальное инженерное решение, и у него есть имя. Но это всегда осознанный выбор с пониманием цены, а не случайность, как в нашей первой таблице. К этому мы вернёмся гораздо позже.
Что дальше в курсе
Дальше мы будем учиться делать такие чертежи по-настоящему: как находить сущности (клиент, заказ, товар), как описывать связи между ними, как раскладывать данные так, чтобы каждый факт хранился один раз. Но прежде, в следующем уроке, мы освоим маленький набор команд, которым с базой данных вообще разговаривают — чтобы дальше можно было не только рисовать чертежи, но и проверять их руками.
Попробуй сам
Возьми лист бумаги или открой любой текстовый файл. Придумай маленький пример из своей жизни, где данные естественно сваливаются в одну большую таблицу с дублями — например, список книг с автором и страной автора, или список занятий с именем тренера и его телефоном. Запиши его как одну плоскую таблицу и найди дубль: какой факт повторяется в нескольких строках. Затем мысленно проделай три беды: что будет, если этот факт изменится; как добавить запись, у которой ещё нет «главного» события; что потеряется при удалении строки. После этого раздели таблицу на две так, чтобы повторяющийся факт хранился ровно один раз, и убедись, что все три беды исчезли. Сохрани этот разбор — мы вернёмся к нему, когда будем говорить о связях между таблицами.