Что случилось с ограничениями базы данных?


46

Когда я рассматриваю модели баз данных для RDBMS, я обычно удивляюсь, обнаружив, что ограничения практически отсутствуют (кроме PK / FK). Например, процент часто хранится в столбце типа int(хотя это tinyintбыло бы более уместно), и нет CHECKограничения для ограничения значения до диапазона 0..100. Аналогично в SE.SE ответы, предлагающие проверочные ограничения, часто получают комментарии, указывающие на то, что база данных является неподходящим местом для ограничений.

Когда я спрашиваю о решении не применять ограничения, члены команды отвечают:

  • Либо они даже не знают, что такие функции существуют в их любимой базе данных. Это понятно для программистов, использующих только ORM, но гораздо меньше для администраторов баз данных, которые утверждают, что имеют более 5 лет опыта работы с данной RDBMS.

  • Или то, что они применяют такие ограничения на уровне приложений, и дублирование этих правил в базе данных не является хорошей идеей, нарушая SSOT.

В последнее время я вижу все больше и больше проектов, в которых даже внешние ключи не используются. Точно так же я видел несколько комментариев здесь на SE.SE, которые показывают, что пользователи не заботятся о ссылочной целостности, позволяя приложению справиться с этим.

Отвечая на вопрос команд о выборе не использовать FK, они говорят, что:

  • Это PITA, например, когда нужно удалить элемент, на который есть ссылки в других таблицах.

  • NoSQL качается, и там нет внешних ключей. Поэтому они нам не нужны в РСУБД.

  • Это не имеет большого значения с точки зрения производительности (контекст, как правило, представляет собой небольшие веб-приложения для интрасети, работающие с небольшими наборами данных, поэтому даже индексы не будут иметь большого значения; никого не волнует, если производительность данного запроса превышает 1,5 с. до 20 мс)

Когда я смотрю на само приложение, я систематически замечаю два паттерна:

  • Приложение правильно очищает данные и проверяет их перед отправкой в ​​базу данных. Например, нет способа сохранить значение 102в процентах через приложение.

  • Приложение предполагает, что все данные, которые поступают из базы данных, являются абсолютно действительными. То есть, если он выражается 102в процентах, либо что-то, где-то произойдет сбой, либо это будет просто отображаться пользователю, что приводит к странным ситуациям.

  • Хотя более 99% запросов выполняется одним приложением, со временем начинают появляться скрипты - либо скрипты, запускаемые вручную при необходимости, либо задания cron. Некоторые операции с данными также выполняются вручную над самой базой данных. Как скрипты, так и ручные SQL-запросы имеют высокий риск введения недопустимых значений.

И тут возникает мой вопрос:

Каковы причины для моделирования реляционных баз данных без проверочных ограничений и в конечном итоге даже без внешних ключей?


Что бы это ни стоило, этот вопрос и ответы, которые я получил (особенно интересное обсуждение с Томасом Килианом), побудили меня написать статью с моими выводами на тему ограничений базы данных .


8
Я чувствую к вам, но, кажется, вы уже знаете, почему ограничения являются хорошей идеей, так что добавить нечего в форме ответа. Я отмечу, однако, что отсутствие ограничений не является новым явлением, я видел его в течение десятилетий в базах данных, разработанных разработчиками без глубокого понимания реляционных баз данных. Я думаю, что это редко продуманное дизайнерское решение.
JacquesB

1
@JacquesB: вы можете опубликовать ответ, так как «Я видел его десятилетиями» дает совершенно другое видение того, которое у меня было для явления, появившегося три-четыре года назад (учитывая, что я работал в IT менее десятилетие мое мнение о явлении, вероятно, неверно). Таким образом, выводы будут очень разные.
Арсений Мурзенко

1
Мы работаем с большим количеством клиентов. И хотя развертывание новой версии нашего программного обеспечения - дело простое, обновление всей базы данных везде - это боль. Вот почему у нас больше всего ограничений в программном обеспечении. О, да, крошечная цифра для процента часто не очень хорошая идея, потому что проценты могут быть дробями.
Питер Б

1
Голосование за то, чтобы вновь открыть этот вопрос, поскольку оно было ошибочно закрыто как «главным образом основанное на мнении», когда ответы пока показывают, что это не так.
Дэвид Арно

3
Я с тобой 110%.
Периата Breatta

Ответы:


28

Важно различать разные варианты использования баз данных.

Доступ к традиционной бизнес-базе данных осуществляется несколькими независимыми приложениями и службами и, возможно, напрямую авторизованными пользователями. Очень важно иметь хорошо продуманную схему и ограничения на уровне базы данных, поэтому ошибка или недосмотр в одном приложении не повредит базу данных. База данных является критически важной для бизнеса, что означает, что непоследовательные или поврежденные данные могут иметь катастрофические результаты для бизнеса. Данные будут жить вечно, пока приложения приходят и уходят. В этих местах может быть выделен администратор базы данных для обеспечения согласованности и работоспособности базы данных.

Но есть также системы, в которых база данных тесно интегрирована с одним приложением. Автономные приложения или веб-приложение с единой встроенной базой данных. Пока база данных доступна только одному приложению, вы можете считать ограничения избыточными - при условии, что приложение работает правильно. Эти системы часто разрабатываются программистами с упором на код приложения и, возможно, не имеют глубокого понимания реляционной модели. Если приложение использует ORM, ограничения могут быть объявлены на уровне ORM в форме, более знакомой программистам приложения. На начальном этапе у нас есть PHP-приложения, использующие MySQL, и долгое время MySQL вообще не поддерживал базовые ограничения, поэтому вам пришлось полагаться на прикладной уровень для обеспечения согласованности.

Когда разработчики из этих разных слоев общества встречаются, вы сталкиваетесь с культурой.

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


5
+! 1 за упоминание слона в комнате: ложное предположение, что одно приложение использует только одну БД, а одна БД используется только одним приложением
Tulains Córdova

4
@ TulainsCórdova, я думал, что слон в комнате был системой начисления заработной платы Google. :)
Мачадо

5
@Machado Это гениально: «Я готов поспорить, что их система начисления заработной платы работает на реляционной базе данных с множеством ограничений».
Тулаинс Кордова

2
Также удобно иметь правильно ограниченные базы данных, так как код вашего приложения не является ACID.
Мэтью Уайтед

3
Просто чтобы подчеркнуть комментарий, сделанный @MatthewWhited, приложения не могут применять некоторые виды ограничений между строками / таблицами без выполнения блокировки и выполнения дополнительных запросов. СУБД может сделать это с гораздо меньшими затратами.
Дэвид Олдридж

15

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

При этом все приложения, которые должны масштабироваться, ограничены теоремой CAP , в которой вы должны выбрать 2 из 3: согласованность, доступность и допуск раздела (отказоустойчивость сети).

Изучая теорему CAP, вы увидите, что выбора не так много, как выбрать потерю доступности или согласованности, поскольку вы НИКОГДА не можете реально доверять сети 100% времени.

В целом, несколько приложений могут позволить себе быть несовместимыми в течение некоторого разумного периода времени, но не могут быть недоступны для пользователей. Например, немного неупорядоченная временная шкала в Facebook или Twitter лучше, чем отсутствие доступа к временной шкале вообще.

Таким образом, несколько приложений решили снять ограничения реляционной базы данных, поскольку реляционные базы данных действительно хороши в согласованности, но ценой доступности.

Личное примечание: я тоже старомоден, и я работал с некоторыми действительно старыми финансовыми системами, в которых согласованность данных является первоклассным требованием большую часть времени, и я большой поклонник ограничений базы данных. Ограничения базы данных являются последней линией защиты от многих лет плохой разработки и команд разработчиков, которые приходят и уходят.

"Есть способ в ребусе". Давайте продолжим использовать согласованность «низкого уровня» БД, где согласованность является первоклассным требованием. Но иногда отпустить это не большой грех в конце концов.

-- РЕДАКТИРОВАТЬ: --

Поскольку в вопросе есть небольшое изменение, есть еще одна законная причина для удаления ограничений в базе данных, IMO. Если вы разрабатываете продукт с нуля, где вы разрабатываете свою систему для поддержки технологии нескольких баз данных, вы можете согласиться на наименьший общий знаменатель среди поддерживаемых баз данных и в конечном итоге вообще отказаться от использования каких-либо ограничений, оставляя всю логику управления для ваше приложение.

Хотя это законно, для меня это также серая область, потому что сегодня я просто не могу найти какой-либо механизм базы данных, который бы не поддерживал простые ограничения, подобные предложенному в первоначальном вопросе.


«Сегодня я просто не могу найти ни одного движка базы данных, который бы не поддерживал простые ограничения, подобные предложенному в первоначальном вопросе» Поддерживает ли MySQL ограничения CHECK?
Винсент Савард

@VincentSavard, может быть, не то, что делает CHECK MS SQL, а какое-то ограничение: dev.mysql.com/doc/refman/5.7/en/constraint-invalid-data.html
Мачадо

@Machado - дело не в конкретных ограничениях, а в том, чтобы определить, когда запросы включают данные, которые не могут быть представлены в соответствующих типах. Это явное улучшение ситуации много лет назад, когда MySQL просто молча игнорировал такие значения.
Периата Breatta

1
@PeriataBreatta, в дополнение к этому, я так и не понял, почему MySQL была «де-факто» базой данных OSS, выбранной разработчиками веб-сайтов, когда PostgreSQL был полностью доступен и был более продвинутым. Может быть, это было легче установить, я не знаю.
Мачадо

@Macado - я не могу быть уверен , но я знаю, что в первые дни (еще в середине 90-х) я склонялся к тому, чтобы предпочесть mysql postgres (который позже не переименовывался в postgresql) из-за неправильного представления о postgres не поддерживал SQL (его ранние версии не поддерживали - у него был собственный язык запросов, называемый «постквель»), и я не отставал от его разработки, поэтому не осознавал, что они добавили поддержку SQL примерно в то же время MySQL стал доступен). Если это заблуждение было обычным делом, возможно, именно благодаря этому mysql вырвался вперед. И как только это было впереди, сетевые эффекты вступили во владение.
Периата Breatta

10

Каковы причины для моделирования реляционных баз данных без проверочных ограничений и в конечном итоге даже без внешних ключей?

Для начала давайте выясним, что я говорю здесь только о RDBM, а не о базах данных без SQL.

Я видел несколько баз данных без FK или PK, не говоря уже о проверке ограничений, но, честно говоря, их меньшинство. Возможно, потому что я работаю в большой компании.

По своему опыту на протяжении многих лет я могу сказать, что некоторые причины могут быть:

  • В случае начинающих или хобби программистов, все навыки моделирования
  • Широкое или почти исключительное использование ORM без реального контакта с миром баз данных
  • Отсутствие администратора базы данных или другого эксперта по моделированию данных в команде или небольшом проекте
  • Недостаточная вовлеченность DBA или эксперта по моделированию данных на первых этапах разработки
  • Умышленные проектные решения по части сообщества разработчиков , который считает , что даже проверочное ограничение , которое навязывает , что определенный столбец может только иметь в 1,2 or 3качестве значения, или что столбец «возраст» должен быть >= 0в «имея бизнес - логику в базе данных» . Даже предложения по умолчанию рассматриваются некоторыми как бизнес-логика, которая не принадлежит базе данных, как вы можете видеть в нескольких недавних вопросах и ответах на этом самом сайте. Разработчики, которые так считают, очевидно, будут использовать как можно меньше ограничений и будут делать все в коде, даже ссылочную целостность и / или уникальность. Я думаю, что это крайняя позиция.
  • Использование RDBM в качестве хранилищ значений ключей , либо для эмуляции поведения без SQL, поскольку требования достаточно просты, чтобы их можно было удовлетворить с помощью таблиц RDBMS в качестве изоляторов хранилищ значений ключей.
  • Предполагая, что база данных всегда будет записываться «приложением», и что никому не понадобится выполнять массивную загрузку данных, редактировать или вставлять строки через клиент SQL (во многих случаях для исправления неверных данных, вставленных приложением). В лучшем случае в сценарии всегда будет другое приложение (помимо «приложения»), выдающее инструкции DML для базы данных: клиент SQL.
  • Не понимая, что данные принадлежат владельцу бизнеса , а не приложению.

Тем не менее, я хотел бы заявить, что RDBMS являются очень продвинутыми частями программного обеспечения, которые были созданы на плечах гигантов и оказались очень эффективными для многих бизнес-требований, освобождая программистов от рутинных задач по обеспечению ссылочной целостности в серии. двоичных файлов или текстовых файлов. Как я всегда говорю, «мы больше не живем в мире« одно приложение - одна база данных » . По крайней мере, клиент SQL будет выпускать DML помимо «приложения». Таким образом, база данных должна защищать себя от ошибок человека или программирования в разумных пределах.

В тех хорошо известных типах требований, в которых СУБД не будет хорошо масштабироваться, во всех случаях используется технология без SQL . Но это беспокоит распространение реляционных баз данных без каких-либо ограничений, когда тысячи строк кода (сгенерированных или напечатанных) выделены для обеспечения того, что СУБД должна обеспечивать для вас более эффективными способами.


3

Существуют внешние ограничения, которые определяют технологические решения. Есть всего несколько ситуаций, когда у вас есть необходимость или роскошь использовать ограничения полей базы данных на регулярной основе.

  1. На предприятиях есть разработчики приложений и баз данных, а также администраторы баз данных, но большинство разработчиков не работают в такой среде. Они делают столько, сколько могут в коде. Кроме того, некоторые на стороне базы данных не вмешиваются в бизнес-правила. Они в первую очередь там, чтобы держать вещи в рабочем состоянии. Они никогда не будут настаивать на ограничениях в БД. Лучше всего иметь дело с унаследованными приложениями, интеграциями, миграциями, слияниями, поглощениями.
  2. Перегрузка базы данных может создать узкое место, которое нелегко решить, выбрасывая больше машин для решения проблемы. В некоторых ситуациях язык db не справляется с некоторыми проблемами программирования без существенного снижения производительности, поэтому вы не можете планировать использовать ограничение для всего. У Stackoverflow есть один сервер базы данных, потому что бросить 2 на проблему - проблема.
  3. Автоматизированное тестирование - они добираются, но многие разработчики БД опаздывают на вечеринку вместе со средами IDE / тестирования.
  4. Развертывание - чем больше дБ, тем сложнее. Что происходит, когда обновление базы данных клиента не разрешено, поскольку существуют данные, которые нарушают ограничение? Игра окончена, если у вас нет способа решить эту проблему. В вашем приложении вы можете разрешить пользователю обрабатывать это по мере необходимости или поручить администратору сделать это в пакете.
  5. Только приложение / api / service будет когда-либо записывать данные в базу данных, так зачем? Это действительно поддерживает большую часть времени, поэтому это не распространено.
  6. Обрабатывать ошибки БД достаточно сложно, без сотен нарушений ограничений, с которыми приходится бороться, если все выходит из строя. Большинство из них рады установить соединение и получить правильное имя таблицы.

Многие команды разработчиков не хотят давать слишком много контроля разработчикам БД. Тебе повезло, если ты получишь больше, чем один, поэтому отпуск - это очень весело. Не многие требуют абсолютного контроля над доменом базы данных и несут ответственность за каждый запрос, бизнес-правило, производительность, доступность, безопасность и какие данные поступают в какой RAID. Вот хранимые процедуры, которые вам разрешено выполнять. Веселиться. Даже не думай касаться стола.


2

Это проблема, с которой я боролся всю свою карьеру (почти 40 лет), а также при написании своей СУБД. Описание моей конечной точки здесь: http://unibase.zenucom.com . Итак, вот мои мысли.

  1. Вообще говоря, большинство ограничений лучше обрабатываются в приложении, чтобы разные части приложения могли применять разные ограничения. например, код штата может применяться не во всех юрисдикциях.
  2. В сторону остерегайтесь%. Наценки> 100% или вы разорились :)
  3. Ограничения лучше всего описаны негативно. то есть тем, кем они не могут быть, а не тем, кем они должны быть. Это всегда более простой список.
  4. Внешние ключи всегда хороши и должны использоваться. Полная остановка. FK является одной из немногих семантических конструкций в СУБД и очень полезна. Самая большая трудность - решить, следует ли позволить значению свисать, если удален FK, или использовать зависимые строки в качестве причины, чтобы не удалять запись FK.
  5. Ограничения в реальном мире обычно более сложны, чем ограничение значения одного поля.
  6. Некоторые ограничения, даже на уровне приложений, работают против хороших операций. например, агрессивная проверка даты скрывает ошибки в явно хорошие даты. Вам нужна ошибка оператора, чтобы получить меру ошибок в других разумно выглядящих датах.

1

Ограничения базы данных могли бы быть разумной идеей, но как насчет их практического использования? Возьмите свое процентное ограничение. Если вы примените это, ваша БД с радостью отклонит недействительные проценты. А потом? Вам понадобится бизнес-логика для обработки исключения. Что фактически означает, что бизнес-логика, пишущая неправильный процент, уже потерпела неудачу в другом месте. Итак, вкратце: единственное практическое ограничение - это те, которые вы видите (например, PK / FK).


15
Я вежливо с этим не согласен. Если вам действительно нужна согласованность данных, ограничения БД являются обязательными, особенно если ваша бизнес-логика не работает. Как вы описываете сценарий, произойдет тихий сбой, при котором ущерб от неправильного процентного сбоя будет распространяться дальше в системе. Если у вас есть ограничение БД по этому поводу, вы быстро потерпите неудачу и, таким образом, дадите разработчикам бизнес-логики возможность заранее увидеть ошибку и исправить систему бизнес-логики вместо того, чтобы допускать в нее поврежденные данные.
Мачадо

5
Насколько я понимаю, если процентное ограничение нарушается, вам не нужно обрабатывать это исключение, потому что такое нарушение указывает на то, что изначально в вашем коде есть ошибка (либо кто-то использовал простое целое число вместо экземпляра Percentageкласса, или есть ошибка в самой проверке), в отличие от исключительного случая (например, не работает сетевое соединение). Для меня нарушение должно было привести к HTTP 500 для веб-приложения или к аварийному завершению для настольного приложения, а затем оно должно быть зарегистрировано и исправлено.
Арсений Мурзенко

7
@ThomasKilian: нет; с точностью до наоборот. Неправильные данные не попадут, особенно потому, что существуют ограничения базы данных. Если ваша бизнес-логика верна в коде, вы никогда не будете нарушать эти ограничения. Если в коде произошла ошибка, эти ограничения предупредят вас об этой ошибке, сохраняя при этом базу данных в безопасности.
Арсений Мурзенко

9
@ThomasKilian: Я не думаю, что кто-то спорит против «сделать все правильно» - вероятно, больше всего кто-то с небольшим опытом знает, что это плохая идея - проектировать систему, предполагая, что вы будете в первый раз все правильно, и никаких ошибок или ошибок не произойдет в течение всего срока службы системы. Ограничения БД гарантируют, что ошибка или ошибка не повредят базу данных.
JacquesB

3
@JacquesB Я сражаюсь против ветряных мельниц. Если вы поместите бизнес-логику в БД, она также может потерпеть неудачу, как и прежде, и не сможет спасти вас таким же образом. Но (!) Теперь у вас есть бизнес-логика, которой она не принадлежит. Полагать, что БД может спасти вашу гнилую бизнес-логику, просто неправильно. Логика в БД должна следовать тем же правилам, что и вся бизнес-логика.
qwerty_so

1

В наши дни люди чаще используют программное обеспечение (например, Entity Framework) для автоматического создания таблиц и столбцов. Идея в том, что они не нуждаются в навыках SQL, освобождая умственные способности.

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

Для достижения наилучших результатов создавайте таблицы с использованием SQL и добавляйте ограничения вручную, но иногда люди не могут этого сделать.


Конечно, некоторые фреймворки поддерживают автоматическое добавление PK и FK (полу).
Дэвид Олдридж
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.