3 формы SQL-нормализации и описание таблиц

Блог им. yrnt /
Предположим, что программист Санжар написал паука, который ползает по КазНету и собирает информацию пользователях. Хранить собранную информацию он решил в РСУБД. Для хранения данных он разработал таблицу accounts


1Ф — Удаляем повторяющиеся группы. Колонки превращаем в строки
Санжар подумал раз. И решил, что дублирование колонок не есть гуд, поэтому он изменил структуру хранения на


2Ф — Устраняем избыточность данных. Смотрим на дублирующиеся данные. Дробим табличку
Санжар подумал два. Теперь он решил, что табличка accounts слишком избыточна(много повторяющихся строк), поэтому он изменил структуру хранения на


3Ф — Все колонки таблиц должны функционально зависеть от первичного ключа
Санжар подумал три. И окончательно решил, что колонка browser не зависит от колонки login, т.к. это независимая сущность, поэтому он изменил структуру хранения на


Описание таблиц
Мало кто знает, что описывать таблицы можно не только в ER-диаграмме. Есть более старинный способ — текстовый.

TABLE users
#*	login
*	fname

TABLE sites
#*	site_fqdn
o	site_desc

TABLE user_accounts
#*	account_id
\*	login
\*	site_fqdn

TABLE user_sessions
#* 	session_id
\*	login
*	browser
*	city

, где
  • # — первичный ключ
  • \ — внешний ключ
  • * — обязательное для заполнения поле
  • o — необязательное для заполнения поле

О нормализации
Нормализация — это организация табличек в БД таким образом, чтобы устранялись избыточность и несогласованные зависимости.
  • Избыточность — это когда в табличке дублируется много ячеек;
  • Несогласованная зависимость — это когда в ячейке таблицы users хранятся все логи пользователя за 2 года в формате JSON:).

О денормализации
Вы участвуете в высоких нагрузках? Хорошо. Лишний SQL-запрос — плохо! Поэтому Вы стремитесь декрементировать форму нормализации? Хорошо. Но не забудьте, что денормализуя БД вы можете резко увеличить ее размер(не удивляйтесь стометровым дампам для мелких БД) и затруднить доступ к некоторым данным(затруднение = парсинг = приседания с процессором). А если забудете, то вы сильно рискуете подвергнуть себя стресстестам после шести и рабочим выходным.

НФБК — Устраняем зависимости ключевых атрибутов от неключевых
НФ Бойса-Кодда — строгий вариант 3-ей НФ. Например, есть таблица accounts, которая находится в 3НФ. Пусть jnet.kz хостится у hoster.kz и idhost.kz

TABLE accounts
#*	login	goldy		a_bekzat
\*	site	jnet.kz		jnet.kz	
\*	hoster	hoster.kz	idhost.kz


Если мы удалим goldy из таблицы accounts, то потеряем информацию о том, что jnet.kz хостится hoster.kz. Чтобы избежать подобной аномалии, приведем таблицу к BCNF добавлением таблички site_hosters

TABLE accounts
#*	login	
\*	site	 
\*	hoster

TABLE site_hosters
\*	site	jnet.kz
\*	hoster	hoster.kz 

17 комментариев

webman
А как же формы более высокого порядка?)
yrnt
Важны ли они для практика?
webman
Если честно никогда не сталкивался, но вроде как Нормальная форма Бойса — Кодда используется
yrnt
Добавил про НБФК:).
webman
)) Интересно а реально если ли применения 4-5-6 формы?
yrnt
4-ю видел на практике. 5-ю и 6-ю еще ни разу не видел.
webman
Про текстовый способ не знал, интересно
webman
Если честно никогда не сталкивался, но вроде как Нормальная форма Бойса — Кодда используется ошибка
summerwind
В noSQL по сути так и получается, что в одном документе хранится и информация о пользователе, и его логи, и его посты, и т.д. Но это не останавливает многих использовать noSQL даже на сайтах уровня небольшого блога
yrnt
Кому-то удобнее работать с документами, а не sql-строками. Размер проекта здесь неважен.
summerwind
А мне кажется, что важен, т.к. noSQL специально заточен на масштабируемость и производительность для работы с большими объемами данных. А хранилище данных желательно как раз выбирать, исходя из специфики проекта, а не по субъективным симпатиям
yrnt
1. Саня, посмотри на комментарий, на который я отвечал.
даже на сайтах уровня небольшого блога
Я лишь указал, что не в размере дело:). Для большинства noSQL — мода. С точки зрения сути и то, и другое — средства персистенса. Кто сказал, что тот же postgresql не справится с большим объемом данных? Или под большим объемом данных ты подразумевал Big Data?
2. Когда я писал об удобстве, я не имел ввиду субъективные симпатии. Плз, посмотри в Википедии определение слова «Удобство»:).
summerwind
Что-то тут уже цепляние к словам пошло…
Размер (количество данных) проекта это только один из параметров, который имеет значение. Есть и другие факторы, по которым выбирается бд. Структурированность данных, например.
Если бы postgres, mysql идеально решали все проблемы во всех случаях, тогда не было бы смысла изобретать еще один подход к хранению данных. Из этого вывод, что для каких-то задач/видов проектов noSQL подходит лучше. В то же время есть проекты, для которых лучше подходит RDB (мой пример с блогом). Смысл моего комментария в том, что многие не учитывают этого и мирятся с денормализацией и другими пережитками noSQL. Либо noSQL, действительно, уже во всех сферах превосходит SQL, либо просто эти люди где-то увидели, что «это хорошо» и не разобрались, где именно.
yrnt
Что-то тут уже цепляние к словам пошло…
Была необходимость, чтобы мы пришли к одинаковому пониманию некоторых слов:).

Смысл моего комментария в том, что многие не учитывают этого и мирятся с денормализацией и другими пережитками noSQL. Либо noSQL, действительно, уже во всех сферах превосходит SQL, либо просто эти люди где-то увидели, что «это хорошо» и не разобрались, где именно.
p.s. noSQL никогда не заменит SQL, надеюсь не надо объяснять почему:)?
p0is0n
Нет, это не правда.
summerwind
Что «не правда»?
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.