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






Вы идущий, чтобы ошибаться с PHP, 100% гарантия. PHP носит процедурный характер. Вам нужны декларативные ограничения. Вы хотите сказать всему стеку: «Это ограничения данных, и эти ограничения не могут быть нарушены». Вы не хотите много использовать "Шаг 1 ... Шаг 2 ... Шаг 3 ... Шаг 432 ..." в качестве вашего метода наложения ограничений на данные, потому что
На самом деле вопрос должен быть сформулирован так: «Почему я должен использовать PHP для обеспечения соблюдения этих ограничений, если я мог просто сделать это с MySQL?»
Как вы интерпретируете исключение, возникшее в значимом сообщении об ошибке (без добавления большего количества кода, чем вы изначально получили)? И вы не верите в валидацию в клиенте?
Дело не в этом, проверяйте все, что хотите, но если вы что-то забыли, вы не рискуете целостностью своих данных, это просто дрянная ошибка для пользователя.
Безопасность реализуется послойно, как и целостность данных. проверку клиента можно обойти, тогда PHP должен это подтвердить. Ограничения целостности базы данных должны уловить остальное
Если вы хотите отлавливать ошибки, выяснять, что не так, и отображать значимую информацию для пользователя, то непременно также реализует проверку и валидацию в PHP. Но если вы реализуете это в Только, вы будут ошибаетесь.
Я в некоторой степени не согласен, у вас должны быть ограничения в ОБЕИХ местах. В коде и в базе данных, но еще одна причина для наложения ограничений в БД заключается в том, что когда-нибудь у вас может быть другое приложение, которое будет работать с той же базой данных, которому вы не можете полностью доверять.
Да, у вас должны быть ограничения в базе данных, а также написать свой код для обеспечения соблюдения этих ограничений на уровне приложения, помимо того, что они применяются сервером базы данных. Но вы получите неправильное применение на уровне кода, потому что это сложно; так что поместите ограничения в свой db.
Они очень важны. Вы не хотите полностью определять свою модель через PHP. Что делать, если в вашем PHP-коде есть ошибка? Вы легко могли бы иметь столбцы с нулевым значением, в которых, согласно вашим бизнес-правилам, этого не должно быть. Определив его на уровне базы данных, вы, по крайней мере, получите эту проверку бесплатно. Вы действительно возненавидите, когда в вашем PHP есть ошибки или какой-либо другой инструмент когда-либо использует вашу базу данных. Вы просто спрашиваете о проблеме, ИМХО.
Имейте в виду, это очень короткая версия истории.
Важно реализовать ограничения в базе данных, потому что невозможно предсказать будущее! Вы просто никогда не знаете, когда ваши требования изменятся.
Также учтите, что над одним приложением может работать несколько разработчиков. Вы можете знать, каковы все ограничения, но младший разработчик не может. При ограничениях в базе данных код младшего разработчика выдаст ошибку, и он будет знать, что что-то нужно исправить. Без ограничений код не может выйти из строя, а данные могут быть повреждены.
Если вы можете поклясться на всю жизнь, что ничто не будет Когда-либо получить доступ к БД, хотя любые другие средства, кроме вашей (конечно без ошибок) PHP-страницы, тогда делать это только с PHP будет нормально.
Поскольку в реальных сценариях всегда присутствует некоторая неопределенность, хорошо, чтобы сервер БД следил за целостностью ваших данных.
Для простых баз данных ограничения ссылочной целостности могут быть не абсолютным требованием, но желательным. Чем сложнее приложение, тем больше пользы вы сможете извлечь из него. Их раннее планирование облегчит вам жизнь в будущем.
Кроме того, ссылочная целостность заставляет вас разрабатывать базу данных в более строгой манере, потому что уже не каждый грязный взлом возможен. Это тоже хорошо.
Вы не можете «просто» сделать это с помощью PHP по той же причине, по которой программисты «просто» не могут писать код без ошибок. Это сложнее, чем вы думаете. Особенно если вы думаете, что это не так уж и сложно.
Что ж ... если вы не можете записать какой-то пуленепробиваемый код вставки \ обновления, вам следует сосредоточиться на игровом программном обеспечении, а не на программах для управления базами данных
Софт для игр, наверное, сложнее. В любом случае я останусь без работы, как только мир обнаружит безошибочный код Филиппа Грондье.
Для меня самое важное в использовании NOT NULL - это часть документации. Когда я возвращаюсь к проекту через несколько месяцев, я забываю, в каких столбцах допустимо иметь нулевые значения. Если в столбце указано NOT NULL, то я знаю, что мне никогда не придется иметь дело с потенциальными нулевыми значениями из него. И если он допускает null, то я точно знаю, что мне нужно с ними иметь дело.
Другое дело, как отмечали другие: вы можете где-то что-то упустить, а очистка данных - отстой или может быть совершенно невозможной. Лучше знать наверняка, что все данные в вашей базе данных согласованы.
Включение этих ограничений в MySQL занимает почти нулевое время. Если они избавят вас даже от единственной ошибки из-за неисправного PHP или другого кода, разве это того не стоит?
Имейте в виду, что ошибки, от которых вы избавитесь, могут быть довольно неприятными. Поиск и исправление самой ошибки может быть несложным; неприятная часть заключается в том, что как только вы исправите ошибку, вы останетесь с кучей ошибочных данных, которые, возможно, даже не удастся исправить.
Я бы даже не стал подходить к этой проблеме с точки зрения «ну, что-то другое, кроме PHP, может когда-нибудь получить доступ к вашим данным». Это правда, но, на мой взгляд, еще более важны головные боли, время (деньги) и потеря данных, которые вы можете спасти, просто добавив несколько простых ограничений.
Я спрашивал людей, как включить внешние ключи в MySQL, и это довольно сложно. Обе таблицы должны быть InnoDB, что, как мне сказали, плохая идея. Кроме того, указанная таблица уже создана и содержит данные. Кто-нибудь может помочь?
Почему это плохая идея? В любом случае, «ALTER TABLE tablename ENGINE = InnoDB» может преобразовать заполненную таблицу из MyISAM в InnoDB. Хотя на это нужно время, в зависимости от количества данных.
Используйте базу данных для структурной целостности данных, а для всего остального используйте уровень BR. И ловите ошибки как можно раньше. Они работают вместе.
Если повезет, когда ваш код станет зрелым, вы не столкнетесь с ошибками RI базы данных; и вы можете с гордостью заявить о себе первым.
Я не думаю, что вы можете быть уверены, что к вашей базе данных будет обращаться только PHP, и если да, то разработчики, которые будут использовать ее для соблюдения этих ограничений на протяжении всего жизненного цикла вашей базы данных.
Если вы включите эти ограничения в свою схему, то можно будет получить хорошее представление о том, как данные используются и связаны между собой, исследуя вашу схему. Если вы поместите все это только в код, то кому-то придется искать как в базе данных, так и в коде PHP.
Но разве это не должно быть в проектной документации, словаре данных и логическом дизайне базы данных?
Да, но эти документы печально известны тем, что устарели и устарели. Я знаю, что ты никогда не допустит этого, но некоторые люди, которые имеют опыт работы с менее дисциплинированными проектами, могут предположить, что это касается вашего проекта, и захотят ознакомиться с фактическим кодом и схемой, а не с документацией.
Я высоко ценю ваш вопрос, так как глубоко убежден, что правила значений по умолчанию должны быть реализованы на стороне кода, а не на стороне базы данных, и это по очень простой причине: когда пользователи являются теми, кто инициирует изменения базы данных ( INSERTS, SELECTS и UPDATES), эти изменения должны включать все бизнес-правила, а значения по умолчанию в основном являются бизнес-правилами:
Несколько лет назад мы решили избавиться от всех этих артефактов на стороне базы данных, таких как «not null», «(do not) allow empty strings» и других уловок «значения по умолчанию», и это отлично работает. Аргументы в пользу значения по умолчанию в основном относятся к некоему принципу «безопасности» («делайте это на стороне базы данных, потому что вы забудете об этом на стороне кода / ваш язык не предназначен для этого / это проще сделать» на стороне базы данных "), что не имеет никакого смысла, если вы решили не реализовывать какое-либо значение по умолчанию на стороне базы данных: просто убедитесь, что ваши бизнес-правила правильно реализованы во время отладки.
За последние 2 года никому в команде и в голову не пришло объявить значение по умолчанию в таблице. Я предполагаю, что наш младший стажер даже не знает о чем-то, что называется "значением по умолчанию".
Обновлено: перечитывая здесь некоторые ответы, мой последний комментарий был бы следующим: делайте это с любой стороны, будь то БД или код, но сделайте свой выбор и сделайте это только с одной стороны! Нет ничего более опасного, чем наличие таких элементов управления с обеих сторон, потому что в конечном итоге (1) вы никогда не узнаете, действительно ли обе стороны реализуют одно и то же правило, а это означает, что (2) проверка правил будет означать проверку обеих сторон, что действительно может стать беспорядком! Наихудшая ситуация, конечно, возникает, когда одна часть работы выполняется на стороне базы данных (т.е. правила, которые были определены при создании базы данных), а другая часть (т.е. вновь идентифицированные правила) выполняется на стороне клиента ... ночной кошмар ....
К сожалению, ваш молодой стажер, к сожалению, будет не информирован о типичных рабочих процедурах, когда перейдет к другому работодателю. Здесь упоминается еще один ответ; «Что, если вы подключите к этой базе данных другое приложение?»; если вы не можете поделиться все необходимыми библиотеками, значит, вы ошиблись.
Обычно я за объявление ограничений в базе данных. Аргументы в пользу ограничений:
Аргументы против ограничений:
Боюсь, это религиозная тема.
С пуристической точки зрения вы хотите, чтобы база данных обеспечивала ссылочную целостность. Это идеально, когда у вас есть множество приложений, обращающихся к базе данных, потому что ограничения находятся в одном месте. К сожалению, реальный мир не идеален.
По моему опыту, если вам нужно обеспечить некоторую ссылочную целостность, ваше приложение должно знать, как это сделать. Это независимо от того, является ли он окончательным арбитром или его также проверяет база данных. И даже если база данных делает выполняет ссылочную целостность, приложение должно знать, что делать, если база данных отклоняет обновление, потому что ссылочная целостность будет нарушена ...
Кстати, настройка MySQL для поддержки ограничений внешнего ключа - это немного сложный процесс, потому что вам нужно перейти на InnoDB. Если вы сделаете это просто, вы можете вернуть большую производительность, установив для innodb_flush_log_at_tx_commit значение 1. Но, вероятно, было бы лучше, если бы вы вместо этого могли перепроектировать свой сайт с учетом транзакций. Тогда вы получите два преимущества InnoDB.
Наличие уровня данных, обеспечивающего согласованность данных с помощью ограничений, помогает гарантировать, что ваши данные остаются согласованными, и обеспечивает дешевую проверку ошибок во время выполнения в вашем приложении.
Если вы считаете, что ограничения не имеют смысла, у вас либо небольшая / некритичная система, либо вы упускаете возможность огромный улучшить качество своей системы. Это нельзя недооценивать.
Возможны следующие варианты: выбор другой СУБД, переосмысление собственной системы метаданных или ручное управление ограничениями. Ручное управление запросами без системы метаданных быстро становится невозможным для надлежащего обслуживания и аудита, поскольку сложность схемы / системы растет и без необходимости усложняет развивающуюся схему.
Я рекомендую выбрать другую СУБД.
Проверка согласованности намного сложнее, чем вы думаете. Например, MySQL использует согласованность транзакционного чтения, что означает, что значения, которые вы проверяете, могут не совпадать со значениями в области другой транзакции. Схемантику согласованности для одновременного доступа очень сложно реализовать, если она не привязана непосредственно к уровню данных.
Когда все сказано и сделано, даже с небольшими усилиями, затраченными на ручную проверку, вероятным результатом будет то, что вы все равно сможете проехать на грузовике через угловые ящики, которые вы не учли или допустили ошибку при формировании.
По вашему вопросу NOT NULL ... Очевидные требования к полям данных являются хорошей отправной точкой. Вот еще пара вещей, которые следует учитывать при определении допустимости значения NULL для столбца.
Это дает гарантию, которая может быть очень полезной при написании запросов. В различных соединениях могут использоваться условия NULL, чтобы показать несоответствие строки таблицы отдельно от значения NULL, которое нельзя принять, если условие допускает пустые значения. (Если допускаются значения NULL, совпадение может означать, что либо строка не соответствует, либо строка соответствует, но значение столбца равно нулю.)
Использование NOT NULL также помогает определить правила для более простых запросов, соответствующих значениям. Поскольку вы не можете сказать «КОГДА значение1 = значение2», если и значение1, и значение2 равны NULL, результат оценки все равно будет ложным.
Даже если в вашем PHP-коде нет ошибок, он может остановить выполнение сценария в середине (ошибка нехватки памяти, segfault в некоторой библиотеке и т. д.), Оставляя наполовину вставленный материал в базе данных, отсюда важность использования InnoDB и транзакций.
То же самое для ограничений, конечно, у вас должна быть правильная проверка формы и ограничения базы данных за ней, чтобы отлавливать ошибки.
Ограничения базы данных легко указать, найти ошибки в приложении сложно, а без ограничений - еще труднее.
Мой опыт показывает, что базы данных с неправильными ограничениями и все, что использует MyISAM, БУДУТ иметь несоответствующие данные после нескольких месяцев использования, и очень трудно найти, откуда они.
+1 Совершенно верно! Кроме того, когда вы в конечном итоге пишете сценарий для устранения повреждений, он может непреднамеренно нанести БОЛЬШЕ ущерба без защиты ограничений.
Реализуйте значения и ограничения по умолчанию на уровне базы данных; правила, которые приведут к приемлемым данным для любого приложения-потребителя. Это изолирует вас от проблем с честностью.
Затем внедрите лучшие значения по умолчанию и ограничения на уровне приложения. Если вам технически запрещено (доступ к API, внешним по отношению к базе данных) реализовывать ограничение или генерировать значение по умолчанию на уровне базы данных, приложение - это то место, где вам нужно это сделать. Это приведет к значению по умолчанию лучше. Однако segfault или общий сбой приложения не приведет к сохранению неприемлемых данных.
Попытки компенсировать это в PHP приводят к безумию. MySQL очень и очень терпимо относится к изменениям DDL с произвольным потоком.