2008-11-10 20 views
5

Truy vấn "tĩnh" là truy vấn vẫn giữ nguyên ở mọi thời điểm. Ví dụ: nút "Thẻ" trên Stackoverflow hoặc nút "7 ngày" trên Digg. Trong ngắn hạn, họ luôn luôn ánh xạ tới một truy vấn cơ sở dữ liệu cụ thể, vì vậy bạn có thể tạo chúng tại thời điểm thiết kế.Cách tạo truy vấn động và an toàn

Nhưng tôi đang cố gắng tìm ra cách thực hiện các truy vấn "động" trong đó người dùng về cơ bản quyết định cách truy vấn cơ sở dữ liệu sẽ được tạo khi chạy. Ví dụ, trên Stackoverflow, bạn có thể kết hợp các thẻ và lọc các bài viết theo những cách bạn chọn. Đó là một truy vấn động mặc dù một truy vấn rất đơn giản vì những gì bạn có thể kết hợp nằm trong thế giới của các thẻ. Một ví dụ phức tạp hơn là nếu bạn có thể kết hợp các thẻ và người dùng. Trước hết, khi bạn có truy vấn động, có vẻ như bạn không thể sử dụng api thay thế để tránh phun sql vì các phần tử truy vấn sẽ phụ thuộc vào những gì người dùng quyết định đưa vào truy vấn. Tôi không thể thấy cách khác để xây dựng truy vấn này ngoài việc sử dụng chuỗi chắp thêm.

Thứ hai, truy vấn có khả năng mở rộng nhiều bảng. Ví dụ: nếu SO cho phép người dùng lọc dựa trên Người dùng và Thẻ, và những điều này có thể sống trong hai bảng khác nhau, việc xây dựng truy vấn sẽ phức tạp hơn một chút so với chỉ thêm cột và mệnh đề WHERE.

Tôi làm cách nào để thực hiện điều gì đó như thế này?

+0

Để đề xuất tóm tắt: Bạn đang sử dụng ngôn ngữ nào để nói chuyện với cơ sở dữ liệu của mình? Bạn đang sử dụng cơ sở dữ liệu nào? –

+0

Cơ sở dữ liệu của bạn rất quan trọng. RDBMS nào? Thứ hai, bạn có sẵn sàng giới hạn không. Bạn có muốn nói rằng bạn chỉ có thể tìm kiếm trên 10 thẻ ... 11 là verboten? –

Trả lời

0

Vâng, các tùy chọn phải ánh xạ tới thứ gì đó.

Chuỗi truy vấn SQL CONCAT không phải là vấn đề nếu bạn vẫn sử dụng thông số cho các tùy chọn.

2

Quy tắc đầu tiên là người dùng được phép chỉ định giá trị trong các biểu thức SQL, nhưng không phải cú pháp SQL . Tất cả cú pháp truy vấn phải được chỉ định theo nghĩa đen bởi mã của bạn, không phải do người dùng nhập. Các giá trị mà người dùng chỉ định có thể được cung cấp cho SQL dưới dạng tham số truy vấn. Đây là cách hiệu quả nhất để hạn chế nguy cơ tiêm SQL.

Nhiều ứng dụng cần "xây dựng" các truy vấn SQL thông qua mã, vì khi bạn chỉ ra, một số biểu thức, kết nối bảng, sắp xếp theo tiêu chí, vv tùy thuộc vào lựa chọn của người dùng. Khi bạn xây dựng một phần truy vấn SQL theo từng mảnh, đôi khi rất khó đảm bảo rằng kết quả là cú pháp SQL hợp lệ.

Tôi đã làm việc trên một lớp PHP có tên là Zend_Db_Select cung cấp API để trợ giúp việc này. Nếu bạn thích PHP, bạn có thể xem mã đó để biết các ý tưởng. Nó không xử lý bất kỳ truy vấn nào có thể tưởng tượng được, nhưng nó thực hiện rất nhiều.

Một số khung công tác cơ sở dữ liệu PHP khác có các giải pháp tương tự.

1

Mặc dù không phải là giải pháp chung, dưới đây là một số bước bạn có thể thực hiện để giảm thiểu vấn đề truy vấn động nhưng chưa an toàn.

Tiêu chí trong đó giá trị cột nằm trong tập hợp các giá trị có số lượng thẻ là tùy ý không cần phải động. Cân nhắc sử dụng hàm instr hoặc sử dụng bảng lọc đặc biệt mà bạn tham gia. Cách tiếp cận này có thể dễ dàng mở rộng đến nhiều cột miễn là số cột được biết. Lọc trên người dùng và thẻ có thể dễ dàng được xử lý bằng cách tiếp cận này.

Khi số cột trong tiêu chí lọc tùy ý nhưng nhỏ, hãy xem xét sử dụng các truy vấn tĩnh khác nhau cho từng khả năng.

Chỉ khi số cột trong tiêu chí lọc là tùy ý và có khả năng lớn, bạn nên xem xét sử dụng truy vấn động. Trong trường hợp này ...

Để được an toàn khỏi việc tiêm SQL, hãy xây dựng hoặc lấy một thư viện bảo vệ chống lại cuộc tấn công đó. Mặc dù khó khăn hơn, đây không phải là một nhiệm vụ không thể. Điều này chủ yếu là về việc thoát khỏi các dấu phân tách chuỗi SQL trong các giá trị cần lọc.

Để được an toàn khỏi các truy vấn tốn kém, hãy xem xét sử dụng chế độ xem được tạo đặc biệt cho mục đích này và một số logic phía trước để giới hạn cách những lượt xem đó sẽ được gọi. Đây là thách thức lớn nhất về thời gian và nỗ lực của nhà phát triển.

0

Nếu bạn đang sử dụng python để truy cập cơ sở dữ liệu của mình, tôi khuyên bạn nên sử dụng Django model system. Có rất nhiều apis tương tự cho cả python và các ngôn ngữ khác (đáng chú ý là ruby ​​trên ray). Tôi tiết kiệm rất nhiều thời gian bằng cách tránh sự cần thiết phải nói chuyện trực tiếp với cơ sở dữ liệu với SQL.

Từ the example link:

#Model definition 
class Blog(models.Model): 
    name = models.CharField(max_length=100) 
    tagline = models.TextField() 

    def __unicode__(self): 
     return self.name 

sử dụng Model (đây là một cách hiệu quả một tuyên bố chèn)

from mysite.blog.models import Blog 
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') 
b.save() 

Các truy vấn trở nên phức tạp hơn nhiều - bạn vượt qua xung quanh một đối tượng truy vấn và bạn có thể thêm các bộ lọc/sắp xếp các yếu tố cho nó. Khi bạn cuối cùng đã sẵn sàng để sử dụng truy vấn, Django tạo ra một câu lệnh SQL phản ánh tất cả các cách bạn điều chỉnh đối tượng truy vấn. Tôi nghĩ rằng nó rất dễ thương.

lợi thế khác của trừu tượng này

  • Mô hình của bạn có thể được tạo ra như là bảng cơ sở dữ liệu với các phím nước ngoài và hạn chế bởi Django
  • Nhiều cơ sở dữ liệu được hỗ trợ (PostgreSQL, MySQL, SQL Lite, vv)
  • DJango phân tích các mẫu của bạn và tạo ra automatic admin site trong số chúng.
Các vấn đề liên quan