1: In the end, it's SQL
Sure, the system you're looking at is not just a simple SQL front-end. While it does terminate some functionality in an SQL database, other things are passed on to web services and other support systems. But what do those do? More likely than not, they terminate functionality in an SQL database or pass the request on to other systems that do the same. Eventually, everything ends up as SQL queries. There aren't web services all the way down.As a corollary, you can determine the efficiency of the architecture by comparing the queries that are actually run for a set of functions with that you would have if you just looked at those functions and translated that into queries to an imaginary database built for the purpose. If you only need a query or two that fetch a grand total of a handful of rows, but the queries that end up hitting the actual databases are a lot more complex (and especially return a lot more data), then you're losing track of the objective somewhere along the way from the user to the database.
2: If the answer to your enterprise integration needs is a bus, then you have bigger problems
If you need a bus to integrate your systems, then you either
- pretend that you don't know what systems you have, or
- actually have no control over what's deployed.
That said, there are cases where a bus makes sense. If you're building a desktop operating system that will be used by millions of users running any number of strange things on their systems, then a bus does make sense. If your enterprise architecture is comparable to millions of installations of a desktop system, however, you have your plate full.
3: Premature generalization is the root of all evil
Premature optimization is the root of all evil, and it applies even when you're not optimizing for runtime performance. If you prematurely optimize for generality, then you will invariably make designs that are more complex than is called for.
For instance, if the cardinality of a relation between two entities is one-to-one, then don't make it one-to-many just because you think it might be useful later on. Yes, it will be painful one day if you end up having to change it, but it will be painful every single day if you needlessly generalize it now.
Another example is that if you're designing a system whose purpose it is to generate HTML that will be sent out over HTTP, then it's OK to make components of the system aware of that now and then. I'm not saying you should generate HTML from the stored procedures in your database, but only that there's no need to make every (or any, actually) component capable of doing everything. If you can simplify the design by assuming, say, that the purpose of the system is what you know it is, then do so.
Conclusion
So, there you go, my Laws of Enterprise Architecture. What are your laws?