Những ưu và nhược điểm của việc giữ SQL trong Procs được lưu trữ so với Code [đã đóng]


274

Những lợi thế / bất lợi của việc giữ SQL trong mã nguồn C # của bạn hoặc trong Procs được lưu trữ là gì? Tôi đã thảo luận điều này với một người bạn trong một dự án nguồn mở mà chúng tôi đang làm việc (Diễn đàn C # ASP.NET). Hiện tại, hầu hết các truy cập cơ sở dữ liệu được thực hiện bằng cách xây dựng dòng SQL trong C # và gọi tới SQL Server DB. Vì vậy, tôi đang cố gắng thiết lập cái nào, cho dự án cụ thể này, sẽ là tốt nhất.

Cho đến nay tôi có:

Ưu điểm cho mã:

  • Dễ bảo trì hơn - không cần chạy tập lệnh SQL để cập nhật truy vấn
  • Dễ dàng chuyển sang DB khác - không có procs sang cổng

Ưu điểm cho Procs lưu trữ:

  • Hiệu suất
  • Bảo vệ

50
Bạn cũng có thể lập luận rằng Procs được lưu trữ giúp bảo trì dễ dàng hơn - bạn không cần phải triển khai lại toàn bộ ứng dụng chỉ để thay đổi một truy vấn.
Darren Gosbell

27
@GvS: đó là một rối loạn chức năng của công ty bạn, không phải là một thực tiễn tốt nhất. Tất nhiên sẽ dễ dàng thay đổi mọi thứ ở 1 vị trí hơn 1000. Các DBA chỉ đơn giản là thực hiện phần của mình để ngăn chặn những thay đổi ung dung đối với hệ thống, và điều đó cần được tôn trọng.
Jeremy Holovacs

Câu trả lời:


179

Tôi không phải là một fan hâm mộ của các thủ tục lưu trữ

Các thủ tục được lưu trữ có thể duy trì THÊM vì: * Bạn không phải biên dịch lại ứng dụng C # của mình bất cứ khi nào bạn muốn thay đổi một số SQL

Cuối cùng, bạn sẽ biên dịch lại nó khi kiểu dữ liệu thay đổi hoặc bạn muốn trả về một cột bổ sung hoặc bất cứ điều gì. Số lần bạn có thể 'minh bạch' thay đổi SQL từ bên dưới ứng dụng của bạn khá ít

  • Bạn cuối cùng sử dụng lại mã SQL.

Ngôn ngữ lập trình, bao gồm C #, có điều tuyệt vời này, được gọi là hàm. Nó có nghĩa là bạn có thể gọi cùng một khối mã từ nhiều nơi! Kinh ngạc! Sau đó, bạn có thể đặt mã SQL có thể sử dụng lại vào một trong những mã này hoặc nếu bạn muốn có được công nghệ thực sự cao, bạn có thể sử dụng một thư viện dành cho bạn. Tôi tin rằng chúng được gọi là Mappers đối tượng quan hệ, và khá phổ biến ngày nay.

Lặp lại mã là điều tồi tệ nhất bạn có thể làm khi bạn đang cố gắng xây dựng một ứng dụng có thể bảo trì!

Đồng ý, đó là lý do tại sao Storageprocs là một điều xấu. Việc tái cấu trúc và phân tách (chia thành các phần nhỏ hơn) thành các hàm dễ dàng hơn nhiều so với SQL thành ... các khối SQL?

Bạn có 4 máy chủ web và một loạt các ứng dụng Windows sử dụng cùng một mã SQL Bây giờ bạn đã nhận ra rằng có một vấn đề nhỏ với mã SQl, vì vậy, thay vào đó, hãy thay đổi Proc ở 1 vị trí hoặc đẩy mã lên tất cả máy chủ web, cài đặt lại tất cả các ứng dụng máy tính để bàn (clickonce có thể giúp) trên tất cả các hộp cửa sổ

Tại sao các ứng dụng windows của bạn kết nối trực tiếp với cơ sở dữ liệu trung tâm? Điều đó có vẻ như là một lỗ hổng bảo mật HUGE ngay tại đó, và tắc nghẽn khi nó loại trừ bộ nhớ đệm phía máy chủ. Họ không nên kết nối thông qua một dịch vụ web hoặc tương tự như các máy chủ web của bạn?

Vì vậy, đẩy 1 sproc mới, hoặc 4 weberervers mới?

Trong trường hợp này, việc đẩy một sproc mới sẽ dễ dàng hơn, nhưng theo kinh nghiệm của tôi, 95% 'thay đổi được đẩy' ảnh hưởng đến mã chứ không phải cơ sở dữ liệu. Nếu bạn đang đẩy 20 thứ vào máy chủ web trong tháng đó và 1 vào cơ sở dữ liệu, bạn khó có thể mất nhiều thứ nếu thay vào đó bạn đẩy 21 thứ vào máy chủ web và 0 cho cơ sở dữ liệu.

Mã dễ dàng hơn được xem xét.

Bạn có thể giải thích như thế nào? Tôi không hiểu điều này. Đặc biệt là các sprocs có thể không kiểm soát nguồn và do đó không thể được truy cập thông qua các trình duyệt SCM dựa trên web, v.v.

Thêm khuyết điểm:

Storedprocs sống trong cơ sở dữ liệu, xuất hiện với thế giới bên ngoài dưới dạng hộp đen. Những điều đơn giản như muốn đưa chúng vào kiểm soát nguồn trở thành một cơn ác mộng.

Cũng có vấn đề về nỗ lực tuyệt đối. Có thể có ý nghĩa khi chia mọi thứ thành một triệu bậc nếu bạn cố gắng biện minh cho Giám đốc điều hành của mình tại sao chỉ tốn 7 triệu đô la để xây dựng một số diễn đàn, nhưng nếu không, việc tạo ra một chương trình lưu trữ cho mọi việc nhỏ chỉ là lừa đảo thêm lợi ích.


99

Điều này hiện đang được thảo luận về một vài chủ đề khác ở đây. Tôi là người đề xuất nhất quán các thủ tục được lưu trữ, mặc dù một số lập luận tốt cho Linq đối với Sql đang được trình bày.

Nhúng các truy vấn trong mã của bạn kết hợp chặt chẽ với mô hình dữ liệu của bạn. Các thủ tục được lưu trữ là một hình thức lập trình hợp đồng tốt, có nghĩa là DBA có quyền tự do thay đổi mô hình dữ liệu và mã trong thủ tục, miễn là hợp đồng được thể hiện bởi đầu vào và đầu ra của thủ tục được lưu trữ được duy trì.

Điều chỉnh cơ sở dữ liệu sản xuất có thể cực kỳ khó khăn khi các truy vấn được chôn trong mã và không nằm ở một vị trí trung tâm, dễ quản lý.

[Chỉnh sửa] Đây là một cuộc thảo luận hiện tại


47

Theo tôi, bạn không thể bỏ phiếu cho có hay không cho câu hỏi này. Nó hoàn toàn phụ thuộc vào thiết kế của ứng dụng của bạn.

Tôi hoàn toàn bỏ phiếu chống lại việc sử dụng SP trong môi trường 3 tầng, nơi bạn có máy chủ ứng dụng ở phía trước. Trong loại môi trường này, máy chủ ứng dụng của bạn có mặt để chạy logic kinh doanh của bạn. Nếu bạn sử dụng thêm SP, bạn bắt đầu phân phối việc triển khai logic kinh doanh trên toàn hệ thống của mình và nó sẽ trở nên rất không rõ ai chịu trách nhiệm cho việc gì. Cuối cùng, bạn sẽ kết thúc với một máy chủ ứng dụng về cơ bản sẽ không làm gì ngoài những điều sau đây:

(Pseudocode)

Function createOrder(Order yourOrder) 
Begin
  Call SP_createOrder(yourOrder)
End

Vì vậy, cuối cùng bạn có tầng giữa của bạn chạy trên cụm 4 Máy chủ rất tuyệt vời này, mỗi cụm được trang bị 16 CPU và nó thực sự sẽ chẳng làm được gì cả! Thật là lãng phí!

Nếu bạn có một máy khách gui béo kết nối trực tiếp với DB của bạn hoặc thậm chí nhiều ứng dụng hơn thì đó là một câu chuyện khác. Trong tình huống này, SP có thể đóng vai trò là một loại tầng trung giả giả tách ứng dụng của bạn khỏi mô hình dữ liệu và cung cấp quyền truy cập có thể kiểm soát được.


44

Ưu điểm cho mã:

  • Dễ bảo trì hơn - không cần chạy tập lệnh SQL để cập nhật truy vấn
  • Dễ dàng chuyển sang DB khác - không có procs sang cổng

Trên thực tế, tôi nghĩ rằng bạn có điều đó ngược. IMHO, SQL trong mã là nỗi đau để duy trì bởi vì:

  • cuối cùng bạn lặp lại chính mình trong các khối mã liên quan
  • SQL không được hỗ trợ như một ngôn ngữ trong nhiều IDE, vì vậy bạn chỉ có một chuỗi các chuỗi được kiểm tra không có lỗi thực hiện các tác vụ cho bạn
  • những thay đổi trong kiểu dữ liệu, tên bảng hoặc ràng buộc phổ biến hơn nhiều so với việc hoán đổi toàn bộ cơ sở dữ liệu cho một cơ sở dữ liệu mới
  • mức độ khó của bạn tăng lên khi truy vấn của bạn tăng lên phức tạp
  • và kiểm tra một truy vấn nội tuyến yêu cầu xây dựng dự án

Hãy nghĩ về Procs được lưu trữ như các phương thức bạn gọi từ đối tượng cơ sở dữ liệu - chúng dễ sử dụng hơn nhiều, chỉ có một nơi để chỉnh sửa và trong trường hợp bạn thay đổi nhà cung cấp DB, các thay đổi xảy ra trong Procs được lưu trữ của bạn chứ không phải trong mã của bạn .

Điều đó nói rằng, hiệu suất tăng của các procs được lưu trữ là tối thiểu như Stu đã nói trước tôi và bạn không thể đặt điểm dừng trong một thủ tục được lưu trữ (chưa).


33

CON

Tôi thấy rằng việc thực hiện nhiều xử lý bên trong các thủ tục được lưu trữ sẽ làm cho máy chủ DB của bạn trở thành một điểm không linh hoạt, khi nói đến việc nhân rộng hành động của bạn.

Tuy nhiên, làm tất cả những gì khủng hoảng trong chương trình của bạn trái ngược với máy chủ sql, có thể cho phép bạn mở rộng quy mô hơn nếu bạn có nhiều máy chủ chạy mã của mình. Tất nhiên, điều này không áp dụng cho các procs được lưu trữ, chỉ thực hiện tìm nạp hoặc cập nhật thông thường mà áp dụng cho các hoạt động xử lý nhiều hơn như lặp qua các tập dữ liệu.

PROS

  1. Hiệu suất cho những gì nó có thể có giá trị (tránh phân tích cú pháp truy vấn bởi trình điều khiển DB / kế hoạch giải trí, v.v.)
  2. Thao tác dữ liệu không được nhúng trong mã C / C ++ / C #, điều đó có nghĩa là tôi có ít mã cấp thấp hơn để xem qua. SQL ít dài dòng hơn và dễ xem qua hơn khi được liệt kê riêng.
  3. Do việc phân tách mọi người có thể tìm và sử dụng lại mã SQL dễ dàng hơn nhiều.
  4. Dễ dàng thay đổi mọi thứ khi lược đồ thay đổi - bạn chỉ cần đưa ra cùng một đầu ra cho mã và nó sẽ hoạt động tốt
  5. Dễ dàng hơn để chuyển đến một cơ sở dữ liệu khác nhau.
  6. Tôi cũng có thể liệt kê các quyền riêng lẻ trên các thủ tục được lưu trữ của mình và kiểm soát quyền truy cập ở cấp đó.
  7. Tôi có thể cấu hình mã truy vấn / mã lưu trữ dữ liệu tách biệt với mã chuyển đổi dữ liệu của mình.
  8. Tôi có thể thực hiện các điều kiện thay đổi trong quy trình được lưu trữ của mình và có thể dễ dàng tùy chỉnh tại trang web của khách hàng.
  9. Việc sử dụng một số công cụ tự động để chuyển đổi lược đồ và các câu lệnh của tôi trở nên dễ dàng hơn thay vì khi nó được nhúng vào mã của tôi, nơi tôi sẽ phải tìm kiếm chúng.
  10. Đảm bảo thực hành tốt nhất để truy cập dữ liệu dễ dàng hơn khi bạn có tất cả mã truy cập dữ liệu của mình trong một tệp - Tôi có thể kiểm tra các truy vấn truy cập vào bảng không thực hiện hoặc sử dụng mức tuần tự hóa cao hơn hoặc chọn * trong mã, v.v. .
  11. Nó trở nên dễ dàng hơn để tìm các thay đổi lược đồ / logic thao tác dữ liệu thay đổi khi tất cả được liệt kê trong một tệp.
  12. Việc tìm kiếm và thay thế các chỉnh sửa trên SQL trở nên dễ dàng hơn khi chúng ở cùng một vị trí, ví dụ: thay đổi / thêm các câu lệnh cách ly giao dịch cho tất cả các procs được lưu trữ.
  13. Tôi và anh chàng DBA thấy rằng việc có một tệp SQL riêng sẽ dễ dàng / thuận tiện hơn khi DBA phải xem lại nội dung SQL của tôi.
  14. Cuối cùng, bạn không phải lo lắng về các cuộc tấn công SQL SQL vì một số thành viên lười biếng trong nhóm của bạn đã không sử dụng các truy vấn tham số khi sử dụng các sqls nhúng.

22

Lợi thế về hiệu suất cho các thủ tục được lưu trữ thường không đáng kể.

Nhiều lợi thế hơn cho các thủ tục được lưu trữ:

  • Tất nhiên, ngăn chặn kỹ thuật đảo ngược (nếu được tạo bằng Mã hóa)
  • Tập trung tốt hơn truy cập cơ sở dữ liệu
  • Khả năng thay đổi mô hình dữ liệu một cách minh bạch (không phải triển khai các máy khách mới); đặc biệt tiện dụng nếu nhiều chương trình truy cập vào cùng một mô hình dữ liệu

16

Tôi rơi vào bên . Chúng tôi xây dựng lớp truy cập dữ liệu được sử dụng bởi tất cả các ứng dụng (cả web và máy khách), do đó, nó KHÔ từ quan điểm đó. Nó đơn giản hóa việc triển khai cơ sở dữ liệu vì chúng ta chỉ cần đảm bảo lược đồ bảng là chính xác. Nó đơn giản hóa việc bảo trì mã bởi vì chúng ta không phải xem mã nguồn và cơ sở dữ liệu.

Tôi không gặp nhiều vấn đề với khớp nối chặt chẽ với mô hình dữ liệu vì tôi không thấy nơi nào có thể thực sự phá vỡ khớp nối đó. Một ứng dụng và dữ liệu của nó vốn đã được ghép nối.


13

Thủ tục lưu trữ.

Nếu một lỗi trượt hoặc logic thay đổi một chút, bạn không phải biên dịch lại dự án. Thêm vào đó, nó cho phép truy cập từ các nguồn khác nhau, không chỉ là nơi bạn đã mã hóa truy vấn trong dự án của mình.

Tôi không nghĩ việc duy trì các thủ tục được lưu trữ là khó khăn hơn, bạn không nên mã hóa chúng trực tiếp trong cơ sở dữ liệu mà trước tiên là trong các tệp riêng biệt, sau đó bạn có thể chạy chúng trên bất kỳ DB nào bạn cần để thiết lập.


24
Nếu bạn thấy mình đưa ra các quyết định kiến ​​trúc cơ bản để tránh biên dịch lại mã của mình, thì trước khi làm bất cứ điều gì, hãy thiết lập quy trình xây dựng không hoàn toàn hấp dẫn. Đây là một cuộc tranh luận.
Michael Borgwardt

13

Ưu điểm cho thủ tục lưu trữ :

Mã dễ dàng hơn được xem xét.

Ít kết hợp, do đó dễ dàng kiểm tra hơn.

Dễ dàng điều chỉnh hơn.

Hiệu suất nhìn chung tốt hơn, từ quan điểm về lưu lượng truy cập mạng - nếu bạn có một con trỏ hoặc tương tự, thì sẽ không có nhiều chuyến đi đến cơ sở dữ liệu

Bạn có thể bảo vệ quyền truy cập vào dữ liệu dễ dàng hơn, loại bỏ quyền truy cập trực tiếp vào các bảng, thực thi bảo mật thông qua các procs - điều này cũng cho phép bạn tìm tương đối nhanh chóng bất kỳ mã nào cập nhật bảng.

Nếu có các dịch vụ khác liên quan (chẳng hạn như Dịch vụ báo cáo), bạn có thể thấy việc lưu trữ tất cả logic của mình trong một thủ tục được lưu trữ, thay vì trong mã và phải sao chép nó dễ dàng hơn

Nhược điểm:

Khó quản lý hơn cho các nhà phát triển: kiểm soát phiên bản của các tập lệnh: mọi người có cơ sở dữ liệu riêng của họ không, hệ thống kiểm soát phiên bản có được tích hợp với cơ sở dữ liệu và IDE không?


Có, bạn có thể có một điều khiển phiên bản trong các thủ tục và cơ sở dữ liệu được lưu trữ trong dự án cơ sở dữ liệu visual studio 2012 và tfs.
hajirazin

11

Trong một số trường hợp, mã sql được tạo động có thể có hiệu năng tốt hơn so với một Proc được lưu trữ. Nếu bạn đã tạo một Proc được lưu trữ (giả sử sp_customersearch) cực kỳ phức tạp với hàng tá tham số vì nó phải rất linh hoạt, bạn có thể tạo một câu lệnh sql đơn giản hơn nhiều trong thời gian chạy.

Người ta có thể lập luận rằng điều này chỉ đơn giản là chuyển một số xử lý từ SQL sang máy chủ web, nhưng nói chung đó sẽ là một điều tốt.

Một điều tuyệt vời khác về kỹ thuật này là nếu bạn đang tìm kiếm trong trình cấu hình SQL, bạn có thể thấy truy vấn bạn đã tạo và gỡ lỗi dễ dàng hơn nhiều so với việc thấy một cuộc gọi Proc được lưu trữ với 20 tham số xuất hiện.


1
Không chắc chắn tại sao câu trả lời này đã được bỏ phiếu .. đúng là một truy vấn nhỏ hơn có thể thực hiện tốt hơn. Điều này thậm chí đã được nhận xét bởi nhóm SQL Server.
Brannon

9

Tôi thích các procs được lưu trữ, không biết bao nhiêu lần tôi có thể thay đổi một ứng dụng bằng cách sử dụng một thủ tục được lưu trữ mà không tạo ra bất kỳ thời gian chết nào cho ứng dụng.

Fan hâm mộ lớn của Transact SQL, điều chỉnh các truy vấn lớn đã được chứng minh là rất hữu ích đối với tôi. Không viết bất kỳ SQL nội tuyến nào trong khoảng 6 năm!


Tôi chỉ không thể hiểu một quan điểm khác bằng cách sử dụng querry trong mã, chỉ không thể hiểu ...
Chaki_Black

8

Bạn liệt kê 2 điểm pro cho sprocs:

Hiệu suất - không thực sự. Trong Sql 2000 hoặc cao hơn, tối ưu hóa kế hoạch truy vấn là khá tốt và được lưu trữ. Tôi chắc chắn rằng Oracle vv làm những điều tương tự. Tôi không nghĩ rằng có một trường hợp cho sprocs cho hiệu suất nữa.

Bảo vệ? Tại sao sprocs sẽ an toàn hơn? Trừ khi bạn có một cơ sở dữ liệu không bảo mật, dù sao thì tất cả quyền truy cập sẽ đến từ các DBA của bạn hoặc thông qua ứng dụng của bạn. Luôn luôn tham gia tất cả các truy vấn - không bao giờ nội tuyến gì đó từ đầu vào của người dùng và bạn sẽ ổn.

Đó là cách tốt nhất để thực hiện dù sao đi nữa.

Linq chắc chắn là cách tôi đi vào một dự án mới ngay bây giờ. Xem cái này tương tự .


Các kế hoạch thực thi SQL đặc biệt chỉ được sử dụng lại trong các trường hợp cụ thể: tinyurl.com/6x5lmd [Câu trả lời SO với bằng chứng mã] LINQ to SQL đã chính thức bị khai tử: tinyurl.com/6298nd [bài đăng trên blog]
HTTP 410

1
Procs là cách an toàn nhất để đi. Họ giới hạn người dùng chỉ thực hiện các hành động trong procs. Họ không thể trực tiếp đến một bảng hoặc xem rằng họ có quyền truy cập bằng văn bản và thay đổi mọi thứ. Procs là cần thiết để ngăn chặn tác hại từ các mối đe dọa nội bộ.
HLGEM

8

@Keith

Bảo vệ? Tại sao sprocs sẽ an toàn hơn?

Theo đề xuất của Komradekatz, bạn có thể không cho phép truy cập vào các bảng (đối với kết hợp tên người dùng / mật khẩu kết nối với DB) và chỉ cho phép truy cập SP. Theo cách đó, nếu ai đó lấy tên người dùng và mật khẩu vào cơ sở dữ liệu của bạn, họ có thể thực thi SP nhưng không thể truy cập vào các bảng hoặc bất kỳ phần nào khác của DB.

(Tất nhiên việc thực thi các sprocs có thể cung cấp cho họ tất cả dữ liệu họ cần nhưng điều đó phụ thuộc vào các sprocs có sẵn. Cung cấp cho họ quyền truy cập vào các bảng cho phép họ truy cập vào mọi thứ.)


1
@Joe Philllips, các lượt xem không cung cấp cho bạn sự bảo mật tốt hơn hoặc thậm chí ngang bằng với các procs và chúng sẽ KHÔNG hữu ích trong việc ngăn chặn gian lận hoặc tổn hại nội bộ. Khi bạn sử dụng procs, mô hình bảo mật là người dùng của họ chỉ có quyền truy cập vào Proc chứ không phải các bảng hoặc dạng xem và do đó họ không thể làm bất cứ điều gì ngoại trừ những gì một Proc làm. Nếu bạn có dữ liệu tài chính và bạn không sử dụng procs, hệ thống của bạn sẽ gặp rủi ro.
HLGEM

7

Nghĩ theo cách này

Bạn có 4 máy chủ web và một loạt các ứng dụng Windows sử dụng cùng một mã SQL Bây giờ bạn đã nhận ra rằng có một vấn đề nhỏ với mã SQl, vì vậy, thay vào đó, hãy thay đổi Proc ở 1 vị trí hoặc đẩy mã lên tất cả máy chủ web, cài đặt lại tất cả các ứng dụng máy tính để bàn (clickonce có thể giúp) trên tất cả các hộp cửa sổ

Tôi thích lưu trữ procs

Việc kiểm tra hiệu năng đối với một Proc cũng dễ dàng hơn, hãy đặt nó vào bộ phân tích truy vấn đặt số liệu thống kê io / time trên set showplan giác trên và voila

không cần phải chạy profiler để xem chính xác những gì đang được gọi

chỉ 2 xu của tôi


6

Tôi thích giữ chúng trong mã (sử dụng ORM, không phải nội tuyến hoặc đặc biệt) để chúng được kiểm soát nguồn mà không phải xử lý khi lưu các tệp .sql.

Ngoài ra, các thủ tục được lưu trữ vốn không an toàn hơn. Bạn có thể viết một truy vấn xấu với một sproc dễ dàng như nội tuyến. Các truy vấn nội tuyến được tham số hóa có thể an toàn như một sproc.


6

Sử dụng mã ứng dụng của bạn như những gì nó làm tốt nhất: xử lý logic.
Sử dụng cơ sở dữ liệu của bạn cho những gì nó làm tốt nhất: lưu trữ dữ liệu.

Bạn có thể gỡ lỗi các thủ tục được lưu trữ nhưng bạn sẽ thấy dễ dàng hơn để gỡ lỗi và duy trì logic trong mã. Thông thường, bạn sẽ kết thúc việc biên dịch lại mã của mình mỗi khi bạn thay đổi mô hình cơ sở dữ liệu.

Các thủ tục được lưu trữ với các tham số tìm kiếm tùy chọn rất không chính xác vì bạn phải chỉ định trước tất cả các tham số có thể và các tìm kiếm phức tạp đôi khi không thể thực hiện được vì bạn không thể dự đoán được bao nhiêu lần một tham số sẽ được lặp lại trong seach.


2
Khi nhiều ứng dụng truy cập cùng một cơ sở dữ liệu và cơ sở dữ liệu bị ảnh hưởng bởi nhập khẩu và truy cập trực tiếp khác (cập nhật tất cả giá 10%), logic phải có trong cơ sở dữ liệu nếu không bạn sẽ mất tính toàn vẹn của cơ sở dữ liệu.
HLGEM

Đối với trường hợp có nhiều ứng dụng, việc đặt logic vào thư viện được sử dụng bởi tất cả các ứng dụng cho phép duy trì tính toàn vẹn trong khi vẫn giữ logic trong ngôn ngữ ứng dụng. Đối với nhập khẩu / truy cập trực tiếp, thông thường tình huống là liệu các quy tắc áp dụng cho ứng dụng có nên được thi hành hay không.
Dave Sherohman

3
nhiều ứng dụng không nên thực hiện cùng một loại thay đổi đối với cơ sở dữ liệu. nên có một thành phần ứng dụng liên quan đến một loại thay đổi. Sau đó, ứng dụng đó sẽ hiển thị một dịch vụ nếu những người khác quan tâm. Nhiều ứng dụng thay đổi cùng một cơ sở dữ liệu / bảng theo bất kỳ cách nào chúng thấy phù hợp là nguyên nhân khiến một hệ thống ứng dụng và cơ sở dữ liệu trở nên không thể nhầm lẫn.
Jiho Han

2
"Cần có một thành phần ứng dụng xử lý một loại thay đổi" - Thành phần đó có thể là một thủ tục được lưu trữ, giả sử trong PL / SQL.
RussellH

6

Khi nói đến bảo mật, các thủ tục lưu trữ an toàn hơn nhiều. Một số người đã lập luận rằng tất cả quyền truy cập sẽ thông qua ứng dụng này. Điều mà nhiều người đang quên là hầu hết các vi phạm an ninh đến từ bên trong một công ty. Hãy suy nghĩ về việc có bao nhiêu nhà phát triển biết tên người dùng và mật khẩu "ẩn" cho ứng dụng của bạn?

Ngoài ra, như MatthieuF đã chỉ ra, hiệu suất có thể được cải thiện nhiều do có ít chuyến đi khứ hồi giữa ứng dụng (cho dù đó là trên máy tính để bàn hay máy chủ web) và máy chủ cơ sở dữ liệu.

Theo kinh nghiệm của tôi, sự trừu tượng của mô hình dữ liệu thông qua các thủ tục được lưu trữ cũng giúp cải thiện đáng kể khả năng bảo trì. Là một người đã phải duy trì nhiều cơ sở dữ liệu trong quá khứ, thật nhẹ nhõm khi phải đối mặt với thay đổi mô hình bắt buộc để có thể thay đổi một hoặc hai thủ tục được lưu trữ và thay đổi hoàn toàn trong suốt đối với TẤT CẢ các ứng dụng bên ngoài. Nhiều lần ứng dụng của bạn không phải là ứng dụng duy nhất chỉ vào cơ sở dữ liệu - có các ứng dụng khác, giải pháp báo cáo, v.v. vì vậy việc theo dõi tất cả các điểm bị ảnh hưởng đó có thể gây rắc rối với việc truy cập mở vào các bảng.

Tôi cũng sẽ đặt các kiểm tra vào cột cộng để đặt chương trình SQL vào tay những người chuyên về nó và cho các SP giúp việc cách ly và kiểm tra / tối ưu hóa mã dễ dàng hơn nhiều.

Một nhược điểm mà tôi thấy là nhiều ngôn ngữ không cho phép truyền tham số bảng, do đó, việc truyền một giá trị dữ liệu số không xác định có thể gây khó chịu và một số ngôn ngữ vẫn không thể xử lý truy xuất nhiều kết quả từ một thủ tục được lưu trữ (mặc dù sau này không làm cho SP trở nên tồi tệ hơn SQL nội tuyến về mặt đó).


Khi mô hình thay đổi, thông thường mã cũng cần thay đổi bất kể người ta đang sử dụng sprocs hay sql động. Và một khi bạn tạo bảng / lược đồ, bạn có thường xuyên thay đổi bảng / lược đồ không? Không thường xuyên. Thông thường các thay đổi đến từ doanh nghiệp nơi họ cần thêm một cột khác hoặc một bảng khác, trong trường hợp đó, tôi nghi ngờ bạn có thể làm mà không cần thay đổi mã.
Jiho Han

4

Một trong những gợi ý từ các phiên Microsoft TechEd về bảo mật mà tôi đã tham dự, để thực hiện tất cả các cuộc gọi thông qua các procs được lưu trữ và từ chối truy cập trực tiếp vào các bảng. Cách tiếp cận này được lập hóa đơn là cung cấp bảo mật bổ sung. Tôi không chắc liệu nó có đáng để bảo mật hay không, nhưng nếu bạn đã sử dụng các procs được lưu trữ, điều đó không thể làm tổn thương.


Bảo mật dữ liệu rất quan trọng khi bạn sử dụng thông tin cá nhân hoặc thông tin tài chính đặc biệt. Hầu hết các gian lận được cam kết bởi người trong cuộc. Bạn không muốn cung cấp cho họ quyền truy cập mà họ cần để vượt qua kiểm soát nội bộ.
HLGEM

4

Chắc chắn dễ dàng hơn để duy trì nếu bạn đặt nó trong một thủ tục được lưu trữ. Nếu có logic khó liên quan sẽ có khả năng thay đổi trong tương lai, thì chắc chắn nên đưa nó vào cơ sở dữ liệu khi bạn có nhiều máy khách kết nối. Ví dụ: tôi đang làm việc trên một ứng dụng ngay bây giờ có giao diện web của người dùng cuối và ứng dụng máy tính để bàn quản trị, cả hai đều chia sẻ cơ sở dữ liệu (rõ ràng) và tôi đang cố gắng giữ càng nhiều logic trên cơ sở dữ liệu càng tốt. Đây là một ví dụ hoàn hảo về nguyên tắc DRY .


4

Tôi chắc chắn đứng về phía các procs được lưu trữ với giả định rằng bạn không gian lận và sử dụng SQL động trong Proc được lưu trữ. Đầu tiên, sử dụng procs được lưu trữ cho phép dba đặt quyền ở cấp độ Proc được lưu trữ chứ không phải cấp độ bảng. Điều này là rất quan trọng không chỉ để chống lại các hành vi tiêm SQL mà còn hướng tới việc ngăn người trong cuộc truy cập trực tiếp vào cơ sở dữ liệu và thay đổi mọi thứ. Đây là một cách để giúp ngăn chặn gian lận. Không có cơ sở dữ liệu nào chứa thông tin cá nhân (SSN, số thẻ tín dụng, v.v.) hoặc bằng mọi cách tạo ra các giao dịch tài chính nên được truy cập ngoại trừ thông qua các thủ tục phân tầng. Nếu bạn sử dụng bất kỳ phương pháp nào khác, bạn sẽ để cơ sở dữ liệu của mình mở rộng cho các cá nhân trong công ty để tạo các giao dịch tài chính giả hoặc đánh cắp dữ liệu có thể được sử dụng để đánh cắp danh tính.

Các procs được lưu trữ cũng dễ dàng duy trì và điều chỉnh hiệu suất hơn nhiều so với SQL được gửi từ ứng dụng. Họ cũng cho phép dba một cách để xem tác động của thay đổi cấu trúc cơ sở dữ liệu sẽ ảnh hưởng đến cách truy cập dữ liệu. Tôi chưa bao giờ gặp một dba tốt, người sẽ cho phép truy cập động vào cơ sở dữ liệu.


4

Chúng tôi sử dụng các thủ tục được lưu trữ với Oracle DB, nơi tôi làm việc bây giờ. Chúng tôi cũng sử dụng Subversion. Tất cả các thủ tục được lưu trữ được tạo dưới dạng tệp .pkb & .pks và được lưu trong Subversion. Tôi đã thực hiện SQL nội tuyến trước đây và đó là một nỗi đau! Tôi rất thích cách chúng tôi làm điều đó ở đây. Tạo và thử nghiệm các thủ tục lưu trữ mới dễ dàng hơn nhiều so với thực hiện trong mã của bạn.

Có một


3

Nhật ký nhỏ hơn

Một pro nhỏ khác cho các thủ tục được lưu trữ chưa được đề cập: khi nói đến lưu lượng SQL, truy cập dữ liệu dựa trên sp tạo ra lưu lượng truy cập ít hơn nhiều . Điều này trở nên quan trọng khi bạn giám sát lưu lượng để phân tích và định hình - nhật ký sẽ nhỏ hơn và dễ đọc hơn nhiều.


3

Tôi không phải là một fan hâm mộ lớn của các thủ tục được lưu trữ, nhưng tôi sử dụng chúng trong một điều kiện:

Khi truy vấn khá lớn, tốt hơn là lưu trữ nó trong cơ sở dữ liệu dưới dạng một thủ tục được lưu trữ thay vì gửi nó từ mã. Theo cách đó, thay vì gửi một lượng lớn ký tự chuỗi từ máy chủ ứng dụng đến cơ sở dữ liệu, chỉ có"EXEC SPNAME" lệnh sẽ được gửi.

Điều này là quá mức khi máy chủ cơ sở dữ liệu và máy chủ web không nằm trên cùng một mạng (Ví dụ: giao tiếp internet). Và ngay cả khi đó không phải là trường hợp, quá nhiều căng thẳng có nghĩa là rất nhiều băng thông lãng phí.

Nhưng bạn ơi, chúng thật tồi tệ để quản lý. Tôi tránh chúng nhiều nhất có thể.


3

Một Proc lưu trữ SQL không làm tăng hiệu năng của truy vấn


Làm thế nào nó có thể không? Hãy giải thích về điều này.
Sandesh

Nó sẽ tăng hiệu suất nếu truy vấn SQL có thể được biên dịch.
TT.

3

Rõ ràng việc sử dụng các thủ tục được lưu trữ có một số lợi thế so với việc xây dựng SQL trong mã.

  1. Việc triển khai mã của bạn và SQL trở nên độc lập với nhau.
  2. Mã dễ đọc hơn.
  3. Viết một lần sử dụng nhiều lần.
  4. Sửa đổi một lần
  5. Không cần phải cung cấp chi tiết nội bộ cho các lập trình viên về cơ sở dữ liệu. Vân vân.

Tôi chưa bao giờ ở trong tình huống có ít thông tin về vấn đề mã hoặc tính năng mới có lợi cho tôi, bạn có thể làm rõ số 5 không?
OpenCoderX

2

Thủ tục lưu trữ có thể duy trì THÊM vì:

  • Bạn không phải biên dịch lại ứng dụng C # của mình bất cứ khi nào bạn muốn thay đổi một số SQL
  • Bạn cuối cùng sử dụng lại mã SQL.

Mã lặp lại là tồi tệ nhất điều nhất bạn có thể làm khi bạn đang cố gắng xây dựng một ứng dụng có thể bảo trì!

Điều gì xảy ra khi bạn tìm thấy một lỗi logic cần được sửa chữa ở nhiều nơi? Bạn có nhiều khả năng quên thay đổi vị trí cuối cùng nơi bạn sao chép và dán mã của mình.

Theo tôi, hiệu suất và bảo mật đạt được là một điểm cộng bổ sung. Bạn vẫn có thể viết các thủ tục lưu trữ SQL không an toàn / không hiệu quả.

Dễ dàng chuyển sang DB khác - không có procs sang cổng

Không khó để viết ra tất cả các thủ tục được lưu trữ của bạn để tạo trong một DB khác. Trên thực tế - việc xuất bảng của bạn dễ dàng hơn vì không phải lo lắng về khóa chính / khóa ngoại.


Chỉ cần một lưu ý: "Dễ dàng chuyển sang DB khác - không có procs sang cổng" được gọi là chuyển sang DBMS khác , không chỉ là cài đặt khác. Có những lựa chọn thay thế ngoài kia, bạn biết đấy ;-).
sleske

2

@Terrapin - sprocs cũng dễ bị tấn công tiêm chích. Như tôi đã nói:

Luôn luôn tham gia tất cả các truy vấn - không bao giờ nội tuyến gì đó từ đầu vào của người dùng và bạn sẽ ổn.

Điều đó đi cho sprocs và Sql động.

Tôi không chắc chắn không biên dịch lại ứng dụng của bạn là một lợi thế. Ý tôi là, bạn đã chạy thử nghiệm đơn vị của mình đối với mã đó (cả ứng dụng và DB) trước khi tiếp tục hoạt động trở lại.


@Guy - vâng, bạn đúng, sprocs cho phép bạn kiểm soát người dùng ứng dụng để họ chỉ có thể thực hiện sproc chứ không phải hành động cơ bản.

Câu hỏi của tôi sẽ là: nếu tất cả quyền truy cập thông qua ứng dụng của bạn, sử dụng kết nối và người dùng có quyền hạn chế để cập nhật / chèn, v.v., mức bổ sung này có thêm bảo mật hay quản trị bổ sung không?

Ý kiến ​​của tôi là rất nhiều sau này. Nếu họ đã xâm phạm ứng dụng của bạn đến mức họ có thể viết lại thì họ có rất nhiều cuộc tấn công khác mà họ có thể sử dụng.

Việc tiêm Sql vẫn có thể được thực hiện đối với các sprocs đó nếu chúng tự động mã nội tuyến, do đó, quy tắc vàng vẫn được áp dụng, tất cả đầu vào của người dùng phải luôn được tham số hóa.


Nó không chỉ là bên ngoài tấn công bạn cần phải chiến đấu. Bạn không thể cho phép truy cập trực tiếp vào các bảng cho người dùng sau đó có thể thay đổi dữ liệu để thực hiện hành vi gian lận.
HLGEM

NHƯ một chính sách, các procs được lưu trữ không được phép sử dụng sql động, hầu như luôn luôn có một giải pháp không động nếu bạn tìm kiếm nó.
HLGEM

SQL tiêm không hiệu quả đối với các sprocs với mã được đặt động bởi vì mã động thực thi với sự cho phép của người gọi, không phải là quyền của chủ sở hữu (không giống như mã tĩnh). Điều này đúng với SQL Server - không chắc chắn về Oracle.
HTTP 410

2

Một điều mà tôi chưa từng thấy đề cập đến cho đến nay: những người hiểu rõ nhất về cơ sở dữ liệu không phải luôn là những người viết mã ứng dụng. Các thủ tục được lưu trữ cung cấp cho người cơ sở dữ liệu một cách để giao tiếp với các lập trình viên không thực sự muốn tìm hiểu nhiều về SQL. Cơ sở dữ liệu lớn - và đặc biệt là di sản - không phải là điều dễ hiểu nhất, vì vậy các lập trình viên có thể chỉ thích một giao diện đơn giản cung cấp cho họ những gì họ cần: hãy để các DBA tìm ra cách tham gia 17 bảng để thực hiện điều đó.

Điều đó đang được nói, các ngôn ngữ được sử dụng để viết các thủ tục được lưu trữ (PL / SQL là một ví dụ khét tiếng) là khá tàn bạo. Họ thường không cung cấp bất kỳ loại mỹ phẩm nào bạn thấy trong các ngôn ngữ chức năng phổ biến hiện nay, OOP hoặc chức năng. Hãy suy nghĩ về COBOL.

Vì vậy, hãy tuân thủ các thủ tục được lưu trữ chỉ đơn thuần là trừu tượng hóa các chi tiết quan hệ hơn là các quy trình có chứa logic kinh doanh.


"Các ngôn ngữ được sử dụng để viết các thủ tục được lưu trữ (PL / SQL là một ví dụ khét tiếng) khá tàn bạo [và] không cung cấp bất kỳ tính năng nào bạn thấy trong các ngôn ngữ phổ biến hiện nay." Bạn cần đọc lại các tài liệu PL / SQL ( download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/toc.htm ). PL / SQL đã đóng gói bằng cách sử dụng các gói, OOP thông qua các loại đối tượng, xử lý ngoại lệ, thực thi mã động, trình gỡ lỗi, trình lược tả, v.v., cùng với hàng trăm gói / thư viện do Oracle cung cấp để thực hiện mọi thứ từ các cuộc gọi HTTP đến mã hóa và các biểu thức thông thường . PL / SQL có RẤT NHIỀU niceties.
ObiWanKenobi

2

Tôi thường viết mã OO. Tôi nghi ngờ rằng hầu hết các bạn có thể làm quá. Trong bối cảnh đó, dường như rõ ràng với tôi rằng tất cả logic nghiệp vụ - bao gồm các truy vấn SQL - thuộc về các định nghĩa lớp. Việc tách logic sao cho một phần của nó nằm trong mô hình đối tượng và một phần trong cơ sở dữ liệu không tốt hơn việc đưa logic nghiệp vụ vào giao diện người dùng.

Phần lớn đã được nói trong các câu trả lời trước đó về lợi ích bảo mật của các procs được lưu trữ. Chúng thuộc hai loại lớn:

1) Hạn chế truy cập trực tiếp vào dữ liệu. Điều này chắc chắn là quan trọng trong một số trường hợp và, khi bạn gặp phải một, thì các procs được lưu trữ là khá nhiều lựa chọn duy nhất của bạn. Theo kinh nghiệm của tôi, những trường hợp như vậy là ngoại lệ chứ không phải là quy tắc.

2) SQL truy vấn / truy vấn tham số. Sự phản đối này là một cá trích đỏ. SQL nội tuyến - ngay cả SQL nội tuyến được tạo động - có thể được tham số hóa hoàn toàn như bất kỳ Proc được lưu trữ nào và nó có thể được thực hiện dễ dàng như trong bất kỳ ngôn ngữ hiện đại nào có giá trị. Không có lợi thế nào ở đây. ("Các nhà phát triển lười biếng có thể không bận tâm đến việc sử dụng các tham số" không phải là một sự phản đối hợp lệ. Nếu bạn có các nhà phát triển trong nhóm của mình, người chỉ muốn nối dữ liệu người dùng vào SQL của họ thay vì sử dụng các tham số, trước tiên bạn hãy cố gắng giáo dục họ, sau đó bạn kích hoạt chúng nếu điều đó không hiệu quả, giống như bạn làm với các nhà phát triển có bất kỳ thói quen bất lợi, xấu xa nào khác.)


2

Tôi là một người ủng hộ mã rất lớn đối với XUÂN. Lý do số một là giữ cho mã được liên kết chặt chẽ, sau đó một giây là việc kiểm soát nguồn dễ dàng mà không có nhiều tiện ích tùy chỉnh để kéo mã vào.

Trong DAL của chúng tôi nếu chúng tôi có các câu lệnh SQL rất phức tạp, chúng tôi thường bao gồm chúng dưới dạng các tệp tài nguyên và cập nhật chúng khi cần thiết (đây cũng có thể là một tập hợp riêng biệt và được hoán đổi trên mỗi db, v.v.).

Điều này giữ cho mã của chúng tôi và các cuộc gọi sql của chúng tôi được lưu trữ trong cùng một điều khiển phiên bản, mà không "quên" chạy một số ứng dụng bên ngoài để cập nhật.


Còn khi bạn "quên" sao chép các thay đổi vào bảng thì sao?
craigmoliver

Quá trình có thể giải quyết các vấn đề triển khai.
Tom Anderson
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.