Làm thế nào để đề xuất sử dụng ORM thay vì các thủ tục được lưu trữ?


31

Tôi làm việc tại một công ty chỉ sử dụng các thủ tục được lưu trữ cho tất cả các truy cập dữ liệu, điều này gây khó chịu khi giữ cho cơ sở dữ liệu cục bộ của chúng tôi đồng bộ vì mọi cam kết chúng tôi phải chạy các procs mới. Tôi đã sử dụng một số ORM cơ bản trong quá khứ và tôi thấy trải nghiệm tốt hơn và sạch hơn nhiều. Tôi muốn đề xuất với người quản lý phát triển và phần còn lại của nhóm rằng chúng tôi xem xét sử dụng ORM Of một số loại để phát triển trong tương lai (phần còn lại của nhóm chỉ quen với các thủ tục được lưu trữ và chưa bao giờ sử dụng bất kỳ thứ gì khác). Kiến trúc hiện tại là .NET 3.5 được viết như .NET 1.1, với "các lớp thần" sử dụng một triển khai lạ của ActiveRecord và trả về các DataSets chưa được xử lý được lặp trong các tệp phía sau mã - các lớp hoạt động như sau:

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...

Có khá nhiều không có ứng dụng của bất kỳ mẫu thiết kế. Không có bài kiểm tra nào (không ai biết cách viết bài kiểm tra đơn vị, và kiểm tra được thực hiện thông qua việc tải lên trang web theo cách thủ công và chọc ngoáy). Nhìn qua cơ sở dữ liệu của chúng tôi, chúng tôi có: 199 bảng, 13 lượt xem, 926 thủ tục được lưu trữ và 93 hàm. Khoảng 30 hoặc hơn các bảng được sử dụng cho các công việc hàng loạt hoặc những thứ bên ngoài, phần còn lại được sử dụng trong ứng dụng cốt lõi của chúng tôi.

Có đáng để theo đuổi một cách tiếp cận khác trong kịch bản này? Tôi chỉ nói về việc tiến lên phía trước vì chúng tôi không được phép cấu trúc lại mã hiện tại vì "nó hoạt động" vì vậy chúng tôi không thể thay đổi các lớp hiện có để sử dụng ORM, nhưng tôi không biết tần suất chúng tôi thêm các mô-đun mới thay thế thêm vào / sửa chữa các mô-đun hiện tại để tôi không chắc liệu ORM có phải là phương pháp phù hợp hay không (đã đầu tư quá nhiều vào các thủ tục được lưu trữ và DataSets). Nếu đó là lựa chọn đúng đắn, tôi nên trình bày trường hợp sử dụng như thế nào? Ra khỏi đầu tôi những lợi ích duy nhất tôi có thể nghĩ đến là có mã sạch hơn (mặc dù có thể không phải vậy, vì kiến ​​trúc hiện tại không phải là ' Được xây dựng với các ORM trong tâm trí, vì vậy về cơ bản chúng tôi sẽ là các ORM gian lận trong các mô-đun trong tương lai nhưng các mô-đun cũ vẫn sẽ sử dụng DataSets) và ít gặp rắc rối hơn khi phải nhớ các tập lệnh thủ tục nào đã được chạy và cần chạy, vv nhưng đó là nó, và tôi không biết làm thế nào hấp dẫn một cuộc tranh luận sẽ được. Bảo trì là một mối quan tâm khác nhưng một điều mà không ai ngoại trừ tôi dường như quan tâm.


8
Âm thanh như bạn có nhiều vấn đề hơn là chỉ đơn giản là thuyết phục nhóm sử dụng ORM. Dường như với tôi rằng nhóm của bạn không nhận thức được một số thực tiễn phát triển tốt (ví dụ: mẫu thiết kế, thử nghiệm đơn vị). Đây là những vấn đề quan trọng hơn bạn cần phải giải quyết.
Bernard

6
Trớ trêu thay, tôi nghĩ trong khoảng 5 năm phát triển tôi chỉ gặp có thể một số ít người / nhóm nhận thức được những thứ như mẫu thiết kế và thử nghiệm đơn vị; Thường thì tôi là người duy nhất trong công ty biết về những điều đó.
Wayne Molina

3
@Wayne M: Tôi thấy điều đó hơi đáng lo ngại, nhưng tôi cũng không ngạc nhiên về điều này.
Bernard

2
Tôi đã tìm thấy nó rất ... không thành công. Thật kỳ lạ khi bạn đề xuất một cái gì đó và có được một cái nhìn "con nai trong đèn pha" cho thấy người khác không có ý tưởng mơ hồ về những gì bạn đang nói về hoặc tại sao mọi người sẽ xem xét làm điều đó. Tôi đã có điều đó xảy ra khá nhiều lần trong quá khứ.
Wayne Molina

2
Tôi là một fan hâm mộ lớn của Thủ tục lưu trữ, vì vậy nhận xét của tôi thiên vị, nhưng tôi hoàn toàn không đồng ý với toàn bộ tiền đề. Bạn thích ORM và bạn muốn sử dụng cái này tốt. Tuy nhiên, phần còn lại của đội vẫn ổn với các procs được lưu trữ. Tại sao buộc họ phải làm những gì bạn thích?
Đêm tối

Câu trả lời:


47

Các thủ tục được lưu trữ là xấu, chúng thường chậm và hiệu quả như mã phía máy khách thông thường.

[Việc tăng tốc thường là do cách thiết kế giao diện thủ tục khách và lưu trữ được thiết kế và cách các giao dịch được viết dưới dạng các cụm SQL ngắn, tập trung.]

Thủ tục lưu trữ là một trong những nơi tồi tệ nhất để đặt mã. Nó chia ứng dụng của bạn thành hai ngôn ngữ và nền tảng theo các quy tắc thường là ngẫu nhiên.

[Câu hỏi này sẽ được hạ xuống để có số điểm khoảng -30 vì nhiều người, nhiều người cảm thấy rằng các thủ tục được lưu trữ có sức mạnh ma thuật và phải được sử dụng bất chấp các vấn đề họ gây ra.]

Di chuyển tất cả các mã thủ tục được lưu trữ đến máy khách sẽ giúp mọi thứ dễ dàng hơn nhiều.

Thỉnh thoảng bạn vẫn phải cập nhật lược đồ và mô hình ORM. Tuy nhiên, các thay đổi lược đồ được tách biệt khỏi các thay đổi ORM, cho phép một số độc lập giữa các ứng dụng và lược đồ cơ sở dữ liệu.

Bạn sẽ có thể kiểm tra, sửa chữa, bảo trì, hiểu và điều chỉnh tất cả các quy trình được lưu trữ khi bạn viết lại chúng. Ứng dụng của bạn sẽ chạy giống nhau và trở nên mỏng manh hơn nhiều vì bạn không còn xâm nhập vào hai công nghệ khác nhau.

ORM không phải là phép thuật, và các kỹ năng thiết kế cơ sở dữ liệu tốt là vô cùng cần thiết để làm cho nó hoạt động.

Ngoài ra, các chương trình có nhiều SQL khách có thể trở nên chậm do suy nghĩ kém về ranh giới giao dịch. Một trong những lý do khiến các thủ tục được lưu trữ có vẻ nhanh là các thủ tục được lưu trữ buộc thiết kế giao dịch rất, rất cẩn thận.

ORM không kỳ diệu buộc thiết kế giao dịch cẩn thận. Thiết kế giao dịch vẫn phải được thực hiện cẩn thận như khi viết các thủ tục lưu trữ.


19
+1 vì các thủ tục được lưu trữ là một nỗi đau hoàn toàn để làm việc với
Gary Rowe

3
: '(Tôi không có vấn đề gì với các thủ tục được lưu trữ. Nó chỉ là một lớp trừu tượng khác đối với tôi.
Mike Weller

3
Nếu chúng ta tạo SP thì công cụ cơ sở dữ liệu lưu trữ nó dưới dạng biên dịch và nó tạo đường dẫn thực thi để nó sẽ thực thi nhanh nhất có thể. Nhưng ORM gửi SQL mỗi lần cần được biên dịch và chạy bởi công cụ cơ sở dữ liệu. Tôi nghĩ rằng sẽ chậm hơn khi sử dụng ORM thay vì Thủ tục lưu trữ.
Nhà phát

4
Buồn cười. Chúng tôi đã chuyển trở lại từ ORM sang các thủ tục được lưu trữ chỉ vì .. TỐC ĐỘ. Không phải lượng thời gian chúng ta cần để lập trình, mà là thời gian ORM cần cho những thứ như vật chất hóa, tìm kiếm một đối tượng, cập nhật trên các máy khách khác nhau. SP nơi địa ngục nhanh hơn rất nhiều. Một ví dụ: đọc 30.000 đối tượng từ DB với ORM hiện đại mới cần ... ồ. thời gian chờ sau 2 phút. Gọi thủ tục được lưu trữ và nhận kết quả - 2 giây. Có - tồn tại nhiều thủ thuật như phân trang để giảm bớt tên gọi từ DB - nhưng khác biệt lớn nếu chúng chỉ có thể sử dụng ORM hoặc
Offler

2
@DeveloperArnab: Điều đó có thể đúng 20 năm trước, nhưng các công cụ DB hiện đại khá phức tạp và có thể nhận ra các truy vấn đã thực hiện trước đó và sử dụng lại các kế hoạch thực hiện, sự khác biệt về tốc độ hiện nay rất khó đảm bảo các rắc rối bổ sung của SP.
whatsisname

20

Các thủ tục được lưu trữ là tốt, chúng nhanh và rất hiệu quả và là nơi lý tưởng để đặt mã liên quan đến dữ liệu của bạn. Di chuyển tất cả mã đó sang máy khách sẽ giúp bạn trở thành nhà phát triển ứng dụng khách dễ dàng hơn một chút (một chút, vì bạn vẫn sẽ phải cập nhật lược đồ và mô hình ORM khi cam kết thay đổi chúng) nhưng bạn sẽ mất tất cả mã hiện có đó và thực hiện ứng dụng của bạn chậm hơn và có lẽ dễ vỡ hơn khi xem xét việc mất tất cả các kỹ năng sql.

Tôi tự hỏi nếu các DBA đang ngồi đó nói rằng "ồ, mỗi lần cam kết, tôi phải kéo khách hàng xuống một lần nữa, chúng ta nên chuyển tất cả mã thành các dạng DB".

Trong trường hợp của bạn, bạn sẽ có thể thay thế ORM tùy chỉnh hiện tại (tức là các lớp vui nhộn của bạn) bằng người khác mà không bị mất ngoại trừ thay đổi cách viết mã phía sau mã của bạn. Bạn có thể giữ các SP quá nhiều (hầu hết?) Các ORM sẽ vui vẻ gọi chúng. Vì vậy, tôi khuyên bạn nên thay thế các lớp "Foo" đó bằng ORM và đi từ đó. Tôi không khuyên bạn nên thay thế SP của bạn.

Tái bút Dường như bạn có rất nhiều mã phổ biến trong các lớp mã phía sau, điều đó làm cho chúng trở thành một mẫu thiết kế trong chính chúng. Bạn nghĩ gì về một mẫu thiết kế ở nơi đầu tiên! (ok, nó có thể không phải là tốt nhất, hoặc thậm chí là tốt, nhưng nó vẫn là DP)

Chỉnh sửa: và bây giờ với Dapper , mọi lý do để tránh sprocs trên ORM hạng nặng đã biến mất.


3
+1, bước đầu tiên rõ ràng là di chuyển đến ORM và sử dụng điều đó để ánh xạ kết quả của các thủ tục được lưu trữ hiện có vào các đối tượng. Loại bỏ tất cả những thứ ds.Tables[0].Rows[0]["FooName"].ToString()nhảm nhí đó . Quản lý thích thủ tục lưu trữ? Anh ấy sẽ giữ chúng. Nhưng về mặt vật lý, không thể tranh luận rằng việc chuyển tất cả mã soạn sẵn lặp đi lặp lại thành thứ gì đó được tạo ra bởi, nói, LINQ sang SQL, là một điều tồi tệ.
Carson63000

11
Chà, tôi không thể tin được có bao nhiêu "sai" trong bài viết của bạn. So sánh của bạn với một DBA rên rỉ về việc phải kéo mã là không phù hợp và hoàn toàn vô nghĩa. Trước hết, cơ sở dữ liệu là một DỊCH VỤ có nghĩa là lưu trữ và truy xuất dữ liệu, kết thúc câu chuyện. LOGIC như tên ngụ ý đi vào Lớp Logic nghiệp vụ, là một phần của mã API. Ứng dụng dễ vỡ hơn di chuyển từ sprocs? Bạn nghiêm túc hay chỉ là trolling? TDD một ứng dụng có logic trong sprocs và cho tôi biết điều đó thú vị như thế nào. Ngoài ra ORM không có nghĩa là phải được chuyển đổi. Cơ sở dữ liệu là, vì chúng chỉ là một DỊCH VỤ.
Matteo Mosca

5
Tôi thực sự không thể hiểu tại sao một số người nghĩ rằng cơ sở dữ liệu là một loại đất thánh nơi mọi thứ đều thiêng liêng. Nghĩ về điều này. Khi một công ty bên thứ ba cung cấp cho bạn một dịch vụ, họ có cấp cho bạn quyền truy cập trực tiếp vào db của họ hay họ che giấu nó đằng sau một API? Để sử dụng một ví dụ phổ biến, hãy sử dụng bất kỳ dịch vụ nào của Google. Bạn, nhà phát triển, kết nối với API công khai của họ, thậm chí bạn không biết cơ sở dữ liệu nào trong đó hoặc nếu có cơ sở dữ liệu nào. Đó là cách bạn thiết kế một phần mềm tách rời và tách rời. Cơ sở dữ liệu không có nghĩa là được truy cập trực tiếp bởi các ứng dụng. Các tầng trung lưu ở đó cho điều đó.
Matteo Mosca

5
@Matteo Mosca: chắc chắn, nhưng làm thế nào để phần mềm trung gian truy cập DB ... nó là máy khách của DB. "Client" không có nghĩa là "GUI" hay "ứng dụng máy tính để bàn". Có rất nhiều vùng màu xám trong các tầng ứng dụng - bạn có xác thực trong GUI hoặc trong logic máy chủ / doanh nghiệp không? Nó nên đi vào máy chủ để trở thành một thiết kế rõ ràng, nhưng điều đó sẽ thực sự kém về hiệu năng và khả năng đáp ứng của người dùng. Tương tự, bạn thường đặt một số logic trong DB khi nó làm cho hiệu suất và (trong trường hợp này) tính chính xác của dữ liệu tốt hơn.
gbjbaanb

4
Tôi xin lỗi nhưng tôi vẫn không đồng ý. Ngày bạn phải triển khai ứng dụng của mình ở một môi trường khác, nơi bạn không có cùng công nghệ DB mà bạn đã sử dụng, bạn thấy mình trong tình huống ứng dụng của bạn không thể chạy được vì bạn không có tất cả các sprocs trên cơ sở dữ liệu mới .. và ngay cả khi bạn tạo lại chúng (đó là một nỗi đau hoàn toàn) thì chúng có thể khác nhau, do sự khác biệt của phương ngữ SQL, v.v. Một API tập trung với logic và xác thực, được thể hiện thông qua một tiêu chuẩn (như SOAP hoặc REST) ​​giải quyết điều này vấn đề, và thêm khả năng kiểm tra, phiên bản và tính nhất quán.
Matteo Mosca

13

Bạn dường như đang cố gắng dẫn dắt nhóm của mình từ một cực đoan (các thủ tục và bộ dữ liệu được lưu trữ) sang một nhóm khác (một ORM toàn diện). Tôi nghĩ có những thay đổi khác, gia tăng hơn mà bạn có thể đặt ra khi thực hiện để cải thiện chất lượng mã của lớp truy cập dữ liệu của mình, điều mà nhóm của bạn có thể sẵn sàng chấp nhận hơn.

Mã triển khai bản ghi hoạt động nửa nướng mà bạn đã đăng không đặc biệt thanh lịch - Tôi khuyên bạn nên nghiên cứu Mẫu lưu trữ dễ hiểu và dễ thực hiện và rất phổ biến với các nhà phát triển .NET. Mẫu này thường được liên kết với ORM nhưng thật dễ dàng để tạo các kho lưu trữ bằng cách sử dụng ADO.NET đơn giản.

Đối với Dataset - yuck! Các thư viện lớp của bạn sẽ làm việc dễ dàng hơn nhiều nếu bạn trả về các đối tượng được nhập tĩnh (hoặc thậm chí động). Tôi tin rằng minh họa này giải thích ý kiến ​​của tôi về Dataset tốt hơn tôi có thể.

Ngoài ra, bạn có thể bỏ các Proc được lưu trữ mà không cần nhảy tới ORM - không có gì sai khi sử dụng SQL được tham số hóa. Trên thực tế, tôi chắc chắn sẽ ưu tiên cho nó hơn là sử dụng các lưu trữ được lưu trữ trừ khi bạn có các quy trình phức tạp tiết kiệm cho nhiều chuyến đi khứ hồi đến máy chủ. Tôi cũng ghét nó khi tôi mở một cơ sở dữ liệu kế thừa và thấy một danh sách vô tận các thủ tục CRUD.

Tôi không nản lòng khi sử dụng ORM - Tôi thường sử dụng chúng cho hầu hết các dự án tôi làm. Tuy nhiên tôi có thể thấy lý do tại sao có thể có nhiều xích mích khi cố gắng giới thiệu một người vào dự án này và nhóm của bạn để đưa nó vào một cách tử tế, nghe có vẻ như họ đã ngừng học những điều mới khoảng 8 năm trước. Phải nói rằng tôi chắc chắn sẽ xem xét giống "Micro ORM" mới như Dapper (được sử dụng để cung cấp năng lượng cho trang này không kém) và Massive , cả hai đều rất dễ sử dụng và giúp bạn gần gũi hơn với SQL hơn là ORM điển hình, và nhóm của bạn có thể sẵn sàng chấp nhận hơn.


2
Tôi nghĩ vấn đề chỉ là khi ứng dụng được viết không có ORM thực sự đáng chú ý cho .NET nên nó đã được thực hiện theo cách khác (cách ASP.NET 1.1) và không ai nghĩ sẽ làm điều đó (hoặc bất cứ điều gì khác) cho đến khi tôi tham gia vài tháng trước
Wayne Molina

1
+1 cho Dapper. Tôi mới bắt đầu sử dụng nó trên một dự án và nó cực kỳ dễ thực hiện và sử dụng. Tôi đã là một fan hâm mộ lớn.
SLoret

4

Tôi đang ở trong một tình huống tương tự, thực sự phần cứng, sức mạnh và chính trị của chúng ta nghiêng về phía cơ sở dữ liệu, vì vậy mọi thứ đều trải qua một thủ tục được lưu trữ. Thật không may, chúng là một nỗi đau cho một lập trình viên, đặc biệt là khi nói đến siêu dữ liệu và tạo mã, vì không có dữ liệu meta phong phú trong các thủ tục được lưu trữ như các bảng.

Bất kể, bạn vẫn có thể viết mã thanh lịch và sạch sẽ bằng cách sử dụng các procs được lưu trữ. Tôi hiện đang tự triển khai mẫu Kho lưu trữ với tất cả các thủ tục được lưu trữ. Tôi khuyên bạn nên xem FluentAdo.net để biết ý tưởng tuyệt vời của mình khi ánh xạ từ bộ dữ liệu trở lại các đối tượng kinh doanh của bạn. Tôi lấy một phần của ý tưởng đó, và tái sử dụng nó cho giải pháp cây nhà của tôi.


3

JFTR - Tôi là một nhà phát triển PHP thấp, nhưng điều này có vẻ như là một vấn đề chính trị.

Với quy mô của "mục nát" hỗ trợ ứng dụng, sau đó - thực hành tốt nhất sang một bên - sẽ có một chi phí đáng kể để thoát khỏi ứng dụng. Điều này có vẻ như nó giáp với lãnh thổ viết lại.

Bạn có thể đảm bảo rằng giải pháp thay thế mà bạn đề xuất sẽ mang lại lợi ích để chứng minh chi phí cho doanh nghiệp không? Tôi nghi ngờ rằng ROI của liên doanh này có thể khó bán cho doanh nghiệp. Trừ khi ứng dụng không ổn định, hoặc bạn có thể chứng minh giá trị của việc đại tu về mặt tài chính - điều này có thể chứng tỏ là khó khăn.

ORM có phải là sự thay thế duy nhất cho XUÂN? Có một vài mẫu thiết kế giữa một ORM đầy đủ và vanilla SQL. Có lẽ bạn có thể bắt đầu quá trình bằng cách đưa các XUÂN này dần dần ra khỏi DB thành DBAL. Tất nhiên, có một mối nguy hiểm là điều này sẽ phát triển thành một ORM homebrew theo thời gian - nhưng bạn đã tiến một bước gần hơn đến mục tiêu.


2

Chúng tôi đã chuyển từ SP sang ORM vài năm trước.

Trong một trường hợp, chúng tôi đã phải cập nhật 80 bảng. Mô hình ước lượng cũ sẽ ước tính 80 giờ cho việc này với entlib và SP. Chúng tôi đã làm điều đó trong 10 :)

Nó đã giúp chúng tôi giảm 80% lượng thời gian chúng tôi sử dụng để phát triển lớp truy cập dữ liệu.


1
Và bạn không thể kịch bản cập nhật bảng tại sao?
Đêm tối

Điều này đã lấy một đối tượng phức tạp trong bộ nhớ và lưu nó vào cơ sở dữ liệu quan hệ để báo cáo. Chúng tôi đã viết một chương trình phản ánh lên đối tượng để tạo cấu trúc bảng.
Shiraz Bhaiji

-1

Nghe có vẻ nhiều hơn với tôi rằng vấn đề cơ bản là việc triển khai của bạn không hoạt động đúng và tự động.

Có thể dễ dàng hơn để thiết lập một công cụ xây dựng liên tục, biết cách thao tác cơ sở dữ liệu khi cần sau mỗi lần xác nhận.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.