Это хорошая практика, чтобы вообще избегать специального SQL в приложениях ASP.NET? - PullRequest
2 голосов
/ 13 мая 2011

Вместо этого создавать только хранимые процедуры и вызывать их из кода?

Ответы [ 7 ]

4 голосов
/ 13 мая 2011

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

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

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

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

В сценарии, когда приложение или учетная запись пользователя имеют доступ только к SP EXEC SP, тогда у этой учетной записи не будет возможности даже использовать SQL-инъекцию в форме: "; SELECT имя, пароль от ПОЛЬЗОВАТЕЛИ;» или "; УДАЛИТЬ ИЗ ПОЛЬЗОВАТЕЛЕЙ;" или "; DROP TABLE USERS;" потому что в аккаунте нет ничего, кроме EXEC (и, конечно, нет DDL). Вы можете контролировать видимость столбца на уровне SP, и вам не нужно будет, например, отказывать в выборе в столбце зарплаты сотрудника.

Другими словами, если вы не можете свободно предоставлять db_datareader для публики (потому что это действительно то, что вы делаете, когда вы используете LINQ-to-table), тогда вам потребуется некоторая реалистичная защита в вашем приложении, и SP - единственный способ пойти, возможно, с LINQ-to-views.

4 голосов
/ 13 мая 2011

полностью зависит от того, что вы делаете.

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

Однако динамически сгенерированные операторы SQL могут кэшировать свои планы запросов, поэтому разница незначительна.

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

Принимая во внимание, что sprocs - трудная задача для поддержки и обновления, они разделяют DB-логику и код .Net таким образом, что разработчикам становится сложнее собирать воедино методы доступа к данным.

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

Так что я бы не рекомендовал это, поскольку «один размер подходит всем».

2 голосов
/ 13 мая 2011

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

1 голос
/ 13 мая 2011

sql в простом в обслуживании, sql в приложении в области поддержки.

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

0 голосов
/ 15 мая 2011

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

ORM, такие как Entity Framework, nHibernate, LINQ to SQL и т. Д., Будут управлять созданием кода доступа к данным.и слои репозитория и предоставляют вам строго типизированные объекты, представляющие ваши таблицы.Это может привести к созданию более чистой и удобной в обслуживании архитектуры.

Сохраните хранимые процедуры для более сложных запросов.Здесь вы можете воспользоваться расширенными планами SQL и кэшированными запросами.

0 голосов
/ 13 мая 2011

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

Предположим, вы создаете блог и в вашей таблице сообщений есть user_id.И что вы часто делаете такие вещи, как:

select posts.* from posts where user_id = ? order by published desc limit 20;

Предположим, индексы для сообщений (user_id) и сообщений (опубликовано desc).

Дополнительно предположим, что у вас есть два автора, author1, которыенаписал 3 сообщения давным-давно, и author2, который написал 10 тыс. сообщений с тех пор.

В этом случае план запроса специального запроса будет очень разным в зависимости от того, выбираете ли вы сообщения author1 илисообщения author2:

  • Для author1 база данных решит использовать индекс user_id и отсортировать результаты.
  • Для author2 база данных прочитает первые 20 строк, используяиндекс по опубликованным.

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

0 голосов
/ 13 мая 2011
  1. Динамический SQL - Плохой
  2. Хранимые процедуры - лучше
  3. Linq-To-SQL или Linq-to-EF (или инструменты ORM) - Лучшие

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

...