Как стать автором
Обновить

Комментарии 74

>Забавно лишь, что вся эта белиберда под катом родилась в уме Кодда еще до возникновения SQL как языка, а теперь вот в терминах SQL все подавай…

Тогда эта «белиберда» не интересовала ремесленников :)
>Забавно лишь, что вся эта белиберда под катом родилась в уме Кодда еще до возникновения SQL как языка, а теперь вот в терминах SQL все подавай…

А что делать, если тут в основном стихийные веб программисты — самоучки, которые Кодда не читали и весь опыт по построению структуры базы данных брали от других программистов и от собственных ошибок?
Для них исчисление предикатов это нечто страшное и непонятное.
Я именно такой стихийный веб программист, однако предыдущую заметку понял без проблем, пропустив мимо внимания предикаты и дискретку. Чтобы понять, что такое 2NF совсем не обязательно знать о предикатах. Лично я закончил журфак и ничего страшнее логарифма в жизни не видел :) Правда 10-летний опыт сайтописательства, может быть, сказывается…
> пропустив мимо внимания предикаты и дискретку.

Лучше уж взяться когда-нибудь да прочитать книжечку по формальной логике и дискретке. Мозги хорошо вправляет
Кстати, не посоветуете ли чего-нибудь не сильно мозговыносящего? Давно хочу подтянуть математику, да не зная ВУЗовой программы не представляю, с какого края взяться.
Дома у меня лежит небольшая книжка, приду домой, выпишу авторов.
У нас реляционную теорию преподают по книге Д. Мейера.
Но мозг выносит временами.
В любом случае специалист-самоучка, ставший таковым стихийно, сталкивается рано или поздно с задачами или потребностями, для решения и удовлетворения которых уже не хватает опыта, а требуется окунуться в теорию. Если же такой момент еще не наступил, то можно ничего не делать :) А если приперло, но буквы в голову не лезут, можно, пока не поздно, посмотреть по сторонам на другие (рабочие) специальности, которые не требуют знания дисциплин высшей школы.
Казалось бы в статье описаны на столько элементарные и очевидные вещи, но кто-то на этом сайте, где сидят толпы девелоперов БД и еще больше веб-программистов кто-то может не знать о нормализации и денормализации БД?
Они вполне могут понимать её интуитивно, но быть не в курсе четкой терминологии
На самом деле, то что многие понимают интуитивно, они на самом деле понимают так как им обьяснили другие. Это как испорченный телефон, который через умыи и слова других передал все в чей то мозг, то есть по сути человек принял чтото на веру.

Он может угадать в своей интуиции, а может и не угадать, тут как повезет. Мне, если честно, непонятно как человек будет проводить декомпозицию доменной области, если он не понимает понятий функциональной зависимости, потенциальных ключей и возможных последствий своих действий.
Открою вам страшную тайну: бывает так, что даже senior developer'ы (как указано в их резюме) с большим стажем работы не могут ответить на вопрос что такое нормализация базы данных. Вообще НИЧЕГО.
потому что senior developer нормализацию базы выполняет на полном автоматизме. если он действительно достоен этого звания. знать четкое определение нормальных форм это конечно прекрасно, но не всегда нужно. можно и посомтреть в гугле. главное уметь это делать.
… хотя ответ требовался «нормализация — это приведение к нормальной форме».
ну это простая логика скажем так, до этого можно дойти вообще ничего не зная о программировании и sql. так что если сениор девелопер не может так сделать, ему не место на этой должности.
Который за собой сразу ведет вопрос, что есть нормальная форма и какие нормальные формы вы знаете? Перечислите их хотя-бы то третьей.
Кто-то получает это звание за стаж (выслугу лет), как в армии. О способностях таких людей решать абстрактные проблемы можно и не упоминать. А отдуваются обычно те, кто стоит под ними — обычные разработчики. Именно о таких я написал выше.
Только что приходил чел на собеседование, написал в скиллзах SQL. На просьбу написать простейший запрос из одной таблицы с одной группировкой написал слово SELECT, потом смутился и ушел.
А на какую должность-то шел?
программист Qt+SQL
Это же в любой книжке написано, зачем это тут?

Написали бы лучше статью в каких случаях можно и нужно нарушить xNF и для каких целей
Очень интересная идея, хочу! )
предлагаете мне написать? Тема больно скользкая, могут отхабрить по самое некуда, даже ИМХО не поможет.
Очень интересно в плане, что уже начал гуглить на тему. Вопрос фанатизма в применении таких штук (номализация, паттерны) тоже довольно остро стоит. Поверьте, мне интересно. Статью пока не обещаю, но кто знает.
Жаль нету на хабре возможности написать статью в соавторстве. Я бы поучаствовал. Есть кое-какой опыт антиNF извращений.

Если не напишите, это сделаю я, идея меня уже зацепила
Почему нету возможности? Соавтор упоминается в топике, а сама статья пишется в каком-нибудь совместном редакторе.
Плюсы и минусы все равно получит один.
Ну вы же здесь не только ради этого ;) Дерзайте.
уже обдумываю содержание :)
Если в двух словах, то как правило денормализация производится для данных для которых операция выборки осуществляется значительно чаще чем записи. В такой ситуации выигрыш от избежания большого количества join'ов превалирует над «стоимостью» обновления. В общем и целом как-то так
(FIXME)
НЛО прилетело и опубликовало эту надпись здесь
Не всегда нормализация это есть хорошо.
Запрос вида

SELECT Kids FROM Family WHERE kids LIKE 'С%'

не отработает в данной ситуации как нужно и не найдет Сашу


Зато SELECT Kids FROM Family WHERE find_in_set('Саша', kids); прекрасно отработает
и положит базу на большой нагрузке, ибо все же быстрее искать по индексу чем вот таким вот образом
«Большая нагрузка» — весьма размытое понятие, и 99 из 100 разработчиков в ней в жизни никогда не сталкиваются.

При большой нагрузке вообще часто приходится отказывать от нормализации. А при очень большой нагрузке от реляционных СУБД вообще.
это я с вами полностью согласен, но бывают некоторые уникумы которые вообще забивают на индексы, а потом при 1к хостов сервер ложится мертво… поэтому забывать про оптимизацию скорости работы никогда нельзя
Ну так они и про первообразные не слышали и про О большое и вообще про функцию сложности. Поэтому для них что линейная сложность, что константная, что логарифмическая, что степенная, один фиг.
Зря вы так думаете. Многие SQL-разработчики любят проверять набор данных на пустоту конструкцией вида (SELECT COUNT(*) FROM ....) > 0, которая запросто может положить на лопатки сервер даже с одним подключением, стоит только целевой табличке вырасти до пары лямов записей.
Он же должен заоптимизироваться СуБД и она должна же просто отдать количество записей без реального их анализа, нет?
должен, но если не сможет? Firebird, например, в упор не знает сколько записей в табличках, и на простейший запрос SELECT COUNT(*) FROM table будет каждую запись подсчитывать, проверено неоднократно.

Другое дело что запрос логически не корректен: вам надо узнать есть ли вообще записи, для этого достаточно получить только одну, а не считать их кол-во:

SELECT 1 FROM table LIMIT 1
>>LIMIT 1

Не помню такого в ANSI SQL99… TOP помню, а LIMIT это кажется MySQL лисапед.

>>Firebird, например, в упор не знает сколько записей в табличках, и на простейший запрос SELECT COUNT(*) FROM table будет каждую запись подсчитывать, проверено неоднократно.

А нечего использовать странные и сомнительные СуБД.
Мне например часто нужно число записей хотя-бы для вывода статистики, поэтому раз FireBird этого не умеет, то значит он идет лесом в пользу SQLite,MariaDB,Postgre
>>MariaDB
и вы еще призываете не использовать «странные и сомнительные СУБД»

SQLite вообще ничего не умеет, его область применения очень ограничена.
Это вполне себе MySQL с плюшками от его создателя.
Ограничена, но весьма полезна.
да, для своих задач он почти идеален
я написал LIMIT чтобы было понятнее большинству (MySQL). В MSSQL это TOP, в Firebird FIRST.

>> А нечего использовать странные и сомнительные СуБД
Вы разжигаете?? Тогда пишите минимум 5 пунктов почему Firebird это плохо
>>я написал LIMIT чтобы было понятнее большинству (MySQL). В MSSQL это TOP, в Firebird FIRST.

А потом получаются продукты, прибитые гвоздями к определенных СуБД. Я уже сказал, в ANSII это TOP, хотя LIMIT вроде сейчас уже все поддерживают.
Кстати если Firebird не поддерживает TOP'а, то это уже пункт номер два.
читайте внимательно, в Firebird это называется FIRST

Кстати у меня закрались сомнения что TOP описан в стандарте SQL99. Пруфом не поделитесь?
Я точно сейчас не найду, да и за pdf с текстом стандарта денюжку просят. Насчет именно 99 не уверен, может и в 2003 появился, но я своему преподу по базам данных таки доверяю.
да, и мало-мальски сложный продукт по-любому будет прибит гвоздями к реализации SQL, хотя бы в силу отсутствия внятных стандартов на синтаксис хранимых процедур.
В общем случае их нужно всячески избегать, а если уж и делать, то инкапсулировать как можно сильнее. Имхо хранимые процедуры — это костыль
Я думаю все наоборот: 99 из 100 разработчиков рано или поздно создают неоправдано большую нагрузку на СУБД.
Да, да. На рендер главной страницы WordPress брога требуется около 60 запросов к СУБД.

Разработчики может быть и создают большую нагрузку, но мало кто это осознаёт. В среднем уникальных посетителей любого сайта довольно мало, так что можно извращаться как угодно прежде чем «станет больно».

Согласитель, ведь главное — это не «делать по учебнику», а чтобы было а) удобно б) быстро по времени разработки в) легко читалось.

Когда же на сайт реально вырастает нагрузка, то можно предположить что и появляются ресурсы на рефакторинг мест, где тормозит. Так что метология «Scale on Demand» — самая выгодная с экономической точки зрения.
это не Scale on Demand а скорее Refactoring on Demand
Тем не менее такая схема на мой взгляд единственно верная для стартапов, сильно ограниченных в ресурсах.

Лучше потратить ресурсы на продвижение, чем сделать идеальный с технической точки зрения продукт, которым никто не пользуется. Ведь полпулярность продукта мало зависит от «нормальности» его БД, согласны?
Замечательно, а что если данные в записи будут разнородные, а что если вам нужно отсортировать всех деток по именам, а что если…?
В каждом случае приходится применять какие то решения выходящие за рамки обычного SQL — либо функцию использовать, либо запрос усложнить, либо упростить таблицу.
Кроме того, вы еще можете пожелать построить связи между таблицами, например заставить каждого ребенка ходить в детсад и хранить эту информацию в другой таблице. А связать как?
функция find_in_set относится только к какой-то конкретной реализации языка SQL
все это очень сложно и скучно, можно объяснить намного проще и короче:
1НФ: поле таблицы должно принимать только одно значение для данной записи (например возраст только один, а вот детей может быть много)
2НФ: все поля должны зависеть от ключа (например если ключом является название фирмы, то количество сотрудников зависит от ключа, а погода на Ямайке не зависит :))
3НФ: поля должны зависеть от ключа напрямую, т.е. без посредников в лице других полей (например в таблице фирм есть поля адрес и количество этажей в здании, адрес зависит от фирмы, а количество этажей зависит от адреса, который зависит от фирмы, значит это не 3НФ и количество этажей надо вынести в отдельную таблицу)
пардон про вторую нф немного соврал
фикс: 2НФ: если ключ составной, то все поля должны зависить от ключа целиком а не от части только (например ключ фио ребенка и адрес где он живет, так вот возраст зависит от обоих частей ключа (могут быть два ребенка в семье или тезки однофамильцы с разными адресами (ситуацию когда в семье два одинаковых имени у ребенка не берем)) а вот количество этажей в доме зависит только от адреса, но не зависит от фио)
Хех, вспомнился студенческий курс по «Базам Данных», где препод то и дело негодуя выкрикивал: «Боже, кто это написал!?».
Статья понравилась, написана понятно, с удовольствием «освежила» память.
Вот только формулировка 2NF мне больше нравится такая: «отношение находится в 2NF тогда, и только тогда, когда оно находится в 1NF и нет зависимости частей потенциального ключа от не ключевых атрибутов».
ИМХО, такая формулировка понятнее, но это сугубо мое личное мнение.
А у нас было определение такого рода "… тогда и только тогда, когда оно находится в 1НФ и каждый атрибут отношения функционально полно зависит от первичного ключа".
3НФ определялась как отношение, находящееся во 2НФ и не имеющее транзитивных или псевдотранзитивных функциональных зависимостей.
За доходчивое объяснение и правильную терминологию — спасибо.

Таблица из второго примера понравилась — точнее её контент. Пойду переслушаю все альбомы из неё :)
Запрос вида

SELECT Kids FROM Family WHERE kids LIKE 'С%'

не отработает в данной ситуации как нужно и не найдет Сашу, поскольку LIKE не умеет парсить списки, извлекать значения и трактовать их как аргументы для сравнения с шаблоном. ’Ваня, Саша’ в данном случае неатомарное значение типа список строк. Чтобы научить SQL работать с такими данными, нужно либо расширить язык, либо упростить модель до 1NF. Декомпозиция до 1NF достигается разбиением составного значения на атомарные

Кажется здесь критерием отбора служит часть слова — буква. Не значит-ли это, что атомарными значениями в данном являются буквы алфавита, а не имена?
Или по другому задам вопрос: как, с точки зрения 1NF, понимать «атомарность»?
Тут надо задать вопрос можете ли вы использовать части по отдельности? Если да — значение неатомарно и нужно его разделить (разнести либо по разным колонкам либо по строкам).

Например буквы из значения 'Ваня' не несут никакой смысловой нагрузки, они по отдельности вам не нужны, поэтому Ваня — неделим.
«Аня, Саша» можно разбить на «Аня» и «Саша», каждая часть которого имеет смысл для вас или приложения, поэтому это неатомарное значение.

Критерием отбора служит не часть слова, а истинность выражения kids LIKE 'С%', то есть 'С%' в запросе — это не значение, это просто параметр оператору.

Вообще вопрос упирается чисто в здравый смысл. Если по смыслу у вас тип колонки — координаты, то бессмысленно их разбивать если вы их всегда будете трактовать только вместе. З другой стороны, если вы будете оперировать координатами по отдельности, для приложения и для вас отдельная координата будет иметь смысл и следует их разбить.

Если у вас по смыслу в поле строка, то на буквы естественно делить ее не нужно, потому что для большинства задач, буквы не несут смысловой нагрузки.
а если мне потребуется составить алфавитный рубрикатор?
Если рубрикатор, то Google вы не сможете разбить на G и oogle, бо второе не имеет смысла. Хотя случай интересный, это как раз случай когда нормализация не имеет смысла. Хранить и поддерживать связь Буква — Сайт будет намного дороже, чем вычислять эту связь из списка сайтов.
Вопрос «почти в тему» — а каков наиболее правильный аналог Экселевского VLOOKUP средствами «чистого» SQL?
3NF нежизнеспособна в реальных проектах.
Несколько раз сталкивался с задачами денормализации БД.
Спасибо за перевод.
Все нормальные формы — теория. Хотя у военных неплохо прижились.
3NF нежизнеспособна в реальных проектах.
Несколько раз сталкивался с задачами денормализации БД.

ага, no school наше фсё. ;)

нормализация это один из методов анализа предметной области. денормализация — прием, используемый в процессе синтеза решения.

скажите ещё «ООП не жизнеспособно в реальных проектах — постоянно вижу лапшу в коде.» :)
ООП более, чем жизнеспособно. Только если без фанатизма %)
А мне понравился первый пост… Сразу вспомнилась молодость, универ и курс «теория баз данных» :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории