ORM có phải là một công cụ tồi cho các cấu trúc DB giống như cây không?


8

Tôi biết câu hỏi này có thể được đóng lại dưới dạng dựa trên ý kiến, nhưng điều tôi cần ngay bây giờ là một số ý kiến ​​được hỗ trợ bởi các lập luận.

Tôi đang xây dựng một ứng dụng với Postgres và Ecto (Elixir) là lớp bền vững. Có một thực thể tham chiếu chính nó để bạn có thể xây dựng một cấu trúc giống như cây với nó. Tôi càng cố gắng làm điều này với Ecto, tôi càng thất vọng.

Các ORM chỉ đơn giản là một công cụ tồi để tạo các cấu trúc DB phức tạp với nhiều liên kết? Cách hướng đối tượng mà ORM cố gắng thực thi trên dữ liệu quan hệ dường như là một cách tiếp cận tồi ở đây. Đối tượng bị cô lập. Nếu họ tương tác với các đối tượng khác, họ (được cho là) ​​gửi tin nhắn. Các chi tiết bên trong của họ nên được giấu kín. Dữ liệu quan hệ tạo thành một biểu đồ mở, minh bạch. Hai thế giới này dường như hoàn toàn không tương thích với tôi.

Tuy nhiên, ORM rất phổ biến và phổ biến. Có phải phần lớn các ứng dụng web hoạt động với các thực thể khá tách biệt chơi tốt với ORM, hoặc tại sao vậy? Đối với tôi, dường như nếu bạn muốn triển khai bất kỳ mô hình ERD trung bình phức tạp nào bằng cách sử dụng khung ORM, bạn phải hy sinh mã ngắn gọn hoặc hiệu suất.


1
Mỗi hệ thống cơ sở dữ liệu có thể có một triển khai hơi khác nhau để hỗ trợ cấu trúc dữ liệu cây hoặc "phân cấp". Ví dụ, Oracle có START VỚI và CONNECT BY và Sql Server có Biểu thức bảng chung (CTE). Vì vậy, trước khi chọn ORM, người ta nên xác định xem nó có hỗ trợ phù hợp cho các loại cấu trúc dữ liệu này hay không. Một số cung cấp hỗ trợ rất tốt, trong khi những người khác có thể không bao gồm các kịch bản. Câu hỏi này nên được đặt lại từ: Ecto có hỗ trợ cấu trúc cây không?
Jon Raynor

Vì bạn đã đề cập cụ thể đến các postgres, nó hỗ trợ các truy vấn đệ quy cho loại điều này (mặc dù tôi chưa sử dụng nó)
Izkata

1
Tất nhiên ORM là một công cụ tồi. Đã có một ngôn ngữ để diễn đạt rõ ràng các truy vấn trên cơ sở dữ liệu: SQL.
Miles Rout

@Miles Rout Trong hầu hết các trường hợp khi bạn sử dụng SQL đơn giản thay vì ORM, bạn sẽ lặp lại nhiều lần.
Jimmy T.

@JimmyT. Điều đó là sai.
Miles Rout

Câu trả lời:


9

Vào cuối ngày, ORM chỉ là một bản tóm tắt tạo ra sql cho bạn và ánh xạ dữ liệu tới các đối tượng của bạn. Tiết kiệm (tm) cho bạn một số mã 'tấm nồi hơi'.

Vì vậy, không có gì mà các ORM nói chung nhất thiết là xấu theo định nghĩa. Vấn đề là bạn không sử dụng toàn bộ ORM, bạn phải chọn một cái cụ thể và sử dụng nó!

Một ORM cá nhân có thể không làm một điều cụ thể rất tốt. Procs được lưu trữ, sql động, các trường được tính toán, các phép nối phức tạp, vv có thể là các khu vực có vấn đề.

Một vấn đề tinh tế hơn là khi một ORM cố gắng xử lý tất cả các kịch bản này theo cách chung chung, nó sẽ trở nên lớn hơn và phức tạp hơn để sử dụng.

Nếu bạn có một ứng dụng lớn hoặc phức tạp, có khả năng đến một lúc nào đó bạn sẽ gặp sự cố với ORM mà bạn đã chọn. Vì vậy, sẽ hợp lý khi lên kế hoạch trước cho việc này và đảm bảo rằng bạn ẩn ORM đằng sau một kho lưu trữ. Bằng cách đó, bạn có thể tự do trao đổi nó để thay thế hoặc quay trở lại để mã hóa SQL nếu cần.


1
Cần lưu ý rằng, trong rất nhiều ORM (ít nhất là mọi ORM mà tôi đã sử dụng ), bạn có thể viết và thực thi SQL thô . Do đó, nếu ORM không thỏa mãn một số ràng buộc nào đó, bạn luôn có thể sử dụng nó với SQL gốc, đồng thời giảm các hoạt động 'nồi hơi' SELECT * FROM some_table WHERE x = whateverlà cực kỳ phổ biến. Các cấu trúc phân cấp được xử lý tốt trong một số ORM và khủng khiếp ở các cấu trúc khác, vì vậy loại cân nhắc này cần được nghiên cứu trước khi quyết định từ bỏ hoàn toàn ORM.
Chris Cirefice

bạn thường có thể làm điều này, nhưng nó không luôn hoạt động theo cách bạn muốn! gần đây có vấn đề chính xác này với ánh xạ trường nHibernate và nullable
Ewan

Tôi chưa bao giờ sử dụng nHibernate, nhưng tôi đã sử dụng một số như ActiveRecord của Rails, OrmLite (Java) và ActiveJdbc (Java). Mỗi xử lý này thực thi SQL thô khác nhau, ví dụ ActiveRecord làm cho nó thực sự dễ dàng và OrmLite làm cho nó thực sự khó khăn. ActiveRecord đã được phát triển trong nhiều năm và nhiều năm, vì vậy chắc chắn điều đó có liên quan đến nó. Tất cả những sắc thái nhỏ này là một phần của kiểm tra tính khả thi, nhưng đôi khi bạn bỏ lỡ những điều nhỏ nhặt quay lại cắn bạn sau này ...
Chris Cirefice

Vâng, đó là lý do tại sao tôi nói đặt một bọc xung quanh nó. bạn vẫn có thể sử dụng orm, nhưng bạn không bị khóa nếu cho phép bạn xuống theo một cách nào đó
Ewan

Tiết kiệm (tm) - Tôi cười thầm một chút về điều này.
corsiKa

7

Các ORM chỉ đơn giản là một công cụ tồi để tạo các cấu trúc DB phức tạp với nhiều liên kết?

Không. Ví dụ, Ruby on Rails sử dụng ActiveRecord, xử lý các liên kết. Trong ví dụ ở đây: /programming/5109893/rails-how-do-elf-referential-has-many-models-work , cấu trúc giống như cây được thực hiện với 2 dòng mã.

Vì vậy, tôi sẽ lập luận rằng nó dễ dàng hơn so với việc cố gắng cuộn các truy vấn sql của riêng bạn.

Có phải phần lớn các ứng dụng web hoạt động với các thực thể khá tách biệt chơi tốt với ORM, hoặc tại sao vậy?

Có lẽ là không, nhưng đó chỉ là phỏng đoán. Các ORM tồn tại trong một hệ sinh thái nơi chúng đang phát triển mạnh, cho thấy chúng đang được sử dụng. Tôi đã sử dụng ORM cho các hệ thống có hơn 20 mô hình liên quan và thấy chúng vẫn ổn. Tôi chưa bao giờ buộc các đối tượng bị cô lập chỉ với tin nhắn đi qua.

Như một ý kiến ​​tóm tắt, nếu bạn đang tạo các mô hình ERD "phức tạp", không có công cụ nào làm cho chúng dễ dàng. Chỉ các công cụ làm cho chúng hoạt động.


Đúng - Tôi đã sử dụng Entity Framework cho một dự án có CustomerId (PK) và ParentCustomerId (FK nullable quay lại bảng khách hàng) để tạo n cấp cây phân cấp khách hàng. Không có vấn đề gì ở đây (mặc dù nhiều kiểm tra null / .Any()câu lệnh LINQ)
USER_8675309

Hibernate (Java) là một ví dụ điển hình khác về ORM có thể xử lý cây mà không gặp sự cố, đòi hỏi nỗ lực thêm gần như bằng không . Độ phức tạp truy vấn được ẩn khỏi máy khách. Cha mẹ và con cái có thể lười biếng. ID đối tượng cha chỉ là một cột khác trong cơ sở dữ liệu. Một danh sách các nút con có thể được hỗ trợ trong suốt cùng với việc thêm một cột chứa chỉ mục danh sách. (Các cân nhắc về bộ sưu tập được sắp xếp theo thứ tự không phải là duy nhất đối với cây ở đây.)
Jason C

Tôi không thể giúp nhưng cảm thấy rằng đây là một câu trả lời sai lệch. Bởi vì một ORM xử lý trường hợp này, không có nghĩa là các ORM nói chung có thể xử lý việc này. Thật vậy, một google nhanh chóng cho thấy rằng bản ghi hoạt động DOES có gotchas và lỗi trong một số phiên bản xung quanh việc tự tham khảo github.com/rails-api/active_model_serialulators/issues/211coderwall.com/p/4d2utg/ tựa
Ewan

@Ewan - Tôi sẵn sàng đọc lại câu trả lời của mình, nhưng tôi nghĩ rằng nó trả lời thỏa đáng cho câu hỏi nếu các ORM nói chung là xấu. Đó là một câu hỏi khác nhau để hỏi nếu tất cả các ORM có thể xử lý trường hợp này, hoặc nếu chúng là giải pháp tốt nhất. Sự tồn tại của một công cụ ORM ít phù hợp hơn hoặc một lỗi trong phiên bản không làm thay đổi khái quát hóa. Tôi cũng biết tôi cũng có lỗi trong SQL của mình.
cmonkey

5

Như đã lưu ý trong ít nhất một câu trả lời khác ở đây, tất cả các ORM đều không giống nhau. Một số ORM đưa ra các giả định rất quan trọng về cách cấu trúc cơ sở dữ liệu. Công cụ sẽ cung cấp một số hỗ trợ cho việc đi ra ngoài mô hình này nhưng bạn càng đi ra ngoài mô hình đó, ORM càng có ít giá trị. Nếu bạn đang làm việc với một công cụ ORM độc đoán hơn, bạn sẽ có trải nghiệm tốt hơn nhiều nếu bạn thiết kế cơ sở dữ liệu xung quanh các giả định ngầm định của nó.

Tôi chưa bao giờ thực sự hiểu tại sao ORM được nhiều nhà phát triển và kiến ​​trúc sư xem là thiết yếu. Điều này có thể là do thực tế là tôi gần như chưa bao giờ có cơ sở dữ liệu trường xanh để làm việc và thời gian và nỗ lực cần thiết để thực hiện ánh xạ ORM được thực hiện nhiều hơn so với viết SQL. Ánh xạ là đơn giản (và SQL cũng vậy) hoặc nó phức tạp và dù sao tôi cũng cần SQL (hoặc một cái gì đó tương tự). Theo kinh nghiệm của tôi, 'hỗ trợ' được bao gồm trong ORM là nguồn gây ra nhiều lỗi và sự cố hơn là sự giúp đỡ, theo kinh nghiệm của tôi.

Số dặm của bạn có thể thay đổi nhưng tôi tin rằng sẽ tốt hơn khi nghĩ về sự kiên trì của cơ sở dữ liệu như là một trường hợp đặc biệt của tuần tự hóa dữ liệu. Và đúng như tôi nghĩ, thật vô nghĩa khi tin rằng bạn có thể 'gửi' một vật qua dây, tôi không nghĩ việc viết các đối tượng vào cơ sở dữ liệu thực sự có ý nghĩa. Tôi thậm chí nghĩ rằng nó hoàn toàn hợp lệ khi có nhiều biểu diễn đối tượng của cùng một dữ liệu cho các nhu cầu khác nhau. Ánh xạ các đối tượng vào các bảng và ngược lại đã trở thành một kết thúc đối với chính nó trái ngược với một giải pháp cho một vấn đề. Tôi không tin rằng hầu hết mọi người sử dụng các công cụ này thậm chí có lý do rõ ràng để muốn làm điều đó. Nó trở thành một mặc định.


1
Totes đồng ý, một khi bạn từ bỏ chính mình để gõ sql và lập bản đồ, nó hiếm khi mất nhiều thời gian hơn và bạn có toàn quyền kiểm soát
Ewan

@Ewan Để công bằng, tôi nghĩ rằng cần một chút kinh nghiệm để biết cách xây dựng sự trừu tượng đúng đắn giữa logic và DB. ORM có thể giúp các nhà phát triển nhanh chóng có được một cái gì đó khả thi. Đó là ý tưởng rằng các đối tượng có thể được dịch sang các bảng và ngược lại, đó là nơi tôi nghĩ có vấn đề. Điều này đúng với một tập hợp con của mô hình dữ liệu và mô hình đối tượng nhưng không nói chung.
JimmyJames

1
@JimmyJames Điều đó đúng nếu tất cả những gì bạn cần là rất đơn giản cho mỗi thao tác CRUD của bảng. Ngoài ra, một ORM không vi mô là một lời nguyền. (Và cá nhân tôi tìm thấy những ý tưởng của việc tạo ra một đối tượng cho mỗi bộ khác nhau của cột trở lại cho một ORM vi đến được gây phiền nhiễu, mặc dù nó có thể là ít điều phiền toái trong một ngôn ngữ tĩnh gõ.)
jpmc26

1
@ jpmc26 Tôi muốn bước bên cạnh vũng lầy tĩnh so với động nhưng tôi nghĩ bạn đang làm nổi bật loại điều tôi đang nói đến. Nếu tất cả những gì tôi muốn làm là lấy một số dữ liệu, chuyển đổi tối thiểu dữ liệu đó và trả về là JSON, chẳng hạn, tôi thực sự không cần ánh xạ tới các đối tượng để thực hiện điều này. Đối tượng không có chức năng thực sự. Nó hoạt động như một bản đồ nơi dữ liệu được lưu trữ trong giây lát. Nhưng tôi đã thấy các ORM được sử dụng để giải quyết vấn đề đó. Thường thì câu trả lời là tạo các lớp cho các đối tượng đó, nhưng tôi nghĩ đó chỉ là những điểm nổi bật về việc chúng không cần thiết như thế nào.
JimmyJames

Bằng cách nào đó, tôi đã bỏ qua điều mà ban đầu tôi dự định nói: Tình hình không tốt hơn với một cơ sở dữ liệu hoàn toàn mới mà bạn đang phát triển. Nó chỉ phụ thuộc vào loại truy vấn bạn cần viết. Đối với CRUD rất đơn giản trên mỗi bảng, nó có thể tiết kiệm một ít thời gian. Nhưng nếu bạn có các truy vấn trộn và khớp dữ liệu từ các bảng hoặc truy vấn khác nhau phức tạp (nhóm phức tạp, CTE, truy vấn con), bất cứ điều gì không vi mô sẽ tự động gây ra nhiều rắc rối hơn giá trị của nó. Ngay cả khi bạn có thể thoát khỏi CRUD rất đơn giản ngay từ đầu, bạn cá rằng thành công sẽ không dẫn đến sự phức tạp lớn hơn.
jpmc26
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.