2010-05-10 22 views
6

Tôi thường nghe mọi người bẻ ORM vì không linh hoạt và "trừu tượng bị rò rỉ", nhưng bạn thực sự không nghe thấy lý do tại sao chúng có vấn đề. Khi được sử dụng đúng cách, lỗi chính xác của ORM là gì? Tôi hỏi điều này bởi vì tôi đang làm việc trên một orm PHP và tôi muốn cho nó để giải quyết vấn đề mà rất nhiều ORM khác không thành công, chẳng hạn như tải lười biếng và thiếu các truy vấn phụ.Các ORM rơi qua đâu?

Hãy cụ thể với câu trả lời của bạn. Hiển thị một số mã hoặc mô tả một lược đồ cơ sở dữ liệu nơi một ORM đấu tranh. Không quan trọng ngôn ngữ hoặc ORM.

Trả lời

5

Một trong những vấn đề lớn hơn tôi đã nhận thấy với tất cả các ORM mà tôi có được sử dụng chỉ cập nhật một vài trường mà không cần truy xuất đối tượng trước.

Ví dụ: giả sử tôi có đối tượng Project được ánh xạ trong cơ sở dữ liệu của tôi với các trường sau: Id, name, description, owning_user. Nói, thông qua ajax, tôi chỉ muốn cập nhật trường mô tả. Trong hầu hết các ORM, cách duy nhất để tôi cập nhật bảng cơ sở dữ liệu trong khi chỉ có một giá trị Id và mô tả là lấy đối tượng dự án từ cơ sở dữ liệu, thiết lập mô tả và gửi đối tượng trở lại cơ sở dữ liệu. chỉ cho một bản cập nhật đơn giản) hoặc cập nhật nó thông qua các thủ tục lưu sẵn (đó là phương pháp mà tôi hiện đang sử dụng).

+0

Tôi đồng ý rằng đây là vấn đề và đây là thú cưng số 1 của tôi đi kèm với ORMS. Tôi ghét rằng bạn phải 'SELECT' đối tượng chỉ để cập nhật một trong các trường của nó, dẫn đến nhiều truy vấn. Đây là một cái gì đó tôi sẽ giải quyết thông qua tải chậm. – ryeguy

0

ORM đang cố gắng giải quyết một vấn đề rất phức tạp. Có trường hợp cạnh galore và sự cân bằng thiết kế lớn không có giải pháp rõ ràng hoặc rõ ràng. Khi bạn tối ưu hóa thiết kế ORM cho tình huống A, bạn đã làm cho nó khó xử để giải quyết tình huống B.

Có ORM xử lý tải chậm và truy vấn con theo cách "đủ tốt", nhưng gần như không thể nhận được từ "tốt đủ "to" tuyệt vời ".

Khi thiết kế ORM của bạn, bạn phải có một xử lý khá tốt trên tất cả các thiết kế cơ sở dữ liệu có thể khó xử mà ORM của bạn sẽ được xử lý. Bạn phải thực hiện một cách rõ ràng sự cân bằng xung quanh những tình huống mà bạn sẵn sàng xử lý một cách lúng túng.

Tôi không xem ORM là không linh hoạt hoặc bị rò rỉ nhiều hơn mức trừu tượng phức tạp trung bình của bạn. Điều đó nói rằng, một số ORM tốt hơn những ORM khác trong những khía cạnh đó.

Chúc may mắn phát minh lại bánh xe.

+1

Đây là những gì tôi đang nói đến. Bạn tố cáo ORM, nhưng bạn không đưa ra lời giải thích rõ ràng. Các truy vấn phụ chính xác như thế nào chỉ được thực hiện "đủ tốt" trong một số ORM? "... lúng túng khi giải quyết tình huống B" - tình huống nào? Tôi hiểu rằng ORM là sự cân bằng, nhưng trong trường hợp nào bạn bị cản trở bởi những sự cân bằng này? Loại truy vấn nào, cụ thể là gì? – ryeguy

+0

@ryeguy: Tôi không tố cáo ORM. Tôi không biết PHP và tôi không biết các ORM mà bạn biết, vì vậy tôi không biết cách cung cấp cho bạn các ví dụ cụ thể hơn. Một sự cân bằng ORM nổi tiếng là tải lười sẽ phơi bày vấn đề SELECT N + 1. –

+0

Tôi đã nêu trong bài đăng gốc của mình rằng nó có thể là orn thuyết bất khả tri. Tôi đoán tôi sẽ làm rõ hơn. – ryeguy

4

Đối tượng và bản ghi cơ sở dữ liệu thực sự không giống như vậy. Họ đã gõ khe mà bạn có thể lưu trữ các công cụ trong, nhưng đó là về nó. Cơ sở dữ liệu có khái niệm nhận dạng hoàn toàn khác với ngôn ngữ lập trình. Họ không thể xử lý các đối tượng tổng hợp tốt, vì vậy bạn phải sử dụng các bảng bổ sung và các khóa ngoại để thay thế. Hầu hết không có khái niệm về kiểu thừa kế. Và cách tự nhiên để điều hướng một mạng các đối tượng (theo một số con trỏ trong một đối tượng, lấy một đối tượng khác và một lần nữa) sẽ kém hiệu quả hơn khi ánh xạ tới thế giới cơ sở dữ liệu, bởi vì bạn phải thực hiện nhiều chuyến đi khứ hồi và lấy nhiều dữ liệu mà bạn không quan tâm.

Nói cách khác: sự trừu tượng không thể được thực hiện rất tốt ngay từ đầu; nó không phải là công cụ ORM mà là xấu, nhưng ẩn dụ mà họ thực hiện. Thay vì một đẳng cấu hoàn hảo, nó chỉ là sự giống nhau bề ngoài, do đó bản thân nhiệm vụ không phải là một sự trừu tượng rất tốt. (Nó vẫn còn hữu ích hơn việc phải hiểu cơ sở dữ liệu một cách mật thiết. Tuy nhiên, sự khinh miệt đối với các công cụ ORM chủ yếu đến từ các DBA chỉ tìm kiếm trên các lập trình viên đơn thuần.)

3

ORM cũng có thể viết mã không hiệu quả. Vì hiệu suất cơ sở dữ liệu là quan trọng đối với hầu hết các hệ thống, chúng có thể gây ra các vấn đề có thể tránh được nếu một người viết mã (nhưng có thể không tốt hơn nếu con người được hỏi không hiểu điều chỉnh hiệu suất cơ sở dữ liệu).Điều này đặc biệt đúng khi truy vấn phức tạp.

Tôi nghĩ rằng vấn đề lớn nhất của tôi với họ là bằng cách trừu tượng hóa các chi tiết, lập trình viên cơ sở ít hiểu hơn về cách viết truy vấn mà họ cần để có thể xử lý các trường hợp cạnh và những nơi ORM viết mã thực sự xấu. Thật khó để học những thứ cao cấp khi bạn không bao giờ phải hiểu những điều cơ bản. Một ORM trong tay của một người hiểu tham gia và nhóm theo và truy vấn tiên tiến là một điều tốt. Trong tay của một người không hiểu đại số boolean và tham gia và một loạt các khái niệm cơ bản SQL khác, nó là một điều rất xấu dẫn đến thiết kế rất nghèo của cơ sở dữ liệu và các truy vấn.

Cơ sở dữ liệu quan hệ không phải là đối tượng và không được xử lý như vậy. Cố gắng để làm cho một con đại bàng vào một ví lụa nói chung là không thành công. Tốt hơn để tìm hiểu những gì đại bàng là tốt và tại sao và để cho con đại bàng bay hơn để có một ví xấu và một con đại bàng chết.

+1

Nhưng bạn sẽ không nói rằng với việc sử dụng thích hợp của chúng, ORMs tạo mã chỉ tốt? Theo kinh nghiệm của tôi, lần duy nhất họ tạo ra "mã xấu" là khi chúng được sử dụng không chính xác, như tìm nạp các mối quan hệ trong một vòng lặp. – ryeguy

+1

Nhưng đó là chính xác những gì tôi có ý nghĩa, khi những người biết họ đang làm gì, họ là tốt, khi mọi người sử dụng chúng như một cái nạng để tránh học SQL, họ có thể tạo ra một mớ hỗn độn. – HLGEM

+0

Tôi đồng ý, nhưng bạn không thể nói điều đó về bất kỳ công cụ nào? Các lập trình viên thiếu kinh nghiệm có thể viết SQL nghèo dễ dàng như người dùng ORM thiếu kinh nghiệm có thể viết các truy vấn nghèo bằng cách sử dụng ORM. – ryeguy

1

Cách tôi thấy nó giống như thế này. Để sử dụng ORM, bạn phải thường xuyên sắp xếp một số hàm php, và sau đó kết nối với một cơ sở dữ liệu và về cơ bản vẫn chạy một truy vấn MySQL hoặc một cái gì đó tương tự.

Tại sao tất cả sự trừu tượng ở giữa mã và cơ sở dữ liệu? Tại sao chúng ta không thể sử dụng những gì chúng ta đã biết? Thông thường, một nhà phát triển web biết ngôn ngữ phụ trợ của họ, ngôn ngữ db của họ (một số loại SQL) và một số loại ngôn ngữ giao diện người dùng, chẳng hạn như html, css, js, v.v ...

Thực chất, chúng tôi đang cố gắng thêm một lớp trừu tượng bao gồm nhiều hàm (và tất cả chúng ta đều biết hàm php có thể chậm hơn việc gán một biến). Có, đây là một tính toán vi mô, nhưng vẫn còn, nó tăng lên.

Hiện tại, chúng tôi không chỉ thực hiện một số chức năng mà còn phải học cách ORM hoạt động, vì vậy có một số thời gian lãng phí ở đó. Tôi nghĩ toàn bộ ý tưởng tách mã là giữ mã của bạn tách biệt ở mọi cấp độ. Nếu bạn đang ở trong thế giới LAMP, chỉ cần tạo truy vấn của bạn (bạn nên biết MySQL) và sử dụng chức năng php đã có cho các câu lệnh đã chuẩn bị sẵn sàng. LÀM XONG!

ĐÈN CÁCH:

  • tạo truy vấn (string);
  • sử dụng báo cáo được chuẩn bị mysqli và truy xuất dữ liệu vào mảng.

ORM CÁCH:

  • chạy một chức năng mà được đơn vị
  • mà chạy một truy vấn MySQL
  • chạy một chức năng mà bổ sung thêm một điều kiện
  • chạy một chức năng có thêm một điều kiện
  • chạy một hàm khác tham gia
  • chạy một hàm khác có thêm điều kiện về tham gia
  • chạy một chức năng mà chuẩn bị
  • chạy một truy vấn MySQL
  • chạy một chức năng mà fetches các dữ liệu
  • chạy khác MySQL Query

Có ai khác có một vấn đề với ngăn xếp ORM? Tại sao chúng ta trở thành những nhà phát triển lười biếng như vậy?Hay sáng tạo đến mức chúng ta đang làm hại mã của chúng ta? Nếu nó không bị hỏng thì đừng sửa nó. Đổi lại, hãy sửa nhóm dev của bạn để hiểu các khái niệm cơ bản về web dev.

+0

Câu trả lời của bạn khá cụ thể đối với PHP hoặc các ngôn ngữ/nền tảng khác không có hỗ trợ công cụ. Trong C#, tôi chỉ đơn giản sử dụng một câu lệnh như 'var query = from c trong db.Customers từ o trong db.Orders trong đó o.CustomerId = c.ID chọn new {c.ID, c.Name, o.Quantity};' –

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