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

204

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

Логика этой идеи заключается в том, что в большинстве случаев ядро ​​базы данных будет делать лучшую работу по поиску наиболее эффективного способа выполнения вашей задачи, чем вы могли бы в коде. Особенно, когда речь идет о том, чтобы сделать результаты обусловленными операциями, выполняемыми с данными. Можно утверждать, что современные движки эффективно JIT'ing + кэшируют скомпилированную версию вашего запроса, это будет иметь смысл на первый взгляд.

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

PhonicUK
источник
60
Это одно из тех высказываний, которое нужно принимать вдумчиво. Он извлекается всякий раз, когда кто-то находит другого инженера, который делает «выбор * из таблицы», а затем прочесывает результирующий набор вместо того, чтобы использовать предложение where и указывать столбцы. Но если вы зайдете слишком далеко, вы получите другой беспорядок.
Майкл Кохн
154
Начало фразы с «никогда» или «всегда» - это почти всегда рецепт плохого дизайна.
вс
34
Хотя, безусловно, можно попытаться сделать слишком много в SQL, я могу честно сказать, что за 30 лет разработки и консалтинга я никогда не видел реальных серьезных случаев (несколько незначительных). С другой стороны, я видел буквально сотни серьезных случаев, когда разработчики пытались сделать многое в «коде», которое они должны были делать в SQL. И я все еще вижу их. Часто ...
RBarryYoung
2
@MrEdmundo Возьми это к мета.
ta.speot.is
4
Этот вопрос два в одном - я думаю, что он должен быть разделен. 1) Сколько нужно сделать в SQL? 2) Сколько нужно сделать в СУБД? Хранимые процедуры попадают в середину. Я видел целые приложения, закодированные в хранимых процедурах.
reinierpost

Ответы:

321

По словам непрофессионала:

Это то, что SQL делает, и, верьте этому или нет, я видел, что сделано в коде:

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

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

user61852
источник
88
+10000000000 за указание на то, что он опасно предполагает, что все будет происходить только через приложение.
HLGEM
11
@skynorth Это приводит к плохому дизайну базы данных. Вниз по линии , которую вы в конечном итоге с базой данных , которая может быть доступна только по значению с помощью этого приложения из - за всех пост-обработки она делает.
Sirex
21
@skynorth Если вы полагаетесь на код, чтобы убедиться, что ваши ключи сохраняют целостность, то вы удаляете фундаментальный принцип СУБД из БД. Это не имеет смысла, потому что тогда каждое приложение, которое обращается к БД, должно будет точно копировать эту функциональность. Почему бы просто не позволить БД справиться с этим, поскольку это то, для чего он предназначен. Например, БД может предотвратить дублирование ключей.
Баттл Буткус
10
не забывайте транзакции!
Sklivvz
24
@skynorth: tl; dr: правила, обеспечивающие согласованность ваших данных, должны быть реализованы в базе данных. т. е. для 99% когда-либо написанных приложений данные (и, следовательно, база данных) будут жить невообразимо после того, как ваше приложение исчезнет и исчезнет. Я видел это много, много раз за эти годы (эй, нам нужно развернуть версию на Windows / iPhone / Android / что угодно, потому что {вставить старую платформу здесь} умирает, мы ' будет хост или базы данных Oracle здесь и создать новый пользовательский интерфейс там ). Нет никаких причин, чтобы эта тенденция прекратилась сегодня или в ближайшее время.
Двоичный беспорядок
122

Я бы перефразировал это так: «Никогда не делайте в коде то, что SQL Server может сделать для вас хорошо ».

Такие вещи, как манипуляции со строками, работа с регулярными выражениями и тому подобное, я бы не делал в SQL Server (за исключением SQL CLR).

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

Одед
источник
27
Если бы все SQL работало лучше, чем код приложения, было бы помещено на уровень SQL, то в базе данных было бы много бизнес-логики, в лучшую или худшую сторону. Я видел это и да, производительность была звездной. Но, к счастью, все разработчики очень хорошо знали разработку приложений и SQL, потому что граница между ними стала очень аморфной. Я бы не стал рекомендовать это как отправную точку, а скорее как конечную точку после того, как система станет чрезвычайно популярной, а производительность снизится со временем.
Джимми Хоффа
3
Лошади на курсы иннит гув?
StuperUser
28
@NathanLong Я не знаю, почему так много людей все еще думают, что вы не можете сохранить свой SQL в системе контроля версий. Сначала у нас были все наши хранимые процедуры / скрипты таблиц / и т. Д., Необходимые для создания базы данных с нуля при управлении исходным кодом, затем позже использовались проекты базы данных visual studio. Работало без проектов и лучше с ними. SQL, как и любая другая изменяемая вещь, необходимая для создания вашей системы, должна находиться под контролем версий! Развертывание может быть выполнено с помощью инструментов redgate diff для большинства СУБД, если вы сохраняете свои скрипты создания под контролем версий, не поддерживаете скрипты diff, использующие инструменты
Джимми Хоффа,
3
Если ваш SQL имеет поддержку операций REGEX и манипуляции со строками, выполнение их в SQL может быть хорошим выбором.
Кевин Клайн
3
@NathanLong: думайте об этом так: таблица БД определяется фрагментом кода, записанным в текстовом файле, синтаксис которого соответствует строкам «создать таблицу ...». Теперь вы можете хранить этот текстовый файл в любом SCM, который вам нравится, точно так же, как если у вас есть код создания таблицы БД на вашем любимом языке приложения, который вызывает любой необходимый API, и вы сохраните этот текстовый файл в своем SCM. Я думаю, проблема в том, что некоторые люди думают, что БД - это магические звери, и они знают только, как писать VB-код (или что-то еще), и поэтому они думают только на языке приложения, который они знают.
gbjbaanb
47

Никогда не делайте в коде то, что вы можете сделать, чтобы SQL-сервер работал хорошо для вас (акцент мой)

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

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

Рассмотрим эти примеры:

  • Вы храните дату рождения, и вам необходимо рассчитать возраст для группы пользователей. Вы можете сделать так, чтобы SQL-сервер делал вычитание, или вы можете сделать это в своем коде. Количество циклов остается неизменным, а количество отправляемых вам данных увеличивается. Таким образом, решение на основе кода выигрывает
  • Вы сохраняете дату рождения, и вам нужно найти пользователей в возрасте от 20 до 30 лет. Вы можете загрузить всех пользователей обратно на клиент, выполнить вычитание, чтобы найти возраст, а затем выполнить фильтрацию, но отправив логику на SQL Server. уменьшит объем данных, не требуя дополнительных циклов; Таким образом, решение на основе SQL выигрывает.
оборота
источник
1
Когда я где-то работал, бизнес-логика стала аморфной с SQL, у нас не было проблем с многократными обходами; мы просто использовали несколько результирующих наборов в одном цикле, так что это правило вроде бы нарушается, хотя дух правила довольно хорош в стремлении к золотому сечению
Джимми Хоффа
2
+1 это фантастический ответ, потому что он дает конкретные примеры для поддержки обоих направлений.
Брэндон
1
На вашем втором примере. что вы скажете, если сценарий такой, как показано ниже - пользователи и bday являются кэшами и говорят, что размер записи находится в диапазоне 1000-2000. Разве это не быстрее сделать это в памяти, нет необходимости в вызове базы данных, так как данные кэшируются и, таким образом, избегается промежуточная операция sql. Обработка будет перебирать список из 1000+ пользователей в памяти и определять, где происходит совпадение. Не будет ли это быстрее, чем делать это в БД
user4677228
1
@ user4677228 Но попробуйте увеличить :-p. Если ваш код должен сканировать все данные для расчета всех возрастов, а желаемый результат - просто «сколько пользователей не менее 20 лет и моложе 30 лет?», Кэши вам совсем не помогут. Вы все равно закончите потоковую передачу всей таблицы вашему клиенту, но сервер базы данных может сделать все это в своей памяти / кэшах и дать вам быстрый ответ независимо от того, подключается ли клиент БД через локальные сокеты или удаленно через сеть, если Вы просто хотите рассчитать возраст в WHEREпункте.
Бинки
21

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

Посмотрите на пример набора базовых операций . Как вы, возможно, знаете, RDBMS созданы для обработки общих операций хранения и манипулирования данными.

Кроме того, проект выбора базы данных играет важную роль . Наличие СУБД (MS SQL, Oracle и т. Д.) Отличается от баз данных NoSQL, таких как RavenDB.

ЭльЮсубов
источник
Никогда не помещайте операции set в вашу кодовую базу, это будет означать, что абсолютно все, что делается в LINQ для коллекций (select, sum, where, single), должно выполняться в SQL, а не в вашем приложении, это поместит в вашу базу данных МНОГО бизнес-логики.
Джимми Хоффа
4
Вещи, которые вы описываете, не являются клиентским кодом. Это бизнес-уровень, где у вас может быть своя собственная логика манипуляции. Однако выполнение этой логики на записях 1M + нанесет вам ответный удар.
Е.Л. Юсубов
@JimmyHoffa: Это неправда, иногда вы генерируете временную информацию, которая должна обрабатываться с данными, уже имеющимися в памяти приложения. Линк творит чудеса над этим.
Фабрицио Араужо
@FabricioAraujo Я знаю, почему linq великолепен, но этот ответ гласит: « Никогда не выполняйте операции на основе множеств в коде приложения, если вы никогда не выполняли операции над множествами в коде приложения, вы бы никогда не использовали linq, потому что в этом вся цель linq». Я подчеркиваю, что никогда не выполнять операции над множествами в коде приложения - плохое правило, которому нужно следовать
Джимми Хоффа,
@JimmyHoffa: Нет, правило гласит: «никогда не делайте в приложении то, что СУРБД может сделать для вас хорошо». И я говорю о переходной информации - не информация сохраняется в базе данных. Я работал в системах, где для полного выполнения бизнес-правил мне нужно было выполнять обработку кода. Я помню бизнес-правило, которое я выполнял, после тяжелой обработки в БД, дополнительную обработку этих данных для создания (очень важного) отчета. Я мог бы использовать linq для этого (это было сделано на ныне несуществующей Delphi.Net). Другими словами, linq можно использовать даже в соответствии с этим правилом.
Фабрицио Араужо
13

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

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

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

tylerl
источник
1
Деньги могут решить проблемы с масштабируемостью оборудования, в то время как никакие деньги не могут решить сложность программного обеспечения.
Тулаинс Кордова
3
@ user1598390 Действительно: аппаратное обеспечение дешевое , программисты дорогие . Деньги могут решить сложность программного обеспечения. Деньги потрачены на программистов. Но обратите внимание, что мы говорим не о чистом коде, а о спегетти. Мы говорим о выполнении работы на стороне приложения по сравнению с базой данных. Сложность программного обеспечения только незначительно связана, так как оба варианта могут следовать хорошим принципам проектирования. Лучший вопрос: « какой дизайн стоит дороже? ».
Tylerl
Как только у вас есть огромная и полная жирная база кода, большая часть которой делает некоммерческие вещи, единственное, что вы можете сделать, это мать всех реинжинирингов, которые стоят дороже, чем оборудование, и включают слишком много неопределенности, кроме вы всегда будете знать, где найти хорошее оборудование, но хорошие программисты - это отдельная история ... в то время как ваши конкуренты используют свое время для улучшения, адаптации к изменениям и радости клиентов.
Тулаинс Кордова
1
+1 за то, что вы единственный, кто упомянул масштабирование в вашем ответе.
Мэтт
Аппаратное обеспечение было дешевым, уже не так - в центре обработки данных расходы на электроэнергию и оборудование составляют 88% от эксплуатационных расходов (на которые ссылается Microsoft), поэтому тратить больше средств на программистов для написания эффективного кода очень выгодно, и так будет до тех пор, пока мы не получим неограниченную и дешевый термоядерный синтез.
gbjbaanb
12

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

Итак, что нужно сделать в базе данных:

  • Аудит (аудит только для приложений не отслеживает все изменения в базе данных и, следовательно, бесполезен).

  • Ограничения ограничения количества данных, включая значения по умолчанию, ограничения внешнего ключа и правила, которые всегда должны применяться ко всем данным. Все данные не всегда изменяются или вставляются через приложение, есть одноразовые исправления данных, особенно больших наборов данных, которые нецелесообразны делать по одной записи за раз (обновите эти 100 000 записей, которые были помечены как статус 1, когда они должны 2 из-за ошибки в коде приложения или обновите все записи от клиента A до клиента B, потому что компания B купила компанию A), а также импорт данных и другие приложения, которые могут касаться той же базы данных.

  • СОЕДИНЕНИЕ и фильтрация предложений where (для уменьшения количества записей, отправляемых по сети)

HLGEM
источник
6

«Преждевременная оптимизация - корень всего зла (в большинстве случаев, во всяком случае) в компьютерном программировании», - Дональд Кнут

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

В то время как настроения в строке заголовка замечательны, а с точностью до точки (мельчайших фильтрации, проектирования, группировка и т.д. , должны в подавляющем большинстве случаев быть оставлено в БД), определение «хорошо» может быть в заказ. Задач, которые SQL Server может выполнять с высоким уровнем производительности, много, но задач, которые вы можете продемонстрироватьчто SQL Server делает правильно изолированным, повторяемым образом, очень мало. SQL Management Studio - это отличная среда IDE для баз данных (особенно с учетом других опций, с которыми я работал, например, TOAD), но у нее есть свои ограничения, во-первых, в том числе то, что вы используете ее для выполнения (или любой процедурный код, который вы выполняете в БД внизу) по определению является «побочным эффектом» (изменением состояния, лежащим за пределами области памяти вашего процесса). Кроме того, процедурный код в SQL Server только сейчас, благодаря новейшим средам разработки и инструментам, может быть измерен так, как управляемый код может использовать метрики покрытия и анализ пути (так что вы можете продемонстрировать, что этот конкретный оператор if встречается в тестах X) , Y и Z, и тест X предназначен для выполнения условия и выполнения этой половины, в то время как Y и Z выполняют «остальное» , Это, в свою очередь, предполагает, что у вас есть тест, который может установить базу данных с определенным начальным состоянием, выполнить процедурный код базы данных посредством какого-либо действия и подтвердить ожидаемые результаты.

Все это гораздо сложнее и сложнее, чем решение, предоставляемое большинством уровней доступа к данным; Предположим, что слой данных (и, в этом отношении, DAL) знает, как выполнять свою работу, когда задан правильный ввод, а затем проверьте, что ваш код обеспечивает правильный ввод. Сохраняя процедурный код, такой как SP и триггеры, за пределами БД и вместо этого выполняя такие действия в коде приложения, указанный код приложения намного проще в применении.

Keiths
источник
Подожди, подожди, что? Как вы перешли от проверки корректности к тестам, которые могут доказать, что ошибки существуют, но никогда не смогут доказать, что код верен?
Мейсон Уилер
2
хранимая процедура не является процедурным кодом. SP - это предварительно вычисленный SQL-запрос, который хранится и выполняется внутри БД. Это не код приложения.
gbjbaanb
1
Если SP ограничен запросом SQL, то вы правы. Если это T-SQL или PL / SQL, включая условные разрывы, циклы, курсоры и / или другую логику, отличную от запроса, вы ошибаетесь. И Множество SP, функций и триггеров в DB по всему киберпространству имеют эти дополнительные элементы.
KeithS
5

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

Например, если вам нужно получить некоторые данные, а затем вычислить что-то из данных и затем сохранить эти данные в базе данных. Есть два варианта:

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

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

Конечно, ты сбреешь 2 секунды. Тем не менее, вы предпочитали тратить 100% (по крайней мере) одного ядра процессора на сервере базы данных в течение 10 секунд, или вы тратили это время на свой веб-сервер?

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

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

Earlz
источник
1
Вы также забываете о сетевых поездках - вы не можете масштабировать горизонтально, добавляя серверы без некоторого снижения эффективности. Таким образом, снижение нагрузки на данные путем добавления предложения where очевидно - но другие операции sql не обязательно снижают производительность. Хотя, в общем, ваша точка зрения верна, но не настолько, чтобы вы относились к БД как к тупому хранилищу данных. Самое масштабируемое приложение, над которым я когда-либо работал, использует хранимые процедуры для каждого вызова данных (кроме двух сложных запросов). Лучшим является третье решение - «хранимый процесс для захвата только необходимых данных», не уверен, что вы имели в виду «вычислять» или нет.
gbjbaanb
4

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

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

Только мои 0,02 доллара.

Stanley Glass Jr
источник
Зачем вам выполнять регулярное выражение или проверку данных, которые уже находятся в базе данных? Ограничения должны предотвращать попадание плохих данных, и использование регулярных выражений, вероятно, означает, что вам нужно больше полезных столбцов ..
Брендан Лонг,
Я не говорил, что буду использовать регулярные выражения или проверку данных, поступающих из базы данных. Думаю, мне следовало уточнить, что это за данные, поступающие в базу данных. Я хотел сказать, что данные должны быть очищены и проверены до того, как они попадут в DAL.
Стэнли Гласс-младший
3

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

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

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

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

Считаете ли вы "слой" физическим разделением по серверам или логическим разделением? Выполнение логики на любом сервере теоретически все еще может подпадать под его логический уровень. Вы можете организовать разделение путем компиляции в разные библиотеки DLL, а не только для разделения серверов. Это может значительно увеличить время отклика (но жертвуя через производительность) при сохранении разделения проблем. Разделенная DLL может быть позже перемещена на другие серверы без новой сборки для увеличения пропускной способности (за счет времени отклика).

оборота mike30
источник
почему отрицание?
mike30
5
Я не отрицал, но любой специалист по базам данных скажет вам, что, рассматривая базу данных, логический свободный хэш - очень плохая идея. Это вызывает проблемы целостности данных или проблемы с производительностью или и то, и другое.
HLGEM
1
@HLGEM. Ответ описывает причины для сохранения логики в базе данных или сидя на сервере БД. Все еще не объясняет это.
mike30
Возможно, они не добрались до контрапунктов, как я, поэтому я не понизил голос.
HLGEM
3

Идиома больше связана с соблюдением бизнес-правил, с данными, а также с отношениями (данными, структурой и отношениями). Это не универсальное решение для каждой проблемы, но оно помогает избежать таких вещей, как вручную поддерживаемые счетчики записей, сохраняемая вручную целостность отношений и т. д., если эти вещи доступны на уровне базы данных. Поэтому, если кто-то придет и расширит программы или напишет другую программу, которая взаимодействует с базой данных, ему не придется выяснять, как поддерживать целостность базы данных из предыдущего кода. Случай счетчика записей, поддерживаемого вручную, особенно уместен, когда кто-то другой хочет создать новую программу для взаимодействия с той же базой данных. Даже если недавно созданная программа имеет точно правильный код для счетчика, исходная программа и новая, работающая примерно в одно и то же время, могут ее испортить. Существует даже код, который извлекает записи и проверяет условия перед записью новой или обновленной записи (в коде или в виде отдельных запросов), когда, по возможности, этого часто можно достичь прямо в операторе вставки или обновления. Повреждение данных может снова привести. Механизм базы данных гарантирует атомарность; запрос на обновление или вставку с условиями гарантированно повлияет только на записи, соответствующие условиям, и ни один внешний запрос не может изменить данные в середине нашего обновления. Есть много других обстоятельств, когда код используется, когда ядро ​​базы данных будет работать лучше. Все дело в целостности данных, а не в производительности. Даже код, который извлекает записи и проверяет условия перед записью новой или обновленной записи (в коде или в виде отдельных запросов), когда это возможно, когда это возможно, часто это можно сделать прямо в операторе вставки или обновления. Повреждение данных может снова привести. Механизм базы данных гарантирует атомарность; запрос на обновление или вставку с условиями гарантированно повлияет только на записи, соответствующие условиям, и ни один внешний запрос не может изменить данные в середине нашего обновления. Есть много других обстоятельств, когда код используется, когда ядро ​​базы данных будет работать лучше. Все дело в целостности данных, а не в производительности. Даже код, который извлекает записи и проверяет условия перед записью новой или обновленной записи (в коде или в виде отдельных запросов), когда это возможно, когда это возможно, часто это можно сделать прямо в операторе вставки или обновления. Повреждение данных может снова привести. Механизм базы данных гарантирует атомарность; запрос на обновление или вставку с условиями гарантированно повлияет только на записи, соответствующие условиям, и ни один внешний запрос не может изменить данные в середине нашего обновления. Есть много других обстоятельств, когда код используется, когда ядро ​​базы данных будет работать лучше. Все дело в целостности данных, а не в производительности. Механизм базы данных гарантирует атомарность; запрос на обновление или вставку с условиями гарантированно повлияет только на записи, соответствующие условиям, и ни один внешний запрос не может изменить данные в середине нашего обновления. Есть много других обстоятельств, когда код используется, когда ядро ​​базы данных будет работать лучше. Все дело в целостности данных, а не в производительности. Механизм базы данных гарантирует атомарность; запрос на обновление или вставку с условиями гарантированно повлияет только на записи, соответствующие условиям, и ни один внешний запрос не может изменить данные в середине нашего обновления. Есть много других обстоятельств, когда код используется, когда ядро ​​базы данных будет работать лучше. Все дело в целостности данных, а не в производительности.

Так что это на самом деле хороший дизайн или эмпирическое правило. Никакая производительность не поможет системе с поврежденными данными.

Крис
источник
0

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

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

Laurent Goderre
источник
0

Есть несколько вещей, которые нужно запомнить:

  • Реляционная база данных должна обеспечивать ссылочную целостность через внешние ключи
  • Масштабирование одной базы данных может быть сложным и дорогостоящим. Масштабировать веб-сервер намного проще, просто добавив больше веб-серверов. Получайте удовольствие, пытаясь добавить больше мощности SQL-сервера.
  • С C # и LINQ вы можете выполнять свои «объединения» и многое другое с помощью кода, так что во многих случаях вы как бы получаете лучшее из обоих миров
Джо Филлипс
источник
0

«Преждевременная оптимизация - корень всего зла», - Дональд Кнут

Используйте инструмент, наиболее подходящий для работы. Для обеспечения целостности данных это часто база данных. Для расширенных бизнес-правил это система, основанная на правилах, такая как JBoss Drools. Для визуализации данных это будет структура отчетности. и т.п.

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

parasietje
источник