HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Чтобы облегчить считываемость информации в таблице, программисты приводят данные, которые представлены в реляционной модели, к нормальной форме. В этом уроке мы узнаем, что это за форма, а также разберем ее первый уровень.</p>
1 <p>Чтобы облегчить считываемость информации в таблице, программисты приводят данные, которые представлены в реляционной модели, к нормальной форме. В этом уроке мы узнаем, что это за форма, а также разберем ее первый уровень.</p>
2 <h2>Нормальная форма</h2>
2 <h2>Нормальная форма</h2>
3 <p>Возьмем для примера интернет-магазин, в котором продается электроника. Когда пользователь делает заказ, в базу данных заносится запись об этом. В нее входит вся необходимая информация: данные пользователя, какой товар он купил, сколько он стоил и адрес доставки. Затем эти данные используются всеми подразделениями интернет-магазина - от бухгалтеров до службы доставки.</p>
3 <p>Возьмем для примера интернет-магазин, в котором продается электроника. Когда пользователь делает заказ, в базу данных заносится запись об этом. В нее входит вся необходимая информация: данные пользователя, какой товар он купил, сколько он стоил и адрес доставки. Затем эти данные используются всеми подразделениями интернет-магазина - от бухгалтеров до службы доставки.</p>
4 <p><strong>Таблица order_items</strong></p>
4 <p><strong>Таблица order_items</strong></p>
5 <p>В первой строке последнего столбца цена указана в долларах, в остальных записях - это рубли. Последняя запись повторяет предыдущую, потому что этот заказ выполнил тот же человек, но сделал это в другое время.</p>
5 <p>В первой строке последнего столбца цена указана в долларах, в остальных записях - это рубли. Последняя запись повторяет предыдущую, потому что этот заказ выполнил тот же человек, но сделал это в другое время.</p>
6 <p>В этой табличке много повторяющейся информации. Приведем ее к правильной структуре с точки зрения реляционной модели. Для этого приведем данные к<strong>нормальной форме</strong>- это требования, которые минимизируют избыточность данных, потенциально приводящих к логическим ошибкам.</p>
6 <p>В этой табличке много повторяющейся информации. Приведем ее к правильной структуре с точки зрения реляционной модели. Для этого приведем данные к<strong>нормальной форме</strong>- это требования, которые минимизируют избыточность данных, потенциально приводящих к логическим ошибкам.</p>
7 <p>Всего существует шесть нормальных форм, которые включают определенные требования. С каждым следующим уровнем требования все жестче, так как включают в себя предыдущие уровни.</p>
7 <p>Всего существует шесть нормальных форм, которые включают определенные требования. С каждым следующим уровнем требования все жестче, так как включают в себя предыдущие уровни.</p>
8 <p>В рамках курса мы разберем три нормальные формы. В этом уроке познакомимся с первой.</p>
8 <p>В рамках курса мы разберем три нормальные формы. В этом уроке познакомимся с первой.</p>
9 <h2>Первая нормальная форма</h2>
9 <h2>Первая нормальная форма</h2>
10 <p>Первая нормальная форма сводится к трем правилам:</p>
10 <p>Первая нормальная форма сводится к трем правилам:</p>
11 <ul><li>Каждая ячейка таблицы может хранить только одно значение</li>
11 <ul><li>Каждая ячейка таблицы может хранить только одно значение</li>
12 <li>Все данные в одной колонке могут быть только одного типа</li>
12 <li>Все данные в одной колонке могут быть только одного типа</li>
13 <li>Каждая запись в таблице должна однозначно отличаться от других записей</li>
13 <li>Каждая запись в таблице должна однозначно отличаться от других записей</li>
14 </ul><p>Разберем каждое правило подробнее.</p>
14 </ul><p>Разберем каждое правило подробнее.</p>
15 <h3>Каждая ячейка - одно значение</h3>
15 <h3>Каждая ячейка - одно значение</h3>
16 <p>Вернемся к примеру выше. У одной записи поля<em>item</em>и<em>price</em>содержат два значения через запятую. У такого способа организации данных много недостатков. Например, пропадает возможность делать обычную выборку по условиям:</p>
16 <p>Вернемся к примеру выше. У одной записи поля<em>item</em>и<em>price</em>содержат два значения через запятую. У такого способа организации данных много недостатков. Например, пропадает возможность делать обычную выборку по условиям:</p>
17 <p>Другая проблема связана с типами данных. Поле<em>price</em>в таблице<em>order_items</em>имеет числовой тип (numeric). Если мы захотим хранить там более одного значения, то тип превратится в строковый, а все данные станут обычными строками.</p>
17 <p>Другая проблема связана с типами данных. Поле<em>price</em>в таблице<em>order_items</em>имеет числовой тип (numeric). Если мы захотим хранить там более одного значения, то тип превратится в строковый, а все данные станут обычными строками.</p>
18 <p>При такой организации невозможно проверить корректность данных и формат числа. Становится проблематично выполнить агрегирующие запросы, например, считать выручку за определенный месяц одним запросом.</p>
18 <p>При такой организации невозможно проверить корректность данных и формат числа. Становится проблематично выполнить агрегирующие запросы, например, считать выручку за определенный месяц одним запросом.</p>
19 <p>Чтобы избавиться от перечислений в ячейках, можно создать новые записи:</p>
19 <p>Чтобы избавиться от перечислений в ячейках, можно создать новые записи:</p>
20 <p>Теперь на одной строке находится информация только по одному товару. Так мы избавились от перечислений в поле, что позволит выполнять агрегирующие запросы, а также не будет путаницы с типами данных.</p>
20 <p>Теперь на одной строке находится информация только по одному товару. Так мы избавились от перечислений в поле, что позволит выполнять агрегирующие запросы, а также не будет путаницы с типами данных.</p>
21 <h3>Данные одного типа</h3>
21 <h3>Данные одного типа</h3>
22 <p>Снова вернемся к таблице. Верхняя запись в ней содержит цену в долларах, хотя все остальные цены указаны в рублях. Технически база никак не укажет на это. И доллары, и рубли представлены числами, но с точки зрения программы у этих чисел разная природа.</p>
22 <p>Снова вернемся к таблице. Верхняя запись в ней содержит цену в долларах, хотя все остальные цены указаны в рублях. Технически база никак не укажет на это. И доллары, и рубли представлены числами, но с точки зрения программы у этих чисел разная природа.</p>
23 <p>Разные данные в рамках одного поля тоже не дают выполнить агрегирующие запросы, например, поиск сумм, максимального, минимального. Еще усложняется обработка данных на уровне кода. В коде придется каким-то образом понимать, что из себя представляют данные.</p>
23 <p>Разные данные в рамках одного поля тоже не дают выполнить агрегирующие запросы, например, поиск сумм, максимального, минимального. Еще усложняется обработка данных на уровне кода. В коде придется каким-то образом понимать, что из себя представляют данные.</p>
24 <p>Вот еще несколько примеров с похожей ситуацией:</p>
24 <p>Вот еще несколько примеров с похожей ситуацией:</p>
25 <ul><li>Хранение даты свадьбы в поле "день рождения"</li>
25 <ul><li>Хранение даты свадьбы в поле "день рождения"</li>
26 <li>Хранение номера телефона вместо адреса в поле "адрес"</li>
26 <li>Хранение номера телефона вместо адреса в поле "адрес"</li>
27 </ul><p>Исправленная версия таблицы:</p>
27 </ul><p>Исправленная версия таблицы:</p>
28 <p>Мы сконвертировали цену утюга в первой строке из долларов в рубли. Теперь у данных в поле<em>price</em>один тип. Так программе будет легче выполнять агрегирующие запросы.</p>
28 <p>Мы сконвертировали цену утюга в первой строке из долларов в рубли. Теперь у данных в поле<em>price</em>один тип. Так программе будет легче выполнять агрегирующие запросы.</p>
29 <h3>Уникальные записи</h3>
29 <h3>Уникальные записи</h3>
30 <p>Последние две записи в таблице выглядят идентично, хотя это два разных заказа. Их сделал один человек, но в разное время:</p>
30 <p>Последние две записи в таблице выглядят идентично, хотя это два разных заказа. Их сделал один человек, но в разное время:</p>
31 <p>Реляционная модель требует от нас уникальности каждой записи. Иначе нельзя понять, что к чему относится и с какой записью нужно работать при изменениях. Можно начать править не то и потерять важную информацию. При этом мы не можем полагаться на порядок данных внутри таблицы, так как он не гарантирован.</p>
31 <p>Реляционная модель требует от нас уникальности каждой записи. Иначе нельзя понять, что к чему относится и с какой записью нужно работать при изменениях. Можно начать править не то и потерять важную информацию. При этом мы не можем полагаться на порядок данных внутри таблицы, так как он не гарантирован.</p>
32 <p>Реализовать уникальность можно несколькими способами, например, добавить новое поле с датой заказа, которое сделает запись уникальной. Этот способ не очень надежный и не очень удобный в работе. Придется постоянно анализировать весь набор полей.</p>
32 <p>Реализовать уникальность можно несколькими способами, например, добавить новое поле с датой заказа, которое сделает запись уникальной. Этот способ не очень надежный и не очень удобный в работе. Придется постоянно анализировать весь набор полей.</p>
33 <p>Лучше добавить<strong>первичный ключ</strong>(<em>PRIMARY KEY</em>) - поле или набор полей, которые содержат уникальное значение для каждой записи. Первичный ключ не может меняться, его значение однозначно определяет любую запись в таблице.</p>
33 <p>Лучше добавить<strong>первичный ключ</strong>(<em>PRIMARY KEY</em>) - поле или набор полей, которые содержат уникальное значение для каждой записи. Первичный ключ не может меняться, его значение однозначно определяет любую запись в таблице.</p>
34 <p>Разберем два вида первичного ключа:</p>
34 <p>Разберем два вида первичного ключа:</p>
35 <ul><li><strong>Естественный</strong>- когда используются значения из окружающего мира, например, email, ФИО или паспортные данные. При этом нужно убедиться, что ключ не будет повторяться. Такие первичные ключи используют редко из-за их ненадежности. Часто они не уникальны и могут изменяться или повторяться. Например, номер паспорта меняется при смене документа</li>
35 <ul><li><strong>Естественный</strong>- когда используются значения из окружающего мира, например, email, ФИО или паспортные данные. При этом нужно убедиться, что ключ не будет повторяться. Такие первичные ключи используют редко из-за их ненадежности. Часто они не уникальны и могут изменяться или повторяться. Например, номер паспорта меняется при смене документа</li>
36 <li><strong>Суррогатный</strong>- когда используются автоматически генерируемые уникальные значения. Такой ключ поддерживается любой базой данных "из коробки". Иногда это просто числа, а иногда - сложные число-буквенные строки или хеши</li>
36 <li><strong>Суррогатный</strong>- когда используются автоматически генерируемые уникальные значения. Такой ключ поддерживается любой базой данных "из коробки". Иногда это просто числа, а иногда - сложные число-буквенные строки или хеши</li>
37 </ul><p>Добавим в нашу таблицу первичный ключ:</p>
37 </ul><p>Добавим в нашу таблицу первичный ключ:</p>
38 <p>Первичный ключ принято создавать первым полем с названием<em>id</em>. Для первичного ключа обязательно указывать<em>PRIMARY KEY</em>в описании таблицы:</p>
38 <p>Первичный ключ принято создавать первым полем с названием<em>id</em>. Для первичного ключа обязательно указывать<em>PRIMARY KEY</em>в описании таблицы:</p>
39 <p>Такой ключ все еще нужно формировать самостоятельно, но теперь база данных сама следит за уникальностью. При попытке создать запись с повторяющимися первичными ключами возникнет ошибка.</p>
39 <p>Такой ключ все еще нужно формировать самостоятельно, но теперь база данных сама следит за уникальностью. При попытке создать запись с повторяющимися первичными ключами возникнет ошибка.</p>
40 <h2>Выводы</h2>
40 <h2>Выводы</h2>
41 <p>В этом уроке мы узнали, что такое нормальная форма в реляционной модели. Она помогает облегчить считываемость информации в таблице. Еще мы подробно разобрали первый уровень формы. Так мы узнали, что каждая ячейка таблицы может хранить только одно значение. Иначе может произойти путаница с типами данных, из-за чего будет невозможно проверить их корректность.</p>
41 <p>В этом уроке мы узнали, что такое нормальная форма в реляционной модели. Она помогает облегчить считываемость информации в таблице. Еще мы подробно разобрали первый уровень формы. Так мы узнали, что каждая ячейка таблицы может хранить только одно значение. Иначе может произойти путаница с типами данных, из-за чего будет невозможно проверить их корректность.</p>
42 <p>Также все данные в одной колонке могут быть только одного типа. Данные разного типа усложняют работу с таблицей, так как в коде придется каким-то образом понимать, что из себя представляют данные. А чтобы отличать записи друг от друга, нужно использовать суррогатный первичный ключ, который сделает каждую запись уникальной.</p>
42 <p>Также все данные в одной колонке могут быть только одного типа. Данные разного типа усложняют работу с таблицей, так как в коде придется каким-то образом понимать, что из себя представляют данные. А чтобы отличать записи друг от друга, нужно использовать суррогатный первичный ключ, который сделает каждую запись уникальной.</p>