Developing for Scalable Applications
Evan Hoff has an eye opening post about the results of putting simple business logic in the database. Go read it, now.
Now, after you have read that, let me continue with Rob's reply to my previous post:
I disagree in part, since it all depends on what do you define as extreme. Using OR/M opens new levels of extremeness with regards to the DB and queries. A few days ago I spend a few hours writing a query using NHibernate that I would never ever write in SQL, because it would be so much work to handle that. Obviously there are things that the DB does best, and for that, I have other options, including views or SP, but I use those through the OR/M, so I maintain my domain.
Absolutely. I can give you well documented code that it an absolute nightmare to develop with. It may be performant, but it wouldn't let you do anything with it.
Case in point, a coworker had decides that he wants to "save" page load times by not using user controls in a WebForms application. He still needed to generate dynamic HTML. He put the dynamic HTML in a resource file, read it into a static variable, and then built the HTML using string.Format().
There is a chance that it is more performant solution that just using user controls, and there was a clear line of reasoning leading to this behavior, but the maintainability concerns were:
- Non standard way of doing something, completely threw me off when I looked at the page.
- Ugly code that I couldn't understand.
- Presentation logic & HTML Generation are two separate concerns that were mixed together
- You had to restart the application if you wanted to change the HTML in the resource file (static variable for caching)
- Guess what happens for other cultures?
- No syntax highlighting or designer support for the HTML
This is only from a few minutes of thinking about it. I have not profiled the differences, but I believe that they are minute if any, but even if it had significant advantage, the maintainability concerns are simply too important. I'll throw a cache at the page and still be faster than anything hand optimized can get to.
You can use any tool badly, so I can't really comment on this unless I have more information. Perf issues are not inherent to OR/M by no means, but it is certainly possible to use OR/M to create performance issues. The same is true for maintainability in OR/M, it is not a given if you use OR/M, only easier.
I didn't have the chance of working on something in the order of PayPal or eBay, but I still disagree. There is a point in which the answer "throw more hardware" at it breaks, that is usually when you hit the physical constraints of the data center. Nevertheless, I think we are confusing performance and scalability here. Performance is how fast I can do something, scalability is how many concurrent somethings I can do. For the most part, I would worry about scalability more than performance.
Cheap web machines and caching as a scalability measure is one of the easiest routes to scalable applications, and as Evan has pointed out, even minor business logic handling in the database can completely break this model and leaves you with scaling out from the database, which is not a good thing.
So, let me try that comment again:
I can scale up faster and bigger and have more ability to change the application using this approach, rather than spending the time shaving milliseconds now and not being able to respond to change in three months time because of the optimizations that I did now.
I do not assume that all good engineers know & understand NHibernate. I do assume that it is possible to pick up NHibernate in a week or so. Knowledge about NHibernate is simple a pre-requisite for the application, much like knowledge of SQL is. NHibernate is not a "one off" approach because it is not something that is built for this particular project, it is a general framework with a wealth of knowledge, support, community, etc.
Oh, and did I said that you really want to read Evan's post
Comments
I have a question about using OR/M and StoredProcs/Views in general in the context of a DDD application. Say you have some calculated value like salestax. It can be calculated in the domain objects, or in the application services, or in the db itself. As a general design principle, you would only want this calculation to be defined in one place, right? So how could you ever write a storedproc or view which returns with something like salestax? Should the calculation be done in a db function that gets used by the other layers?
Mike G,
I would put it in the domain, because that is the most flexible place as far as I am concerned.
If I needed it for something else, like reporting, I would handle that in the ETL process, using my domain.
Ayende,
I'm not sure I understand. If you put the salestax calculation in the domain (domain objects I assume), how would a report (from an SP) use this calculation?
Mike G,
I won't do the report from the OLTP DB, I would move the data to a separate DB and report from there, the ETL process from the DBs would handle the sale tax calc using the domain
Ok, I see what you're saying. I had considered this but thought it would end up in too many round trips to the database, and concluded that there just must be another way! I always considered reporting as the one place where it was ok to break rules in order to improve performance, and this has led to the reporting system I'm working on to end up having some calculations defined in both TSQL and .NET...
Comment preview