5 ms·
I'm still of the opinion that ORM frameworks are just too much of an abstraction away from the database. What's wrong with just writing pure SQL?
by djhworld 12y ago
I'm still of the opinion that ORM frameworks are just too much of an abstraction away from the database.
What's wrong with just writing pure SQL?
- jamesaguilar 12y agoWhy stop there? You should just provide the query opcode program directly to the db! Point being, different folks like to work at different levels of abstraction.
- tekacs 12y agoAlternately to my sibling comment here, how about reading (and rebutting if you see fit) [slide 1][1] of the link before commenting on it. -.-' [1]: http://present.go-steel-programmers.org/talk-review-orms/gsp-go-orms.slide#2 http://present.go-steel-programmers.org/talk-review-orms/gsp...
- eldelshell 12y agoIn my many years I've seen four reasons that stand: 1) Maintainability between the database and the software models. Specially when starting a new project, the database model can change a lot and it can be pain. 2) Every project I've seen using SQL DAOs, end up writing some sort of ORM. You can see this when you find a class called "Select" in your persistence code. 3) Not every developer is a good SQL developer. 4) Your persistence/DAO layer has to keep up with other stuff which an ORM usually provides: connection management, transactions, caching, key restrictions, error handling. This is a critical bug waiting to happen scenario. I'm also not a big fan of ORM's (and actually have been trying to stay away from them in new projects) but most of the times it is the best solution.
- sudowhodoido 12y ago3) Not every developer is a good SQL developer. I find that developers are better SQL developers than their ability to successfully design a domain model.
- deaddodo 12y agoThe whole purpose of ORM's /is/ abstraction. The idea is to take the raw concepts of data atoms and abstract them into programmatic entities. This way, you can work with the data directly and not need to worry about SQL semantics and nuance. Additionally, there's the side effect of encouraged utilization of DB server functionality/optimization (views [materialized and direct], triggers, procedures, enforced foreign keys, indices, etc).
- sudowhodoido 12y agoAfter years of using Hibernate and NHibernate, considered best of breed and most well thought out and thoroughly engineered ORMS, I agree. They fall of a productivity cliff pretty quickly, particularly on larger projects (I'm talking things with 100+ domain objects). I've settled on: Use CQRS (Command Query Response Segregation) and stuff ORMs where the sun doesn't shine. Separate Update/Insert/Delete commands and queries. Commands return nothing and are assumed to work unless an exception is thrown, then the whole batch is rolled back. Queries return data. Transaction boundaries are arbitrary based on the requirement of the calling service, not the unit of work and/or session. By default all transactions are imperative. Stored procedures, triggers and views are banned. Commands are classes with properties attached (easy to validate, test and provide good encapsulation) and are internally represented as raw SQL with bound parameters. Queries return enumerable lists of objects and are internally represented as a raw SQL query with bound parameters. Everything is programmed to generic interfaces: IStorageCommand<T> and IStorageQuery<T> That is all. I've used Dapper on .Net to do the internal representation. It is portable across non SQL stores as well and has been used to interface with cache and Redis as well. Plus due to the loosely coupled abstraction, you can use AOP to stick read-through cache interceptors in between the IStorageQuery<T> interface and the consumer. Also you can stick cache invalidators between IStorageCommand<T> and the consumer. Moving one of our core subsystems over to this with some careful design and DBA consultation knocked our 48 Core Xeon SQL box from 60% utilisation to 5% (mainly IOPS/storage throughput. CPU is a non issue there).
- windowsworkstoo 12y agoYes, nice, same here. One question out of curiosity - on your IStorageQuery interface what methods do you have? Do you have the usual by Id's etc or do you have a query object that you pass in that can build/translate to the relevant SQL?
- sudowhodoido 12y agoQuery object. The interface is as follows (I simplified a bit above: public interface IStorageQuery<T,Q> where Q : IStorageQueryCommand { IEnumerable<T> Query(Q query); } IStorageQueryCommand is an empty marker interface. Internally this is all bound to the query by property name.
- lmm 12y agoIt's repetitive (because it doesn't support abstraction well enough), the tooling is poor, and it's difficult to test. If I want to write a function to retrieve these three objects based on these criteria, it should be possible to separate the logic from the actual retrieving from the database. And the interface between those two should be something more structured than String.
- aikah 12y ago> What's wrong with just writing pure SQL? What's wrong with wanting to abstract something that only the database care about? when you want to read a file in go,do you execute a shell command like "cat myfile.txt" and pipe the result? or do you use a pure go api ? Each time you do an http request,do you send headers and body through tcp sockets as text,or do you use an http api?
- enneff 12y agoI'm no sure the point your making, but you appear to be agreeing with the OP. Go's os.Open function is a thin veneer around the open system call, which is the same thing cat uses. The HTTP package provides as thin a layer over actual HTTP as possible. The story with database/sql is the same.
- aikah 12y agomy point is ,you dont write raw tcp text commands when you do an http request in Go(well you can,but what's the point when... )...There is an abstraction layer,you deal with "objects",not HTTP text commands directly. I dont see why it's nice to have an abstraction for HTTP but as soon as it comes to RDBMSs, string commands should be the way to go...
- shanemhansen 12y agoYour analogy is flawed. Using a httplib for http is like using a database driver for SQL. An ORM for http would be something like Ruby's Active Resource or some other abstraction that his all URLs and query strings from you.
- eropple 12y agoBecause it's a massive impedance mismatch for most nontrivial cases. Relational and object systems have never played particularly well together. The contention is, and it's one that I agree with, is that the tooling that inevitably builds up to address this impedance mismatch is too hard to usefully generalize in a way that doesn't end up taking over your project. (This is why I dig mappers for document-based databases and avoid them for relational ones.)
- kibibu 12y agoFor one point of data, I found migrating a medium-sized Django web app from MySQL to Postgres was trivially easy in the parts where I'd used an ORM, and annoyingly difficult in the parts where I'd dropped to SQL for performance.