2011-02-10 29 views
8

Tôi đang cố gắng hiểu lợi ích của việc xây dựng SQL thông qua một DSL xây dựng hướng đối tượng và tham số hóa chuỗi SQL thô. Sau khi nghiên cứu/thực hiện cùng một truy vấn theo ba cách, tôi nhận thấy rằng SQL thô là dễ đọc nhất. Điều này đặt ra câu hỏi, "tại sao nhảy qua một vòng?" Tại sao không chỉ khai báo và sử dụng SQL thô?Tại sao sử dụng trình tạo SQL? Arel v. Phần tiếp theo v. T-SQL

Đây là những gì tôi đã đi lên:

Trước tiên, tôi đoán nó làm cho SQL cầm tay hơn vì nó sau đó có thể được sử dụng bởi bất kỳ DB với một adapter. Tôi đoán đây là biggie, phải không? Tuy nhiên, không phải là hầu hết T-SQL dễ hiểu đối với hầu hết các cơ sở dữ liệu?

Thứ hai, nó cung cấp một đối tượng truy vấn có thể được tái sử dụng - làm cơ sở cho các truy vấn khác, tên-phạm vi chaining vv

sự trở lại chính về đầu tư bạn nhận ra bằng cách xây dựng SQL của bạn thay vì tuyên bố là gì nó?

def instances_of_sql(ttype_id) #raw sql 
    ttype_id = get(ttype_id).try(:id) 
    ti = get('tmdm:type-instance') 
    inst = get('tmdm:instance') 
    type = get('tmdm:type') 

    self.class.send :sanitize_sql, [%{ 
    SELECT t.* 
    FROM associations a 
    JOIN roles type ON type.association_id = a.id AND type.ttype_id = ? 
    JOIN roles inst ON inst.association_id = a.id AND inst.ttype_id = ? 
    JOIN topics t  ON t.id = inst.topic_id 
    WHERE a.topic_map_id IN (?) 
    AND a.ttype_id = ? 
    AND type.topic_id = ? 
    }, type.id, inst.id, self.ids, ti.id, ttype_id] 
end 

def instances_of_sql(ttype_id) #sequel 
    ttype_id = get(ttype_id).try(:id) 
    ti = get('tmdm:type-instance') 
    ir = get('tmdm:instance') 
    tr = get('tmdm:type') 

    DB.from(:associations.as(:a)). 
    join(:roles.as(:tr), :tr__association_id => :a__id, :tr__ttype_id => tr[:id]). 
    join(:roles.as(:ir), :ir__association_id => :a__id, :ir__ttype_id => ir[:id]). 
    join(:topics.as(:t), :t__id => :ir__topic_id). 
    where(:a__topic_map_id => self.ids). 
    where(:a__ttype_id => ti[:id]). 
    where(:tr__topic_id => ttype_id). 
    select(:t.*).sql 
end 

def instances_of_sql(ttype_id) #arel 
    ttype_id = get(ttype_id).try(:id) 
    ti = get('tmdm:type-instance') 
    inst = get('tmdm:instance') 
    type = get('tmdm:type') 

    #tables 
    t = Topic.arel_table 
    a = Association.arel_table 
    tr = Role.arel_table 
    ir = tr.alias 

    a. 
    join(tr).on(tr[:association_id].eq(a[:id]),tr[:ttype_id].eq(type[:id])). 
    join(ir).on(ir[:association_id].eq(a[:id]),ir[:ttype_id].eq(inst[:id])). 
    join(t).on(t[:id].eq(ir[:topic_id])). 
    where(a[:topic_map_id].in(self.ids)). 
    where(a[:ttype_id].eq(ti[:id])). 
    where(tr[:topic_id].eq(ttype_id)). 
    project('topics.*').to_sql 
end 

Tôi hoàn toàn đánh giá cao phạm vi được đặt tên và xem cách chuỗi chúng có thể mang lại lợi ích. Tôi không lo lắng về việc truy cập các hồ sơ liên quan thông qua một mô hình. Tôi hoàn toàn nói về việc xây dựng một truy vấn phức tạp.

+4

_ "Thứ hai, nó cung cấp đối tượng truy vấn có thể được sử dụng lại - làm cơ sở cho các truy vấn khác, chuỗi phạm vi được đặt tên, v.v." _ Đó là một lý do tôi sử dụng phần tiếp theo, cũng như thực tế được gán cho các mô hình cho phép tôi viết mã Ruby mô tả ngắn, đôi khi có thể tạo ra SQL phức tạp. Tuy nhiên, cách sử dụng tốt nhất mà tôi gặp phải là trong một trang tìm kiếm phức tạp, nơi một loạt các thành phần giao diện người dùng cho phép tôi điều chỉnh truy vấn từ từ và có điều kiện khi tôi xử lý các tùy chọn tìm kiếm. – Phrogz

+0

Phát hiện câu hỏi. Tôi thường thấy mình dành 10% thời gian để viết truy vấn thực tế và 90% thời gian dịch nó sang cú pháp ORM, hầu hết các vấn đề với việc nhóm và biểu thức tổng hợp, kết hợp với các bảng có nhiều bí danh. –

+0

@Phrogz: Bạn nên làm điều đó một câu trả lời, như tinh chỉnh các truy vấn bằng cách sử dụng Ruby thực sự là một trong những lợi thế lớn nhất của ORMs, IMO. Dễ dàng hơn nhiều khi bạn có nó trong phương pháp xích hơn khắc nó bằng dây. –

Trả lời

9

Các liên kết @ Kyle Heironimus đã để suy nghĩ Nick Kallen về Arel có dòng này:

Bạn sẽ lưu ý việc sử dụng các nguồn gốc bảng trong subselect. Đây là khủng khiếp, theo ý kiến ​​của tôi. Chỉ những người lập trình SQL tiên tiến mới biết cách viết (Tôi thường hỏi câu hỏi này trong công việc các cuộc phỏng vấn mà tôi chưa từng thấy bất kỳ ai làm đúng). Và nó không nên khó!

Vâng, Kallen đặt điều này xuống vì thiếu đóng cửa theo thành phần trong SQL. Điều đó có thể đúng trong một số trường hợp, nhưng kinh nghiệm của tôi là nhiều hơn nữa - rằng hầu hết các dev đều là khủng khiếp tại SQL. Họ chỉ biết những điều cơ bản nhất, những thứ cơ bản này được sử dụng sai khi họ cố gắng tìm kiếm các giải pháp thủ tục trong một ngôn ngữ dựa trên bộ. Tôi đã phải tranh luận về những lợi ích của cơ sở dữ liệu trong 3NF tại một công ty tôi đã ở, với tất cả các nhà phát triển khác, họ chỉ không nhận được nó. Những người tài năng (hầu hết trong số họ :), nhưng không có đầu mối về SQL hoặc cơ sở dữ liệu.

Đặt mã bằng C# hoặc Ruby hoặc Python < chèn ngôn ngữ bạn chọn> và các nhà phát triển lại hài lòng. Họ có thể gắn bó với tư duy thủ tục/OO và tạo ra mã có vẻ tốt cho họ.

Tôi biết điều này sẽ không kiếm được bất kỳ phiếu bầu nào, có lẽ hoàn toàn ngược lại, nhưng đó là quan điểm của tôi. Arel trông thú vị BTW.


Là một phụ lục cho ý kiến ​​tôi đã thực hiện ở trên, hơn sáu tháng và sau khi sử dụng các thư viện Sequel rất nhiều trong thời gian đó, tôi có thể nói rằng nó thực sự là một điều đẹp, và bây giờ tôi cảm thấy tôi sẽ sử dụng nó trước sử dụng SQL thẳng.Nó không chỉ vô cùng mạnh mẽ và cho phép tôi làm những điều đơn giản và tiên tiến mà không có quá nhiều đầu trầy xước (sẽ luôn có một số) nó có thể xuất ra SQL nó đã sử dụng, và nó cũng sẽ cho phép tôi thả xuống SQL nếu tôi cảm thấy tôi cần. Điều này không theo bất kỳ cách nào vô hiệu hóa nhận xét của tôi về sự hiểu biết nhất của SQL về SQL, (gần đây tôi đã nói, bởi một nhà phát triển để nói chuyện với người khác, rằng bình thường hóa là một di tích của một thời gian khi không gian lưu trữ đắt tiền. .. oh thân yêu!) chỉ là sự phát triển của thư viện Sequel rõ ràng đã được thực hiện bởi những người thực sự hiểu cơ sở dữ liệu. Nếu bạn biết thiết kế SQL và db, vv thì nó sẽ cung cấp cho bạn nhiều quyền lực hơn một cách nhanh chóng hơn. Tôi không thể nói cùng một ORM khác mà tôi đã sử dụng, nhưng có lẽ những người khác sẽ nghĩ khác đi.

+0

Tôi thành thạo với SQL. Vấn đề là tôi thường bắt đầu với SQL và sau đó chuyển đổi nó thành cú pháp của người xây dựng. Đây là "hoop" tôi đang đề cập đến. – Mario

+0

@Mario - Tôi đã làm cho một điểm chung, tôi hy vọng bạn không dùng nó để có nghĩa là một lời chỉ trích của bạn. Xin lỗi nếu nó xuất hiện theo cách đó. Tôi nghĩ rằng nếu bạn thành thạo với SQL sau đó gắn bó với SQL, mặc dù tôi nhớ LINQ tạo ra một số câu lệnh SQL nhanh hơn nỗ lực của tôi (trong một vụ cá cược nhẹ nhàng với một đồng nghiệp). Bạn luôn luôn có thể sử dụng nó để so sánh hoặc để giúp bạn bắt đầu, nhưng đi từ SQL đến cú pháp xây dựng âm thanh khó khăn! :) – iain

4

Bạn có khá nhiều lý do.

Here là những suy nghĩ của người tạo ra Arel.

Các vấn đề liên quan