Почему ограничение применяется в базе данных? Разве это не будет более гибким, чтобы поместить это в коде?
Я читаю книгу для начинающих по реализации баз данных, поэтому я спрашиваю это как новичок. Допустим, я разработал базу данных, включая эту модель сущности:
entity type | sub-types
----------------+--------------------------------------------
Person | Employee, Student, ...
Student | Graduate, Undergraduate, ...
Employee | Teacher, Administrator, ...
Текущие ограничения:
- Зарегистрированным лицом в системе может быть только Студент или Сотрудник.
- Личность лица требует уникальности социального номера, который, как мы предполагаем, у каждого человека есть только один уникальный (иначе говоря, достаточно хороший первичный ключ). (см. № 1)
Позже мы решим удалить число 1. Если однажды колледж решит, что Teacher
( Employee
подтип) также может быть Student
, посещая курсы в свободное время, гораздо сложнее изменить структуру базы данных, которая может иметь тысячи, миллионы, миллиарды, миллионы записей, а не просто изменение логики в коде: только та часть, которая не позволяла человеку быть зарегистрированным как студентом, так и сотрудником.
(Это очень невероятно, но сейчас я не могу думать ни о чем другом. Видимо это возможно).
Почему мы заботимся о бизнес-правилах в дизайне базы данных, а не в коде?
# 1: примечание 7 лет спустя, пример из реальной жизни:
я видел правительство, в котором из-за ошибки дублировались выданные SSN: несколько человек, один SSN. Те, кто разрабатывал исходную БД, определенно допустили ошибку, не применяя это ограничение уникальности в базе данных. (а позже ошибка в исходном приложении - несколько приложений, использующих общую базу данных и не согласных с тем, где поставить, проверить и применить ограничение? ...).
Эта ошибка будет продолжать существовать в системе и во всех разработанных системах, которые полагаются на базу данных этой исходной системы в течение многих лет. Читая ответы здесь, я научился применять все ограничения, как можно больше, мудро (не слепо) в базе данных, чтобы представить реальный физический мир настолько хорошо, насколько я могу.
источник
Ответы:
Некоторые ограничения лучше всего применяются в базе данных, а некоторые лучше всего применяются в приложении.
Ограничения, которые лучше всего применяются в базе данных, обычно присутствуют, потому что они имеют основополагающее значение для структуры модели данных, например, ограничение внешнего ключа для обеспечения допустимости продукта
category_id
.Ограничения, которые применяются в приложении, могут не иметь принципиального значения для модели данных, например, все продукты FooBar должны быть синего цвета, но позже кто-то может решить, что FooBars также может быть желтым цветом. Это логика приложения, которая не обязательно должна присутствовать в базе данных, хотя вы можете создать отдельную
colours
таблицу, и база данных может потребовать, чтобы продукт ссылался на действительную запись из этой таблицы. НО решение о том, что единственная запись вcolours
имеет значение,blue
все равно будет приходить откуда-то за пределами базы данных.Подумайте, что произойдет, если у вас не было ограничений в базе данных, и вы требовали, чтобы все они применялись в приложении. Что произойдет, если у вас будет более одного приложения, которое должно работать с данными? Как будут выглядеть ваши данные, если разные приложения решат по-разному применять ограничения?
В вашем примере показана ситуация, когда было бы выгоднее иметь ограничение в приложении, а не в базе данных, но, возможно, была фундаментальная проблема, связанная с тем, что исходная модель данных была слишком ограничительной и негибкой?
источник
teachers_as_students
которая называется другим подтипомStudents
и имеет новый внешний ключ, ссылающийся наTeachers
, и сгенерированный системой первичный ключ вместо Social. Номер безопасности. Таким образом, «ученик» на самом деле является псевдонимом для учителя, поэтому учитель все еще может зарегистрироваться, чтобы посещать занятия. Трудно сказать наверняка, насколько хорошо это будет работать, не видя всей модели данных.color_products
, иcolor
вы, вероятно, сможете создавать дополнительные раскрывающиеся списки с большей легкостью - большинство IDE / загрузчиков схем поддерживают следующие fkeys.Так как:
Просто несколько причин, которые важны для меня.
источник
Данные, скорее всего, долго будут жить после кода приложения. Если правило имеет решающее значение для данных, полезных во времени (например, ограничения внешнего ключа, которые помогают сохранить целостность данных), оно должно быть в базе данных. В противном случае вы рискуете потерять ограничение в новом приложении, которое попадает в базу данных. Мало того, что несколько приложений обращаются к базам данных (включая те, которые могут не понимать, что существует важное правило данных), но некоторые из них, такие как приложения импорта данных или отчетов, могут не иметь возможности использовать уровень данных, установленный в основном приложении ввода данных. Откровенно говоря, шансы на наличие ошибки в ограничении намного выше в коде приложения по моему опыту.
По моему личному мнению (основываясь на более чем 30-летнем опыте работы с данными и опыте работы с сотнями различных баз данных, используемых для самых разных целей), любой, кто не поместит ограничения в базу данных, которой он принадлежит, в конечном итоге получит плохие данные. Иногда плохие данные до такой степени, что их невозможно использовать. Это особенно верно, когда у вас есть финансовые / нормативные данные, которые должны соответствовать определенным критериям аудита.
источник
Большинство ограничений ссылочной целостности, которые реализованы вне базы данных, могут быть побеждены, поэтому, если вы хотите, чтобы ваши данные всегда имели гарантированную целостность, вы должны применить ограничения в базе данных. Полная остановка, вот и все.
Как правило, ограничения уровня приложения снимаются с помощью механизма согласованности чтения базы данных, с помощью которого сеансы не могут просматривать данные других сеансов, пока они не будут зафиксированы.
Например, два сеанса могут попытаться вставить одно и то же значение в столбец, который должен быть уникальным. Они оба могут проверить в то же самое время , что значение не существует, может и вставить их значение, и оба могут совершить. Уникальное ограничение, реализованное в базе данных, не позволит этому случиться.
Кстати, это не неизвестно разработчикам языка приложений. Прочтите раздел 3.10 «Уникальность» в руководствах по Ruby on Rails: проверки правильных записей и обратные вызовы
источник
Преимущества ограничений, накладываемых базой данных:
Простота. Объявление ограничения значительно проще, чем объявление ограничения и написание кода, который обеспечит выполнение этого объявления.
Точность - код, который вы не написали, никогда не будет иметь ошибки, которую вы создали. Поставщики баз данных тратят время на то, чтобы убедиться, что их код ограничения точен, поэтому вам не нужно этого делать.
Скорость - Ваше приложение никогда не может иметь больше дистрибутивов, чем база данных, на которой оно основано. Поставщики баз данных тратят время на то, чтобы убедиться, что их код ограничения эффективен, так что вам это не нужно. Сама база данных также имеет более быстрый доступ к данным, чем приложение, независимо от того, насколько оно эффективно.
Повторное использование - вы можете начать с одного приложения на одной платформе, но это может не произойти. Что если вам нужен доступ к данным из другой ОС, другого оборудования или из голосового интерфейса? Имея ограничения в базе данных, этот код никогда не должен быть переписан для новой платформы и никогда не должен быть отлажен для точности или профилирован для скорости.
Полнота - приложения применяют ограничения при вводе данных в базу данных и требуют дополнительных усилий для проверки точности старых данных или для манипулирования данными, уже находящимися в базе данных.
Долговечность - Ваша платформа базы данных, скорее всего, переживет любое конкретное приложение.
источник
Почему ограничения применяются на сервере? Потому что вы не можете заставить плохих парней использовать ваш клиент.
Для пояснения: если вы выполняете только обработку бизнес-правил в своем клиентском приложении, тогда кто-то, использующий другой инструмент, может подключиться к серверу базы данных и делать все, что ему угодно, без каких-либо ограничений ваших бизнес-правил и проверок целостности. Остановить использование произвольного инструмента в любом месте сети очень сложно.
Если вы выполняете проверку целостности на сервере базы данных, то каждая попытка доступа к данным, независимо от инструмента, будет ограничена вашими правилами.
источник
Некоторые отличные ответы здесь и рискуют повторить другие мысли:
UPDATE
инструкцию непосредственно для базы данных, как ваше приложение предотвращает недопустимые изменения? Другая проблема с бизнес-правилами в приложении заключается в том, что перекомпиляция / повторное развертывание может быть затруднено, особенно для распределенных приложений, где возможно, что не все получат обновление одновременно. И, наконец, изменение бизнес-правил в приложении абсолютно ничего не делает с уже существующими данными, которые нарушают новые правила - если вы добавляете новое ограничение к данным, вам нужно исправить данные.В случае, когда вы прямо упоминаете, когда вы вдруг разрешаете что-то, что ранее не было разрешено, это на самом деле не проблема - вы удаляете любое принудительное ограничение, независимо от того, где оно существует. В противоположном случае, когда учителям внезапно перестают быть учениками, у вас потенциально есть куча данных для очистки, опять же, независимо от того, где ранее существовало ограничение.
источник
База данных может эффективно проверять ограничения. Лучше, чем код.
Ограничения целостности помогают базе данных находить эффективный план выполнения
Приложение видит прочитанное единообразно, поэтому вряд ли может гарантировать уникальность. В то время как база данных также может видеть незафиксированные данные.
источник
Краткий ответ ... для сохранения целостности данных (то есть точности и достоверности).
Исключение ...
Если база данных просто хранит данные одного приложения для одного пользователя, как, например, в большинстве баз данных Sqlite, для нее могут не потребоваться ограничения. На самом деле, они обычно этого не делают, чтобы время доступа было таким быстрым, что это неизмеримо.
Для всего остального ...
Базы данных всегда обслуживают двух мастеров, которых я назову редакторами и пользователями .
Редакторы в основном помещают данные в базу данных и извлекают данные по одной или небольшому количеству записей за раз. Их основными задачами являются быстрый, точный доступ ко всем связанным частям данных и быстрое и надежное хранение их изменений.
Пользователи в основном извлекать данные и наиболее связаны с быстрым доступом к бесспорно точной информации. Они часто нуждаются в различных подсчетах, агрегациях и списках, которые раньше создавались в этих легендарных стопках распечаток зеленой бумаги, но обычно сегодня попадают на веб-страницы.
Проекты по разработке баз данных почти всегда начинаются по поручению пользователей , но дизайн основывается на потребностях редакторов во вводе данных и одновременной записи . Как таковые, неопытные разработчики часто отвечают на насущную потребность в скорости (прежде всего, в разработке ), не накладывая ограничений на базу данных.
Если одно и только одно приложение когда-либо будет использоваться для внесения изменений в данные в течение всего срока службы базы данных, и это приложение разработано одним или небольшим числом хорошо скоординированных лиц, то было бы разумно полагаться на приложение для обеспечения целостности данных.
Однако, насколько мы притворяемся, что можем предсказывать будущее, мы не можем.
Усилия по созданию какой-либо базы данных слишком ценны, чтобы их выбрасывать. Как и дом, база данных будет расширяться, изменяться и обновляться много раз. Даже после полной замены все данные будут перенесены в новую базу данных с сохранением всех старых бизнес-правил и отношений.
Ограничения реализуют эти правила и отношения в краткой декларативной форме в самом ядре базы данных, где они легко доступны. Без них последующим разработчикам пришлось бы пролистывать прикладные программы, чтобы перепроектировать эти правила. Удачи!
Кстати, это именно то, что должны делать программисты на COBOL, так как эти массивные базы данных часто создавались до того, как у нас были реляционные движки и ограничения. Даже если они перенесены в современную систему, такую как IBM DB2, ограничения иногда не реализуются полностью, поскольку логика старых правил, воплощенная, возможно, в серии «пакетных» программ на языке COBOL, может быть настолько запутанной, что их непрактично преобразовывать. Вместо этого можно использовать автоматизированные инструменты для преобразования старого COBOL в более новую версию с интерфейсами для нового реляционного механизма и с небольшими изменениями, сохраняя целостность данных ... до тех пор, пока не будет написано новое приложение, которое слегка повреждает все, и компания поднимается скажем, в суде за взыскание с тысяч домовладельцев, которых у них не должно быть.
источник
В дополнение к другим комментариям ...
Если / когда у вас есть база данных, где любая данная таблица может быть обновлена одним или несколькими приложениями или путями кода, то размещение соответствующих ограничений в базе данных означает, что ваши приложения не будут дублировать «тот же» код ограничения. Это выгодно для вас за счет упрощения обслуживания (уменьшение количества мест, которые нужно изменить, если / когда происходит изменение модели данных), и гарантирует, что ограничения применяются последовательно независимо от того, как приложение обновляет данные.
источник
Лично я думаю, что проще создавать и изменять ограничения, чем, например, создавать триггеры, что будет одним из способов обеспечения соблюдения вашего бизнес-правила с использованием исходного кода.
Кроме того, триггеры с меньшей вероятностью будут переносимыми, так как они обычно пишутся на языках конкретного поставщика, таких как PL / SQL.
Но если ограничения не соответствуют вашим потребностям, вы всегда можете использовать триггеры для обеспечения соблюдения ваших бизнес-правил.
источник
Они всегда должны сначала применяться в базе данных, потому что,
varchar(5)
тип, есть большая вероятность, что вы сможете найти схему, загружающую ORM для вашего конкретного языка, которая сопоставляет тип языка с типом схемы и собирает свое собственное ограничение на размер.DBIx for Perl is one such schema loader
; вот еще один для Entity Framework . Возможности этих загрузчиков различны, но все, что они могут предоставить, является хорошим началом для обеспечения целостности приложения без использования базы данных.источник