Як запропонувати використовувати ORM замість збережених процедур?


31

Я працюю в компанії, яка використовує лише збережені процедури для доступу до всіх даних, що робить дуже прикрою тримати синхронізацію наших локальних баз даних, як кожне зобов’язання, яке нам доведеться запускати нові програми. У минулому я використовував деякі основні ORM, і я вважаю цей досвід набагато кращим і чистішим. Я хотів би запропонувати менеджеру з розробки та решті команди, щоб ми розглядали можливість використання ORM якоїсь форми для подальшого розвитку (решта команди лише знайомі зі збереженими процедурами і ніколи більше нічого не використовували). Поточна архітектура .NET 3.5, написана як .NET 1.1, з "класами богів", які використовують дивну реалізацію ActiveRecord і повертають нетипізовані набори даних, які перекинуті на файли, що стоять за кодом - класи працюють приблизно так:

class Foo { 
    public bool LoadFoo() { 
        bool blnResult = false;
        if (this.FooID == 0) { 
            throw new Exception("FooID must be set before calling this method.");
        }

        DataSet ds = // ... call to Sproc
        if (ds.Tables[0].Rows.Count > 0) { 
            foo.FooName = ds.Tables[0].Rows[0]["FooName"].ToString();
            // other properties set
            blnResult = true;
        }
        return blnResult;
    }
}

// Consumer
Foo foo = new Foo();
foo.FooID = 1234;
foo.LoadFoo();
// do stuff with foo...

В основному не застосовується жодна модель дизайну. Тестів взагалі немає (ніхто інший не знає, як писати одиничні тести, а тестування проводиться через завантаження веб-сайту вручну та перебирання). Переглядаючи нашу базу даних, ми маємо: 199 таблиць, 13 переглядів, колосальних 926 збережених процедур та 93 функції. Близько 30 таблиць використовується для пакетних завдань або зовнішніх речей, решта використовуються в нашому базовому додатку.

Чи варто навіть в цьому сценарії дотримуватися іншого підходу? Я говорю про рух вперед лише тому, що нам заборонено переробляти існуючий код, оскільки "він працює", тому ми не можемо змінити існуючі класи для використання ORM, але я не знаю, як часто ми додаємо нові модулі замість цього додавання до / виправлення поточних модулів, тому я не впевнений, чи ORM - це правильний підхід (занадто багато вкладено у збережені процедури та набори даних). Якщо це правильний вибір, як я можу подати випадок використання цього? Єдина користь, яку я можу подумати, - це чистіший код (хоча це може і не бути, оскільки нинішня архітектура не є ' t побудований з урахуванням ORM, так що ми в основному будемо встановлювати присвоєння ORM для майбутніх модулів, але старі все ще будуть використовувати DataSets) і менше клопоту, щоб запам'ятати, які сценарії процедур були запущені та які потрібно запускати, і т. д., але це все, і я не знаю, наскільки переконливим буде аргумент. Інтенсивність ремонту - це ще одна проблема, однак, мабуть, не хвилює ніхто, крім мене.


8
Здається, у вас більше проблем, ніж просто переконати команду використовувати ORM. Мені здається, що ваша команда не знає про деякі хороші практики розробки (наприклад, структури дизайну, тестування блоків). Це важливіші питання, з якими потрібно вирішити.
Бернард

6
За іронією долі, я думаю, що за 5 років розвитку я лише зустрів, можливо, небагатьох людей / команд, які були в курсі таких речей, як модель дизайну та тестування одиниць; зазвичай я єдиний хлопець у компанії, який знає про ці речі.
Уейн Моліна

3
@Wayne M: Я вважаю, що це трохи заважає, але я також не здивований цим.
Бернар

2
Я вважаю це дуже ... відчайдушним. Дивно, коли ви щось пропонуєте і отримуєте "олень у фарах", який свідчить про те, що інша людина не має найяснішого уявлення про те, про що ви говорите, або чому хто-небудь коли-небудь зважиться на це. У мене це траплялося досить багато разів у минулому.
Уейн Моліна

2
Я великий шанувальник "Збереженої процедури", тому мій коментар є необ'єктивним, але я повністю не згоден з усією умовою. Вам подобається ORM, і ви хочете використовувати це добре. Однак у решти команди непогано зберігати документи. Навіщо примушувати їх до того, що вам подобається?
Темна ніч

Відповіді:


47

Збережені процедури погані, вони часто повільні та приблизно такі ж ефективні, як звичайний код клієнта.

[Прискорення, як правило, обумовлено способом, розробленим клієнтським і збереженим інтерфейсом процедур, і тим, як транзакції записуються як короткі, зосереджені сплески SQL.]

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

[Це питання вважатиметься приблизно -30, оскільки багато, багато людей вважають, що зберігаються процедури мають магічну силу і повинні використовуватися, незважаючи на проблеми, які вони викликають.]

Переміщення всіх збережених процедурних кодів до клієнта полегшить ситуацію для всіх.

Вам доведеться час від часу оновлювати схему та модель ORM. Однак зміни схем ізольовані від змін ORM, що дозволяє певну незалежність між програмами та схемами баз даних.

Ви зможете перевірити, виправити, підтримувати, зрозуміти та адаптувати всі ці збережені процедури під час їх перезапису. Ваш додаток працюватиме приблизно так само і стане набагато менш тендітним, оскільки ви більше не впадаєте у дві різні технології.

ORM не є магією, і хороші навички проектування баз даних абсолютно необхідні для роботи.

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

ORM не магічно змушує ретельно розробляти транзакції. Дизайн транзакцій все-таки потрібно робити так само ретельно, як це було під час написання збережених процедур.


19
+1, тому що збережені процедури - це загальний біль для роботи
Гері Роу,

3
: '(У мене немає проблем із збереженими процедурами. Це просто черговий шар абстракції.
Майк Веллер

3
Якщо ми створимо SP, тоді двигун бази даних зберігає його як скомпільовану форму, і він створює шлях виконання так, щоб він виконувався максимально швидко. Але ORM щоразу надсилає SQL, який потрібно скомпілювати та запустити за допомогою двигуна бази даних. Я думаю, буде повільніше використовувати ORM замість збереженої процедури.
DeveloperArnab

4
Смішно. Ми повернулися з ORM до збережених процедур саме через .. SPEED. Не кількість часу, який нам потрібен для програмування, а час, необхідний ORM для таких речей, як матеріалізація об'єктів, пошук об’єкта, оновлення для різних клієнтів. СП де, пекло, набагато швидше. Один приклад: для читання 30 000 об’єктів з БД з новим сучасним ORM потрібно ... о добре. тайм-аут через 2 хвилини. Виклик збереженої процедури та отримання результату - 2 секунди. Так - існує багато хитрощів, таких як підказка, щоб зменшити кількість балів у базі даних, але велика різниця, якщо вони просто використовуються для використання ORM або
Offler

2
@DeveloperArnab: Це, можливо, було правдою 20 років тому, але сучасні двигуни БД досить складні і можуть розпізнавати раніше виконані запити та повторно використовувати плани виконання, різниця в швидкості в наш час настільки незначна, що навряд чи гарантує додаткових клопотів SP.
whatsisname

20

Збережені процедури хороші, вони швидкі та дуже ефективні і є ідеальним місцем для розміщення коду, пов’язаного з даними. Переміщення всього цього коду до клієнта полегшить вам щось як розробник клієнта (трохи, оскільки вам все одно доведеться оновити схему та модель ORM, коли виконувати їх зміни), але ви втратите весь наявний код та зробите ваш додаток повільніше і, ймовірно, більш крихкий, враховуючи втрату всіх цих навичок sql.

Мені цікаво, чи сидять DBA там, говорячи: «О, кожне зобов’язання, я повинен знов запускати клієнта, замість цього нам слід перемістити весь код у форми БД».

У вашому випадку ви повинні мати можливість замінити існуючий користувальницький ORM (тобто ваші смішні класи) на чужі без втрат, за винятком змін способу написання вашого кодового коду. Ви також можете зберегти SP, оскільки більшість (усіх?) ORM із задоволенням називатиме їх. Тому я рекомендую замінити ці "Foo" класи на ORM і піти звідти. Я б не рекомендував замінювати свої ІП.

PS. Здається, у вас є багато загального коду в класах, що стоять за кодом, що робить їх самим схемою дизайну. як ви думаєте, на першому місці модель дизайну! (гаразд, це може бути не найкращим або навіть хорошим, але це все-таки DP)

Редагувати: і тепер із Dapper жодних причин уникати проростків над важкою вагою ORM вже немає.


3
+1, очевидний перший крок - перейти до ORM та використовувати його для відображення результатів існуючих збережених процедур до об'єктів. Позбавтеся від усього цього ds.Tables[0].Rows[0]["FooName"].ToString()лайна. Менеджер любить збережені процедури? Він отримує їх утримувати. Але фізично неможливо стверджувати, що переміщення всього цього повторюваного кодового коду в щось, породжене, скажімо, LINQ в SQL, було поганою справою.
Carson63000

11
Ну я не можу повірити, наскільки "неправильно" є у твоєму дописі. Ваше порівняння з BBA плачем щодо необхідності витягувати код є недоцільним і абсолютно безглуздим. Перш за все, база даних - це СЕРВІС, призначений для зберігання та отримання даних, кінець історії. LOGIC, як випливає з назви, переходить у шар бізнес-логіки, який є частиною коду API. Додаток більш крихкий відходить від паростків? Ви серйозно чи просто тролінг? TDD додаток з логікою в проростках і скажи мені, як це весело. Також ORM не призначені для перемикання. Бази даних є, оскільки вони просто СЕРВІС.
Маттео Моска

5
Я не можу зрозуміти, чому деякі люди думають, що база даних - це якась свята земля, де все святе. Подумайте над цим. Коли стороння компанія виставляє вам послугу, вони надають вам прямий доступ до їх db, або вони маскують її за API? Для використання популярного прикладу візьміть будь-яку службу Google. Ви, розробник, підключитесь до їх загальнодоступного API, навіть не знаєте, яка база даних знаходиться під ним, чи є база даних взагалі. Ось так ви розробляєте міцне і роз'єднане програмне забезпечення. Бази даних не мають доступу до програми безпосередньо. Для цього є середні яруси.
Маттео Моска

5
@Matteo Mosca: звичайно, але як доступ до середнього програмного забезпечення до БД ... це клієнт до БД. "клієнт" не означає "GUI" або "настільний додаток". У ярусах додатків є багато сірих областей - ви ставите перевірку в графічному інтерфейсі або в логіці сервера / бізнесу? Це має бути чітким дизайном на сервері, але це буде дуже погано для продуктивності та чуйності користувачів. Аналогічно, ви часто вкладаєте певну логіку в БД, коли це покращує продуктивність і (у цьому випадку) правильність даних.
gbjbaanb

4
Вибачте, але я все ще не згоден. Після того, як вам доведеться розгорнути свою програму в іншому середовищі, де у вас немає тієї самої технології DB, яку ви використовували, ви опинитесь у ситуації, коли ваш додаток не може працювати, оскільки у вас немає всіх цих проростків у новій базі даних .. і навіть якщо ви відтворите їх (це загальний біль), вони можуть бути різними через різниці діалектів SQL і т. д. Централізований API з логікою та валідацією, викритий через стандарт (як SOAP або REST), це вирішує. Проблема та додає перевіреності, версій та послідовності.
Маттео Моска

13

Ви, схоже, намагаєтесь перевести свою команду з однієї крайності (збережені процедури та набори даних) в іншу (повномасштабна ORM). Я думаю, що є інші, більш поступові зміни, які ви можете встановити щодо впровадження для поліпшення якості коду вашого рівня доступу до даних, які ваша команда може бути готові прийняти.

Напівфабрикат коду реалізації активного запису, який ви опублікували, не особливо елегантний - я рекомендую дослідити шаблон сховища, який легко зрозуміти та реалізувати та користується великою популярністю у розробників .NET. Ця модель часто асоціюється з ORM, але створити сховища за допомогою простого ADO.NET так само просто.

Що стосується DataSet - yuck! З бібліотеками класів вам буде набагато простіше працювати, якщо ви повернете статично (або навіть динамічні) об'єкти, набрані тексту. Я вважаю, що ця ілюстрація пояснює мою думку щодо DataSet краще, ніж я міг.

Крім того, ви можете викопати збережені програми, не переходячи до ORM - нічого поганого у використанні параметризованого SQL. Насправді я б напевно віддав перевагу використанню збережених процесорів, якщо у вас немає складних процедур, які дозволять заощадити на багаторазових поїздках до сервера. Я занадто ненавиджу це, коли відкриваю застарілу базу даних і бачу нескінченний список процедур CRUD.

Я не перешкоджаю використанню ORM - я, як правило, використовую їх у більшості проектів, над якими працюю. Однак я можу зрозуміти, чому може виникнути велика кількість тертя, намагаючись запровадити в цей проект і вашу команду, що, якщо говорити про це, звучить так, ніби вони перестали вчитися новому приблизно 8 років тому. Сказавши, що я б точно визначив нову породу "Micro ORM", таких як Dapper (використовується не тільки для цього сайту) та Massive , обидва з яких неймовірно прості у використанні та тримають вас ближче до SQL, ніж типовий ORM, і що ваша команда може бути більш охоче прийняти.


2
Я думаю, що проблема полягає лише в тому, коли додаток було написано, що для .NET не було реальних записок ORM, тому це було зроблено іншим способом (ASP.NET 1.1 спосіб), і ніхто ніколи не думав робити це по-іншому поки я не приєднався кілька місяців тому.
Уейн Моліна

1
+1 для Dapper. Я тільки почав використовувати його в проекті, і це надзвичайно просто реалізувати та використовувати. Я вже великий фанат.
SLoret

4

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

Незважаючи на те, ви все ще можете писати елегантний та чистий код, використовуючи збережені програми. Наразі я сам реалізую шаблон репозиторію з усіма збереженими процедурами. Я б запропонував поглянути на FluentAdo.net для його геніальної ідеї при зіставленні даних із читача даних назад до об'єктів вашого бізнесу. Я взяв частинку цієї ідеї та переробив її для свого домашнього вирішення.


3

JFTR - Я низько розробник PHP, але це звучить як переважно політична проблема.

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

Чи можете ви гарантувати, що запропонована вами альтернатива принесе користь для виправдання витрат для бізнесу? Я підозрюю, що рентабельність цього підприємства може бути важко продати бізнесу. Якщо додаток нестабільний або ви не зможете довести користь капітального ремонту у фінансовому плані - це може виявитися важким.

Є ORM єдиною альтернативою SPROCS? Існує пара моделей дизайну між повноцінно продутим ORM і ванільним SQL. Можливо, ви могли б розпочати процес, переводячи ці SPROCS поступово з БД у DBAL. Звичайно, існує небезпека, що з часом це переросте у вітчизняну ОРМ - але ти б на крок наблизився до мети.


2

Ми перейшли з SP на ORM кілька років тому.

В одному випадку нам довелося оновити 80 таблиць. Стара модель оцінки оцінила б 80 годин для цього з entlib та SP. Ми це зробили за 10 :)

Це дозволило нам на 80% зменшити кількість часу, який ми використовуємо, розробляючи рівень доступу до даних.


1
І ви не змогли написати сценарій оновлення таблиці, чому?
Темна ніч

Це забирало складний об'єкт у пам'ять і зберігало його реляційну базу даних для звітності. Ми написали програму, яка зробила відображення об'єкта для створення структури таблиці.
Шираз Бхайджі

-1

Мені більше звучить, що основна проблема полягає в тому, що ваші розгортання працюють не правильно та автоматично.

Можливо, буде простіше налаштувати двигун безперервної збірки, який знає, як потрібно маніпулювати базами даних після необхідності кожного виконання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.