Подтвердить что ты не робот

Должны ли вы применять ограничения на уровне базы данных, а также на уровне приложений?

Я читал книгу "Enterprise Rails" Дэна Чака, и это заставило меня задуматься: считаете ли вы, что у вас должны быть ограничения данных как на уровне базы данных, так и на уровне приложений? Или вы чувствуете себя так же, как и устойные структуры, такие как Ruby on Rails - база данных - это просто "немой репозиторий" для данных, и все проверки должны выполняться в вашем приложении (я не пытаюсь выделить RoR здесь - я огромный поклонник Rails, но я не согласен с его подходом к базе данных)?

Лично я считаю, что вы должны иметь их обоих, чтобы убедиться, что ваша база данных и приложение хорошо защищены. Я имею в виду, что вы должны использовать ненулевые ограничения, дайте своим полям длину, если она известна (в отличие от оставления их всех в nvarchar (255)), имеют такие вещи, как Внешние ключи Проверить ограничения и Триггеры в вашей базе данных, а затем также применять это в соответствии с правилами бизнес-логики в вашем приложении. IMO делает ваше приложение надежным через свой пользовательский интерфейс, а также защищает от того, кто может иметь прямой доступ к базе данных.

Контр-аргумент, который я чаще всего вижу, заключается в том, что он требует того, что дублирует логику; один раз на уровне базы данных и один раз на уровне приложения. Скажем, у вас есть проверочное ограничение, чтобы проверить, что SKU продукта введен (т.е. длина больше нуля).

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

Я для одного не вижу в этом ничего плохого - да, у вас есть повторяющаяся логика, но конечным результатом является мышление "база данных как крепость", поскольку, если вы думаете об этом, ваши данные являются самой важной частью ваше приложение; в конце концов, какая польза от вашего блестящего нового приложения Web 2.0, если данные могут быть легко повреждены и скомпрометированы?

Что вы думаете об этом? Должна ли база данных быть непроницаемой крепостью, такой как Форт-Нокс, или открытым сейфом, охраняемым лазерами? Другими словами, следует ли жертвовать некоторым дублированием логики для обеспечения надежной модели данных или оставить все в своем приложении и использовать базу данных просто для хранения данных?

4b9b3361

Ответ 1

Короче: база данных должна обеспечивать соблюдение ограничений.

Почему:

  • Легче. чтобы установить ограничение на конкретный столбец данных, есть только одно место для его установки: сам столбец. Данные могут поступать из разных источников, но проверка помещается туда, где данные, наконец, отправляются на отдых.
  • Целостность. База данных должна нести ответственность за данные, которые она размещает. Непоследовательная база данных так же хороша, как и никакая база данных.
  • Гибкость. Новые среды разработки пользовательского интерфейса возникают слишком часто. Если база данных ставит свою руку, чтобы сказать, что она позаботится об ограничениях, разработка интерфейса и функциональное тестирование будут проще.

Ответ 2

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

Там нет гарантии, что глючный (или вредоносный) уровень "бизнес-логики" не будет вставлять токсичные данные в ваши таблицы. Конечно, если вы можете доверять другим слоям, вам, вероятно, это не понадобится. Но я работаю в мэйнфреймовом магазине, где администраторы баз данных всегда должны устранять проблемы, вызванные тем, что молодые Java-шлемофоны запускают свой кодовый код для производства без адекватного (любого?) Тестирования: -).

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

Ответ 3

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

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

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

Я редко использую триггеры. Я думаю, что они делают базу данных очень непрозрачной. Вы выпускаете простую команду update/insert/delete, и могут произойти странные вещи. Я думаю, есть два места, где триггеры неизбежны:

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

  • Если вы выполняете операции CRUD в представлении. Триггеры являются обязательными для операций вставки/обновления/удаления.

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

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

Jeff Atwoods этого мира предложит вам написать веб-сервис, с которым все приложения будут взаимодействовать. Веб-служба выполняет проверку данных. Это позволяет базе данных оставаться немым контейнером для хранения, что позволяет вам переключать базы данных. На самом деле вы редко меняете двигатели баз данных (если только вы не начали с Microsoft Access!). Если вы пишете веб-сервисы исключительно для централизации проверки данных, то я пытаюсь сделать это за бортом.

Ответ 4

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

Кроме того, используя базу данных как "немой репозиторий", вы, скорее всего, окажетесь в менее эффективном приложении. База данных может делать много вещей намного эффективнее, чем ваше приложение. Почему бы не воспользоваться этим?

Ответ 5

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

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

Должен ли вы проанализировать номер телефона, чтобы обеспечить его в правильном формате? Наверное, нет, но опять-таки вы должны, вероятно, сохранить номер телефона в схеме, которая не имеет проблемы с формированием.

Ответ 6

Как правило, всегда существует дублирование, а базы данных - это не просто немые репозитории.

дб

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

Вы не можете делать все в db, но можете многое сделать. Защитите данные.

бизнес-уровень

Переместившись на уровень, у вас есть бизнес-логика. Обычно это ваша точка интеграции с другими приложениями (веб-сервис, собственный пользовательский интерфейс и т.д.). Здесь бизнес-логика закодирована в приложении. Такие вещи, как если у продукта есть конечная дата x, то он также не может иметь место в y, если y имеет другую дату окончания.

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

также трудно выразить в базе данных другие "правила", такие как "у новых пользователей есть срок годности на 1 год, если они из Аркенсаса, в противном случае 2 года, если у них нет 3 детей, а один из них называется" Барри ". Мы можем смеяться над этим примером, но опытный программист скажет вам, что бизнес-логика - один из самых больших оксюморонов вокруг.

Ui

Переходя к пользовательскому интерфейсу, пользовательский интерфейс также регулярно кодирует бизнес-логику на экранах. Формы и другие страницы будут часто существовать в недопустимом состоянии, и это задача пользовательского интерфейса, чтобы знать правила, по крайней мере, большую часть времени. Надеемся, пользовательский интерфейс отменит логику для бизнес-уровня, но бизнес-уровень не имеет понятия, что поле 1 является обязательной датой, а поле 2 - это описание.

Пользовательский интерфейс знает, как искать продукты с X, если пользователь уже выбрал виджет Y. Пользовательский интерфейс знает, что требуется описание, и что количество элементов > 0 и < 100 (В этих примерах хороший пользовательский интерфейс будет полагаться на бизнес-уровень, чтобы рассказать об этом, например, min и max, но пользовательский интерфейс все еще знает о связи)

В веб-интерфейсе мы также добавляем клиент script, который снова дублирует логику в коде сервера. Мы используем клиентский script, чтобы лучше работать с пользователем, но, в конце концов, не доверяем чему-либо, что приходит от клиента (script можно отключить, обрабатывать поля формы вручную и т.д.)


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

Ответ 7

Если вы не применяете по крайней мере базовую целостность в базе данных, в какой-то момент недействительные данные попадут. Возможно, из приложения. ошибка, может быть, кто-то подтягивает консоль SQL, что угодно. И тогда вы узнаете, что ваше приложение имеет интересные режимы отказа, когда невозможное ( "все записи B должны иметь запись A, что вы имеете в виду, что она не существует?" ) Происходит.

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

Ответ 8

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

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

Во-вторых, я много работаю с Rails и миграциями ActiveRecord, не допускающим большого определения ограничений db-резидентов за пределами поля и NULL_ness.

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

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

Если вы создаете новое приложение/базу данных, ожидая, что другие приложения получат доступ к данным, тогда подход будет зависеть от того, как будут создаваться другие приложения. Опять же, в Rails вам, вероятно, следует взглянуть на способы обмена вашими моделями, и в этом случае этого слоя должно быть достаточно. Если вы не можете отказать другим стилям реализации от прямого доступа к вашим данным, вы вернетесь к дублированию. Мое предпочтение было бы - очень сложно - отрицать прямой доступ к этим приложениям и стремиться обслуживать их через веб-службу (надеюсь, RESTful), чтобы вы могли управлять целостностью данных на уровне бизнес-логики.

Если стороннее (внутреннее или другое) приложение имеет доступ к вашей схеме DDL, перестаньте беспокоиться о проблеме - вы уже потеряли контроль над своими данными, и вы ввернуты!

Ответ 9

Мое личное предпочтение состоит в том, чтобы обеспечить базовую проверку на уровне базы данных, а затем использовать методы интроспекции, чтобы вытеснить эти ограничения до уровня приложения по умолчанию (соглашение по конфигурации). Если у меня есть какое-то взаимодействие с пользователем в форме или подобном, что необычно, я переопределяю значения по умолчанию, которые я получил из базы данных, с любым новым поведением, которое мне нужно. Это помогает мне сохранить основную валидацию, прежде всего DRY-ly, в слое базы данных, тогда как я делаю более сложную проверку (например, формат номера телефона) на уровне приложения.

Я мог бы проверить ограничения на такие вещи, как номера телефонов, но я считаю, что ограничения проверки являются сложным и неудобным способом применения форматов.

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

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

Ответ 10

С точки зрения ООП, база данных, как в Object/Actor, в рамках более крупной системы, и она должна отвечать за себя. Это включает в себя необходимую необходимость проверки ввода.

Ответ 11

Да для обоих. Я нашел это на своем последнем месте. У нас были устаревшие системы delphi с базами данных sybase. Новая система была .NET и Sql-сервером. Один конкретный сотрудник несет полную ответственность за перевод базы данных sybase в базу данных sql-сервера для клиентов, которым требуется обновление до новой системы .NET. Он никогда не работал с кодом приложения .NET и поэтому никогда не видел ограничений данных на уровне приложений.

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

Ответ 12

Лучше применять эти ограничения на уровне базы данных, поскольку они более эффективны (реализованы на C). Это нормально дублировать проверку на другом уровне, поскольку она обеспечивает более удобные сообщения об ошибках и валидации.

Это не предложение XOR, лучше ошибиться в безопасности, принудительное использование этих ограничений в базе данных сделает вашу систему более d urable.

Ответ 13

Это зависит.

Если вы создаете базу данных, которая должна быть встроена в одно приложение, которое вы также создаете, вы можете выбрать проверку данных в СУБД или приложении или в обоих. Почти все базы данных, создаваемые опытными программистами, которые являются новичками базы данных, соответствуют этой категории. В этом случае некоторые другие ответы отвечают на ваш вопрос.

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

Как минимум, вы должны проектировать свои таблицы так, чтобы у них был как минимум один возможный первичный ключ (возможные первичные ключи называются ключами-кандидатами). Вы должны выбрать первичный ключ из ключей-кандидатов и объявить его как ограничение первичного ключа. Это обеспечивает целостность объекта.

Кроме того, вы должны объявить ограничение "ссылок" для каждого внешнего ключа. Это обеспечивает ссылочную целостность. При наличии достойной СУБД вы должны быть способны обеспечить ссылочную целостность, даже если внешний ключ является необязательным, другими словами, может быть NULL. NULL, конечно, не ссылаются ни на что.

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

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

Что касается правил проверки, которые запрещают пропущенные значения (NULLS), нет никакого вреда в их реализации как в приложении, так и в базе данных. Во многих случаях это правильно. Аналогично проверкам диапазонов.

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

Ответ 14

Несмотря на то, что администраторы баз данных любят обеспечивать валидацию на уровне базы данных, это абсолютно непрактично: вы должны проверять данные в JavaScript и часто на стороне клиента быть Web 2.0 +.

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

Предположим, что все 3 стороны: клиент, API и БД. Внедрите клиент, потому что это необходимо для большого UX и снижения нагрузки на сервер. Сделал БД второй, чтобы все данные были ограничены. Внедрить проверку API (на стороне сервера), чтобы сделать все сообщения различимыми пользователями API (Отказ от ответственности: я не Node сообщество PR-парня, но даже неплохо использовать сервер Node.js, таким образом вы можете повторно использовать ваш код проверки на стороне клиента).

Ответ 15

Я согласен, что ответ на этот вопрос зависит от окружающей среды.

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

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