Насколько важны ограничения, такие как NOT NULL и FOREIGN KEY, если я всегда буду контролировать вход в базу данных с помощью PHP?

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

Аналогично NOT NULL. Если я получаю доступ только к этой базе данных с помощью PHP, не могу ли я просто заставить PHP гарантировать, что нулевое значение не будет введено?

Почему я должен использовать MySQL для обеспечения соблюдения этих ограничений, когда я мог бы просто сделать это с помощью PHP?


Я понимаю, что NOT NULL - очень глупая часть, чтобы пренебрегать вышеупомянутыми причинами. Но MySQL не применяет внешние ключи без серьезной обезьяны.

По-вашему, было бы плохо использовать "поддельные" внешние ключи и просто проверить, соответствуют ли значения, которые нужно ввести, в другие таблицы с PHP?

Ответ 1

Вы собираетесь делать ошибки с PHP, гарантированно 100%. PHP является процедурным. То, что вы хотите, - это декларативные ограничения. Вы хотите рассказать весь стек: "Это ограничения на данные, и эти ограничения не могут быть нарушены". Вы не хотите много обсуждать "Шаг 1... Шаг 2... Шаг 3... Шаг 432...", как ваш способ обеспечения ограничений на данные, поскольку

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

На самом деле должен быть сформулирован вопрос: "Почему я должен использовать PHP для принудительного применения этих ограничений, когда я мог бы просто сделать это с MySQL?"

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

Они очень важны. Вы не хотите полностью определять свою модель через PHP. Что делать, если в вашем PHP-коде есть ошибка? Вы можете легко иметь нулевые столбцы, в которых ваши бизнес-правила утверждают, что вы не должны. Определив его на уровне базы данных, вы, по крайней мере, получите эту проверку бесплатно. Вы действительно будете ненавидеть, когда на вашем PHP есть ошибки, или если какой-либо другой инструмент когда-либо использует вашу базу данных. Вы просто просите проблему, ИМХО.

Будьте внимательны, это очень короткая версия истории.

Ответ 5

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

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

Ответ 6

Я обычно выступаю за объявление ограничений в базе данных. Аргументы для ограничений:

  • Декларативный код проще сделать без ошибок, чем императивный код. Ограничения выполняются, даже если код приложения содержит ошибки.
  • Поддерживает принцип "Не повторяй себя", если у вас есть несколько приложений или модулей кода, обращающихся к одной и той же базе данных, и вам необходимо, чтобы правила бизнеса были соблюдены единообразно. Если вам нужно изменить ограничение, вы можете сделать это в одном месте, даже если у вас много приложений.
  • Обеспечивает целостность данных, даже когда люди пытаются обойти приложение, используя специальные инструменты запроса для работы с базой данных.
  • Обеспечивает согласованность, что означает, что вы всегда можете быть уверены, что данные находятся в допустимом состоянии до и после любого обновления данных. Если вы не используете ограничения, вам может потребоваться выполнить периодические запросы, чтобы проверить наличие неработающих ссылок и очистить их.
  • Вы можете легко моделировать каскадное обновление/удаление с помощью ограничений. То же самое в коде приложения является сложным и неэффективным, не может применяться изменения атомарно (хотя рекомендуется использовать изоляцию транзакций) и подвержен ошибкам.
  • Базы данных с ограничениями более самодокументированы, так же как и имена столбцов и типы данных SQL.

Аргументы против ограничений:

  • Более сложные бизнес-правила не могут быть смоделированы декларативными ограничениями, поэтому вы должны каким-либо образом реализовать их в прикладном пространстве. Учитывая это, почему бы не реализовать все бизнес-правила в одном месте (ваше приложение) и на одном языке? Это упрощает отладку, проверку и отслеживание изменений кода.
  • Ограничения часто включают в себя индексы, которые несут некоторые накладные расходы во время вложений/обновлений. С другой стороны, даже если вы не объявляете ограничение, вам, вероятно, понадобится индекс, потому что столбец может часто использоваться в критериях поиска или условиях соединения.
  • Ограничения могут усложнить ваши попытки "очистить" ошибки в данных.
  • В вашем текущем проекте несовместимость MyISAM и InnoDB в отношении ссылочных ограничений вызывает некоторое горе.

Ответ 7

Самое важное в использовании NOT NULL для меня - это больше часть документации. Когда я вернусь в проект через несколько месяцев, я забуду, в каких столбцах допустимо иметь нули. Если в столбце указано NOT NULL, то я знаю, что мне никогда не придется иметь дело с потенциальными нулевыми значениями из него. И если он разрешает null, то я точно знаю, что мне приходится иметь дело с ними.

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

Ответ 8

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

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

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

Ответ 9

Используйте базу данных для целостности структурных данных и используйте уровень BR для остальных. И уловить ошибки как можно раньше. Они работают вместе.

Если вам повезет, когда ваш код созрел, вы не столкнетесь с ошибками RI Databse; и вы можете с гордостью объявить себя первым.

Ответ 10

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

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

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

Моя рекомендация - выбрать другую СУБД.

Проверка согласованности намного сложнее, чем вы думаете. Например, MySQL использует транзакционную согласованность чтения, что означает, что значения, которые вы проверяете, могут не совпадать с значениями в другой транзакции. Согласованность scemantics для одновременного доступа очень трудно получить правильно, если не привязана непосредственно к уровню данных.

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

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

Он обеспечивает гарантию, которая может очень помочь при написании запросов. Различные объединения могут использовать условия NULL, чтобы показать несоответствие строки таблицы, отдельно от значения NULL, которое невозможно принять, если условие допускает null. (Если допустимы NULL, совпадение может означать либо совпадение строки, либо соответствие строки, но значение столбца равно null.)

Использование NOT NULL также помогает определять правила для более простых запросов, соответствующих значениям. Поскольку вы не можете сказать "WHEN value1 = value2", если значения value1 и value2 равны NULL, результат оценки остается ложным.

Ответ 11

Даже если ваш PHP-код совершенно не содержит ошибок, он может остановиться в середине script (ошибка в памяти, segfault в какой-либо библиотеке и т.д.), оставив в базе данных половину вставленного материала, следовательно, важность использования InnoDB и транзакции.

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

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

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

Ответ 12

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

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

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

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

Ответ 13

Я высоко ценю ваш вопрос, так как я глубоко убежден, что правила по умолчанию должны быть реализованы на стороне кода, а не на стороне базы данных, и это по очень простой причине: когда пользователи инициируют изменения в базе данных (INSERTS, SELECTS и UPDATES), эти изменения должны включать все бизнес-правила, а значения по умолчанию - это в основном бизнес-правила:

  • Нет счета-фактуры без номера счета-фактуры
  • Нет строки счета-фактуры без количества, а 0 или нули неприемлемы
  • Нет входящей почты без даты получения
  • и т.д.

Мы решили несколько лет назад избавиться от всех этих артефактов на стороне базы данных, таких как "not null", "(do not) allow empty strings" и другие трюки по умолчанию, и отлично работает, Аргументы в пользу значения по умолчанию в основном относятся к своего рода принципу "безопасности" ( "делайте это на стороне базы данных, потому что вы забудете это на стороне кода/ваш язык не создан для этого/это проще сделать на стороне базы данных" ), что не имеет никакого смысла, как только вы решили не применять какое-либо значение по умолчанию на стороне базы данных: просто убедитесь, что ваши бизнес-правила правильно реализованы во время отладки.

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

EDIT: перечитав некоторые из ответов здесь, мой последний комментарий был бы: сделайте это на любой стороне, будь то БД или код, но сделайте свой выбор и сделайте это только с одной стороны! Нет ничего более опасного, чем наличие такого контроля с обеих сторон, потому что в конечном итоге (1) вы никогда не узнаете, действительно ли обе стороны реализуют одно и то же правило, что означает, что (2) проверка правил будет означать проверку обеих сторон, что может реально стать беспорядком! Худшая ситуация, конечно, когда одна часть работы выполняется на стороне базы данных (то есть правила, которые были определены при создании базы данных), а другая часть (то есть новые идентифицированные правила) выполняется на стороне клиента... кошмар....

Ответ 14

Я боюсь, что это религиозная тема.

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

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

В качестве побочного элемента настройка MySQL для поддержки ограничений внешнего ключа - это немного процесс, потому что вам нужно перейти на InnoDB, Если вы это сделаете, вы можете получить большую производительность, установив innodb_flush_log_at_tx_commit на 1. Но, вероятно, было бы лучше, если бы вы могли вместо этого перестроить свой сайт для обеспечения транзакции. Затем вы получаете два преимущества InnoDB.

Ответ 15

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

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