Việc lưu các câu lệnh SQL trong một bảng để thực hiện sau này có phải là một ý tưởng tồi không?


21

Việc lưu các câu lệnh SQL trong bảng MySQL để thực hiện sau này có phải là một ý tưởng tồi không? Các câu lệnh SQL sẽ sẵn sàng để thực thi, ví dụ, sẽ không có tham số để trao đổi hoặc bất cứ điều gì, ví dụ DELETE FROM users WHERE id=1.

Tôi đoán tôi đang lười biếng, nhưng tôi đã nghĩ ra ý tưởng này bởi vì tôi đang làm việc trong một dự án sẽ yêu cầu khá nhiều công việc định kỳ sẽ thực thi các câu lệnh SQL theo định kỳ.


Bạn nên làm rõ nếu bạn có ý định chạy các câu lệnh SQL này một lần hoặc nếu bạn muốn chạy cùng một tập hợp các câu lệnh.
GrandmasterB

10
Toàn bộ câu hỏi này có vẻ như là một trong những tình huống mà cách tiếp cận cơ bản là sai. Nhưng thật khó để nói chính xác điều gì vì chúng ta biết rất ít về không gian vấn đề.
Erick Robertson

Câu trả lời:


46

Nó an toàn, nếu đó là những gì bạn đang hỏi. Miễn là bạn cẩn thận về bảo mật của mình cũng như bảo mật dữ liệu của bạn.

Nhưng không phát minh lại bánh xe, Các thủ tục được lưu trữ là các bit SQL được lưu trữ trong một bảng. Và họ hỗ trợ, nay khuyến khích, tham số hóa.

Cũng lưu ý, bạn có thể làm cho bảo mật của mình đơn giản hơn VÀ giảm số lượng điểm lỗi VÀ giảm truyền thông mạng bằng cách sử dụng Bộ lập lịch sự kiện MySql thay vì cron.

Các cơ sở dữ liệu khác có tương đương với những điều này, vì lý do tốt. Bạn không phải là người đầu tiên cần chức năng này.


1
+1 khi sử dụng bộ lập lịch. Giới hạn quyền truy cập của người lập lịch chỉ vào các procs tốt hơn truy cập bảng.
JeffO

Nhưng nếu bạn cần tự động tạo các truy vấn này, hãy nói từ UI? Chẳng hạn, nếu bạn cho phép người dùng quản trị tự động đặt quy tắc truy cập trên nội dung web dựa trên các truy vấn phức tạp. Bạn sẽ không muốn UI tạo một Proc mới trong cơ sở dữ liệu. Tôi nghĩ rằng trong một số trường hợp, Stored Queries tốt hơn procs.
Đệ

32

Nếu bạn muốn lưu các câu lệnh SQL trong cơ sở dữ liệu để thực hiện sau này, có một tùy chọn tốt hơn là đặt chúng vào một bảng: sử dụng chức năng tích hợp được cung cấp cho mục đích cụ thể này. Đặt chúng trong các thủ tục lưu trữ.


2
Vì vậy, nơi cron job lưu trữ danh sách các thủ tục được lưu trữ để chạy?
JeffO

1
điều này có thể hữu ích stackoverflow.com/questions/6560639/ Mặc dù nó không sử dụng cron
MetaFight

Không biết tôi đang nghĩ gì. Một danh sách các procs đều có thể được thực thi từ một Proc, vì vậy công việc cron chỉ cần thực thi một.
JeffO

11

Không, tôi sẽ nói nó không phải là một ý tưởng tốt.

Điều đó có nghĩa là mỗi truy vấn / cập nhật "thực" sẽ cần 2 lần truy cập vào cơ sở dữ liệu - một truy vấn để có được truy vấn / cập nhật "thực" và một truy vấn để thực hiện.

Đây có thể không phải là một vấn đề lớn trong một hệ thống nhỏ, nhưng càng nhiều người dùng / giao dịch mà hệ thống của bạn nhận được, nó sẽ càng giảm quy mô.

Tôi đoán điều này xuất phát từ việc tìm kiếm một giải pháp thay thế để nhúng SQL vào mã của bạn?

Đóng gói SQL trong một thủ tục được lưu trữ như Mason Wheeler đề xuất, sẽ là một cách tốt hơn nhiều so với ý tưởng này.


+1, đây là lý do chính tại sao giải pháp của @Mason Wheeler là giải pháp chính xác - anh ta chỉ bỏ lỡ để làm nổi bật điều đó. Mặc dù IMHO không phải là vấn đề hiệu năng mà tôi thấy ở đây quan trọng nhất - không cần phải phức tạp hóa mọi thứ bằng cách trích xuất một câu lệnh SQL từ DB và gửi lại để thực hiện sau đó.
Doc Brown

Tại sao danh sách các câu lệnh sql phải được lưu trữ trong cùng một cơ sở dữ liệu / máy chủ, v.v?
JeffO

1
OP là một đề xuất 2 lần truy cập vào cơ sở dữ liệu. Tôi nói anh ấy không nên làm điều đó. Sau đó, bạn hỏi tại sao nó phải là cùng một cơ sở dữ liệu / máy chủ. Tôi hỏi ai nói nó đã làm? sau đó bạn hỏi làm thế nào khác để bạn nhận được 2 lượt truy cập trên DB. Tại sao bạn không nêu câu hỏi thực tế của bạn thay vì bất cứ điều gì bạn đang làm?
ozz

1
@JeffO Ngay cả khi đó là một cơ sở dữ liệu khác nhau, nó vẫn là 2 truy vấn cơ sở dữ liệu cho 1 truy vấn, đó là sự chậm lại không cần thiết
Izkata

1
@Ozz: bạn cho quá nhiều khía cạnh hiệu suất của câu trả lời của bạn - hiệu suất có thể bị bỏ qua trong hầu hết các tình huống trong thế giới thực. Nhưng sự cần thiết phải có hai hành động (lần đầu tiên để có được truy vấn / cập nhật "thực", lần thứ hai để thực hiện nó) làm cho mọi thứ trở nên phức tạp hơn mức cần thiết.
Doc Brown

4

Xin lỗi, tôi không nghĩ rằng đó là một ý tưởng tốt.

Xem xét trường hợp bảng trong câu hỏi thay đổi. Giả sử cột id của bạn được đổi tên thành new_id .

Cũng như sự thay đổi, có một phiên bản mã của bạn được viết cho một kiểu cũ của cơ sở dữ liệu có thể không còn chạy được nữa. Chắc chắn, bạn có thể biết để kiểm tra trong bảng mã nhưng nó không rõ ràng ngay lập tức đối với người khác.

Để thay đổi như tôi đã mô tả, tôi thường xem xét các tệp SQL độc lập, quy trình được lưu trữ, trình kích hoạt, SQL nội tuyến trong mã máy khách (VB, C #, C ++, v.v.) nhưng là nơi cuối cùng tôi nghĩ sẽ tìm là trong các bảng cơ sở dữ liệu. Mặc dù có lẽ tôi sẽ bây giờ! :)


2

Có những lý do hợp lệ để lưu trữ SQL trong một bảng. Phần mềm tôi làm việc cùng lúc này bao gồm một hệ thống để tạo tài liệu và các tài liệu cần bao gồm các tính toán khá phức tạp sử dụng dữ liệu trong cơ sở dữ liệu. Các tài liệu được cập nhật thường xuyên, thường khác nhau đáng kể về mặt dữ liệu cần thiết và các tính toán cần được thực hiện. Về cơ bản, SQL đang được sử dụng như một ngôn ngữ kịch bản để thực hiện các tính toán này và SQL được lưu trữ trong các bảng cũng lưu trữ thông tin khác cho các tài liệu này. Những người duy trì các tài liệu đó không phải là lập trình viên hoặc DBA, nhưng họ quen thuộc với lược đồ cơ sở dữ liệu và họ thành thạo SQL. Sẽ là chi phí đáng kể để họ duy trì mã SQL đó dưới dạng các thủ tục được lưu trữ.

Đối với những gì bạn đã mô tả - "... một dự án sẽ yêu cầu khá nhiều công việc định kỳ sẽ thực thi các câu lệnh SQL theo định kỳ" - các câu trả lời khác có thể đúng khi đề xuất rằng bạn đã sử dụng các thủ tục lưu trữ, hoặc tương đương, cho DBMS mà bạn ' đang sử dụng.

Một tiêu chí tốt để quyết định xem việc lưu trữ SQL trong bảng có hợp lý hay không trong quy trình được lưu trữ là xác định ai sẽ duy trì SQL đó. Nếu người dùng duy trì SQL đó, tức là họ viết nó và thay đổi nó bất cứ khi nào họ muốn, thì điều đó có thể hoàn toàn tốt, và thực sự tốt nhất, để lưu trữ SQL đó trong một bảng. Nếu các nhà phát triển sẽ duy trì SQL đó, thì nó nên được lưu trữ ở dạng có thể được cập nhật bởi các thủ tục xây dựng và triển khai (hy vọng tự động) của bạn, ví dụ được lưu trữ dưới dạng một đối tượng như một thủ tục được lưu trữ trong chính cơ sở dữ liệu.


1
Cảm ơn bạn đã trả lời. Tôi đã kết thúc bằng cách sử dụng các sự kiện MySQL để lên lịch các truy vấn để chạy. Khá nhiều người nghĩ rằng "cách tiếp cận cơ bản là sai" :) khi tất cả những gì tôi cần là chạy một vài câu lệnh SQL sau 15 phút từ một hành động người dùng cụ thể.
Amged Rustom

2
@AmgadSuliman - điều quan trọng là phải làm từ thiện cho mọi người, đặc biệt là trên các trang web SE. Thật tốt khi có những ý kiến ​​mạnh mẽ, nhưng quá dễ dàng để phù hợp với các mẫu mà chúng ta thích tìm hiểu. Nhưng một phần của việc từ thiện cho những người khác trên các trang này là cung cấp đủ bối cảnh; quá nhiều có thể che khuất câu hỏi thực sự, nhưng nhìn chung điều đó khá dễ khắc phục bằng cách chỉnh sửa tiếp theo.
Kenny Evitt

1

Cách dễ dàng là có một tệp .ini hoặc tệp hương vị cấu hình khác để giữ các truy vấn. Cách này bạn có thể đặt chúng ở một nơi, thay đổi bất cứ điều gì mà không phải truy cập cơ sở dữ liệu để làm như vậy, không phải truy cập cơ sở dữ liệu nhiều lần và đôi khi bạn có thể muốn / cần sử dụng các tham số hoặc thêm điều kiện vào các truy vấn của mình (tăng chúng bằng các công cụ phức tạp hơn cho một trường hợp cụ thể trong mã của bạn).

Tất nhiên, bạn có thể giữ chúng ở mức cơ sở dữ liệu (trong bảng hoặc tốt hơn là các thủ tục được lưu trữ), tuy nhiên nếu bạn lười như tôi ;-) nhưng cũng quan tâm đến hiệu suất, tệp .ini và PHP Phương pháp parse_ini yêu thích để đọc nó, là cách để đi (nếu bạn đang tìm một ngôn ngữ lập trình khác, bạn sẽ tự mình tìm ra cách tiếp cận tương tự)! Thông thường tôi sẽ đọc tệp này trong bộ tải khởi động của ứng dụng và giữ nó trong một đối tượng tĩnh (có thể có lớp bộ đệm ở trên cùng) để thực sự tăng tốc mọi thứ nếu chúng ta đang nói về một số lượng lớn các truy vấn riêng biệt.


1

Nếu bạn chỉ cần câu lệnh SQL một lần, ví dụ, nếu bạn đang xếp hàng một loạt các hoạt động để thực hiện trong giờ làm việc, thì có, đặt chúng vào một bảng sẽ hoạt động tốt.

Nếu bạn cần thực thi cùng một câu lệnh SQL theo các khoảng thời gian được chỉ định, thì tuyến thủ tục được lưu trữ mà những người khác đã đề cập có thể là lựa chọn tốt hơn cho bạn.

Điều đó nói rằng, những gì bạn đang hỏi về khá bất thường, và có thể là một dấu hiệu của một số vấn đề khác. Ví dụ: nếu bạn đang chờ xóa người dùng khỏi cơ sở dữ liệu, có thể tốt hơn để gọi một tập lệnh được lên lịch thực hiện thao tác thông qua mã ứng dụng của bạn, thay vì ghi lại các câu lệnh SQL thực tế. Bằng cách này, SQL và mã không bao giờ không đồng bộ.

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.