Is ORM still the “Vietnam of Computer Science”?

前端 未结 10 778
孤街浪徒
孤街浪徒 2020-12-23 18:05

I read this post last night, and I noticed it was from 2006. I could go either way on the ORM, database thing, but I was just wondering if everything bad Jeff said about OR

相关标签:
10条回答
  • 2020-12-23 18:45

    It's still true.

    Even more than OO software, the database suffers if it isn't treated precisely the way intended. And it wasn't intended that you should interpose some abstraction layer in front of it.

    I think of impermeable abstraction layers as trying to build a Lego castle with all the pieces closed up into a pillowcase. SQL is damn hard to do correctly. It doesn't share many patterns with procedural programming, and best practices for one can be the opposite for the other. You need to be able to grok every single item in a SQL statement, and have a pretty good idea what it's intended to do, and what it in fact does.

    Lots of people seem to think that, like horseshoes, close is good enough - if the right answer pops out, that implies you're nearly there. In SQL, that's simply not true.

    RoR and the ActiveRecord pattern have deservedly earned a reputation as dbms resource hogs for this reason. Optimized ActiveRecord design is more often than not suboptimal SQL design, because it encourages SQL statement decomposition.

    0 讨论(0)
  • IMHO, Monadic approaches like Scala's Slick and Quill largely bypass the aforementioned quagmire, offering more robust solutions to many of Ted's problems (also JOOQ deserves to be mentioned). While they're not perfect, they definitely kill the N+1 and Partial Object problems, mostly kill the Identity problem, and partially kill the Dual Schema problem. Forget about clumsy and verbose CriteriaBuilder queries (anyone read "Execution in the Kingdom of Nouns???"), Scala's monadic for-comprehensions give you a simple DSL in which to write criteria-queries:

    case class Person(id: Int, name: String, age: Int)
    case class Contact(personId: Int, phone: String)
    
    val query = for {
        p <- query[Person] if(p.id == 999)
        c <- query[Contact] if(c.personId == p.id)
      } yield {
        (p.name, c.phone)
      }
    

    This kind of syntax stays sane, even for more complex queries e.g. Ted's is-acceptable-spouse query:

    case class Person(name:String, spouse:Option[PersonId]) {
        isThisAnAccpetableSpouse(person:Person) {...}
    }
    
    val query = for {
        p1 <- people
        p2 <- people if (
            p1.spouse.isEmpty && p2.spouse.isEmpty 
            && p1.isThisAnAccpetableSpouse(p2)
            && p1.isThisAnAccpetableSpouse(p1))
    } yield (p1, p2)
    

    All of this get's compiled into a single SELECT query and run against the database. Inserts, Updates, and Deletes are similar.

    0 讨论(0)
  • 2020-12-23 18:46

    A lot of web 2.0 companies are working on key-value stores. And all these companies have to go through the same painfull process of making it work.

    If ORM is the "vietnam of computer science" then building your own key-value store is probably the "Iraq of computer science" :-)

    0 讨论(0)
  • 2020-12-23 18:47

    Jeffs article links through to Ted Newards article. If you are into the details then you need to look there:

    1. original - http://blogs.tedneward.com/post/the-vietnam-of-computer-science/

    2. followup - http://blogs.tedneward.com/post/thoughts-on-vietnam-commentary/

    Of Ted's original points I have it as:

    • 1 was wrong (Identity)
    • 2 of them solved (Partial objects and N + 1)
    • 2 are debatable (Dual schema / shared schema).

    Disclaimer: I'm the author of Ebean ORM so I'll reference that for the various 'solutions' to the issues raised.

    Ted's original points (distilled because it's really wordy):

    1. Partial Object problem.

    Always solvable. Ebean ORM made partial objects fundemental to it's query language and all internals. JPQL didn't make this a priority to it's more a problem there unfortunately.

    • Refer: http://ebean-orm.github.io/docs/query/partialobjects

    2. N + 1 (Ted's Load time paradox)

    Always solvable. Should have been written as 1 + N / batchSize but it is more interesting than that (per path, need to take into account SQL paging, avoid sql cartesian product). Some ORM's make a right mess of this unfortunately and that brings ORM in general into disrepute. Some ORM's are ok until you hit a level of complexity (like OneToMany inside OneToMany inside OneToMany).

    • Refer: http://ebean-orm.github.io/docs/query/nplus1

    Just to up the ante here ORM's can profile the object graph use and automatically optimise the query (only fetching what is needed, defining fetch paths to optimise for N + 1 etc).

    • Refer: http://ebean-orm.github.io/docs/query/autotune

    This automatic ORM query optimisation idea came out of the University of Texas (using Hibernate). It was included as part of Ebean ORM in 2008 so it's been around for a while now.

    • Refer: https://en.wikipedia.org/wiki/AutoFetch

    3. Identity

    Ted cracks on about a mismatch on identity and concurrency. This point is misplaced as ORMs (well, all the ones I know) go about this aspect in exactly the same manor as the prior client/server tools and specifically ORM's are providing a SNAPSHOT view of part of the database to the application. There was never a problem here but ORM implementations could get themselves into strife with an over reliance on hashCode()/equals() for example.

    4. Dual schema problem

    This is debatable. If the organisation allows then the ORM can provide a DIFF/SQL script to the schema and that is run by FlywayDB/Liquibase etc. If organisations don't allow that this might still be an issue to some extent.

    5. DB Refactoring / Shared schema

    This is debatable. DB design/normalisation folks would argue that the DB design should get to 4NF and that means any refactoring should solely be additive (denormalisation, adding columns/tables) and not breaking changes. People who don't believe in normalisation will be going nuts worried about shared schema.

    0 讨论(0)
提交回复
热议问题