- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
So you're saying that if the vendor simply implemented a brand new type of object whose purpose was specifically to reduce index-to-table lookups, then it would all be fine because "that's what it's supposed to do"? The only reason this is a hack is that they are called "indexes"? That goes back to a "the world revolves around me" position. You don't like covering indexes because they aren't "right".
Here is an interesting analogy:
Indexes are called "indexes" because they work like the indexes in these things we call "books". Well, a typical book index contains a keyword and a page number. If you were looking for how many pages reference the word "widget" in a given book, you could entirely answer that question from the index. Hey, look, database servers do that too!!!! Covering indexes don't abuse the abstract concept, the concept of covering indexes has been in books for hundreds of years.
Admin
I did this already between MySQL 5.0 and SQL Server. They both support stored procs.
And some more..The data layer exposes interfaces from System.Data, but it's a factory that switches to MySQL or SQL Server that actually does the work. I use switch statements where needed for the subtle differences (booleans and names of stored procs params are different a bit), but the creation and population of stored procedure parameters is done by calling a factory to produce them, and returning instances that support the IDbParameter, for example. I found it to be quite painless.
Here's code that demonstrates:
<font size="1"> public static DataSet RunProc(IDbCommand command)
{
if (_cn == null || (_cn.State != ConnectionState.Open))
{
Connect();
}
IDbDataAdapter adapter = GetAdapter(command);
DataSet data = new DataSet();
adapter.Fill(data);
return data;
}</font>
Admin
Nope.
The view to the world is that the database is an amorphous blob with data. It knows what the data should look like, but not the semantics of the data itself (This field is a numeric type is important, the fact that it represents the money in your bank account is not import to the database itself).
The database don't know anything more than it should. It is a large object, with lots of getters and setters, but it definitely does not do anything outside its domain (store valid and consistent relations of data).
The database does not implement business rules. It implements rules for data validation.
From the wikipedia link:
The database object solves the data maintainance issue. It does not solve other parts of the application domain.
Application developers should not have to worry about the implementation of the storage system, tables and columns (or even if the tables exist). They need to be able to obtain data from the store, and put data into it, without worrying about where the data goes.
I would be happy to be enlightened why things should be otherwise.
Admin
My points are 1) vendor tie-in is overrated, esp if you're spending $100,000 + on software and hardware, that ties you in already, and 2) converting data would be just as big a headache as SPs, if not more so, and migrating apps etc. No DBA wants to go through what you described, converting MSSQL to Oracle, regardless of SPs.
Are you saying you use NO SPs, or just don't embed business logic in them, because they're different issues.
I don't think a DB back end would be defining so much application-specific words, or SELECTs. Looks like an awful application design to me.
My 0.02
Dylan
Admin
Precisely. You're not using the data structure for what it was originally intended. It's meant to be a pointer to a lookup, no more, no less. The fact it's frequently useful from a performance standpoint to do so doesn't change the fact that such an action is a hack. It's not what the datastructure was meant to do.
I only don't like them when they're used inappropriately and have never said anything other than that. You seemd to anyway, suggest them as quite a regular solution and not as a performance optimization. That's the only thing they are, and it's critical to remember that.
Actually, you may not be able to, because book indexes don't work like database indexes. I see your point however, the fact that a structure of pointers can be used for counting isn't a new concept, and is an acceptable use of such a strucutre.
That's a non-sequitur. Counting isn't covering, by your own definition.
Admin
It's a parameterized query. The database implicitly caches it in compiled form. After the first time it's used, running the query is just as efficient as calling a stored procedure. I'm a little curious why there's a PARAMS_FIRST and PARAMS_SECOND constant. On the databases that I've used, the place holder for a parameter is "?".
Admin
"the enterprisocity of an application is directly proportionate to the number of constants defined "
what theorem is this under? I don't recall this from college !
Admin
SELECT * doesn't guarantee any field order. To use it safely, you need to access fields by name rather than by position. If you still need the same fields, than except for the extra memory usage, additional columns should be irrelevant. Of course, if you are accessing SELECT * fields by position, you could be setting yourself up for a disaster.
Admin
Admin
>In fact, if you do a test -- you will see that using select * is on average faster that specifying all the columns!
The DB engine might find the results faster on the server, but if you only need data from one field on a 30 field table, how would returning all the fields across a network be faster?
Admin
I've worked with DBA's like that for a very short while. They never wanted to work with me again when I throw the BULLSH*T flag at them and tell them that they'll lazy SOB's.
Admin
Well, really you should have:
public class SqlBits
{
public const int BIT_ZERO = 0;
public const int BIT_ONE = 1;
public const int BIT_POSITION_ZERO = 0;
public const int BIT_POSITION_ONE = 1;
public const int BIT_POSITION_TWO = 2;
// ...
}
public class SqlLetters
{
public const string SPACE_CHAR = BIT_ZERO << BIT_POSITION_SEVEN +
BIT_ZERO << BIT_POSITION_SIX +
BIT_ONE << BIT_POSITION_FIVE +
BIT_ZERO << BIT_POSITION_FOUR +
BIT_ZERO << BIT_POSITION_THREE +
BIT_ZERO << BIT_POSITION_TWO +
BIT_ZERO << BIT_POSITION_ONE +
BIT_ZERO << BIT_POSITION_ZERO;
public const string A_CHAR = //... you get the idea
}
(There needs to be a vomit emoticon like Yahoo IM has...)
Admin
So, until someone names a technique, and you accept that name as a non-hack, it's a hack. Funny thing is that there is a name for a covering index, it's called a "covering index". A well accepted, widely used name. The only reason you won't release it from hack status is because you don't accept that name.
So, the evolution of any technology is always and forever, a hack? How about a mouse? Computers were not originally designed to be used with mice. Oh, wait, I forgot -- if you "accept" it, then it is absolved. BTW, indexes were created specifically to enhance performance. They really have no reason to exist other than to accelerate read operations.
Both. They are used quite regularly as performance optimizations. From the beginning that's what this was about. Besides, you can't use the fact that a technology could be misapplied to categorize that technology as a hack. Maybe if it were likely to cause a level of confusion that often results in misuse. I figured that we were all professionals and it didn't need to be stated that any decision to index data would always be accompanied by an analysis of the costs and benefits and if it wasn't a net gian, it wouldn't be done.
Also, If I suggested them as "quite a regular solution and not as a performance optimization", then what did I suggest them for? My argument has been, from the beginning, that covering indexes are an excellent performance tool.
:-)
Come on.... It's trivial to modify the scenario to "finding out if a page is in the first or second half of a book". I wanted to keep the book example a bit more believable, so I used counting instead of some other read operation. Any type of lookup using the index key or bookmark information as the data is an analogy to a covering index.
Admin
I think the more 'enterprise' a system gets, the more WTF it gets. I took several ABAP training courses (the 'programming' language for SAP) and my jaw was perpetually dropped to the desk. Here I thought this 'enterprise' system was going to be so advanced, so perfectly architected (if that's a word) and developed by the best of the best. I thought I'd be learning top techniques for a top system. Oh. My. God.
It would take a 1000 page tome just to touch the surface of the abject ugliness behind the glossy corporate appearance of that system. For instance no SQL--it's all procedural loops. To do a Join on the Customers table from the Orders table, you instead nest a loop of the entire customers table inside the loop of the orders table (not the real table names--those are 4-digit cryptic German names, but that's another story).
Anyway, bottom line is that there is no santa claus. There is no "enterprise" system that's magically 'better'--better coded, better designed, etc, etc. than what you have.. If you have a system that does what it's supposed to for the users--then going 'enterprise' is probably going to be a few large steps backwards.
--Jim
Admin
And with 9 bits per byte, the computer will run 12.5% faster too!
Admin
Speed of response is hardly the only thing you should be looking at. Select * IS pretty bad.
Admin
Admin
is there another way to select from a table besides "SELECT *"?
a major telecom company generally uses either the global "SELECT *" or its HUGE ADABAS tables, or the far-more-efficient "SELECT", followed by a complete list of all the columns in the table. and remember, these are tables with in excess of 400 columns.
we love job security.
Admin
My bytes go to 11!
Admin
HEY!
db vendor independence? wtf?
If you aren't locked into a db vendor by blowing hundreds of thousands of dollars, YOU AREN'T ENTERPRISE!
Thank you for your time in this matter.
Admin
Ok, I agree, that this is more than just overdone.
But to answer your last sentence: Have you heard, that MySQL uses "LIMIT" instead of "TOP" ...
Admin
Amen! I'm a network guy, and the bane of my life is shitty little DB apps that work well on a LAN being implemented on a WAN. If the server that does the "SELECT *" is on the same LAN as the DB server then it doesn't affect me (its still crap though), but on a network it is poison.
Admin
I think if I found this code it would inspire a new form of SQL injection attack. This SQL causing the injection of my foot up the author's a$$!
Admin
The problem here is that the SQL words are all hard-coded, they should have been stored in a config file.
Admin
Admin
Vital enterprise application are for proactive organizations leveraging collective synergy to think outside the box and formulate their key objectives into a win-win game plan with a quality-driven approach that focuses on empowering key players to drive-up their core competencies and increase expectations with an all-around initiative to drive up the bottom-line.
You forgot best-of-breed!
*smack*
Admin
Thank you very very much. To DBAs who don't like to put 'business logic' in the database : WTF is a schema design all about ? Do you really design a database with no thought at all as to how it's going to actually be used?
Oh, and two words about triggers : referential integrity. It can be important, and unless you think your app programmers are as perfect as your DBAs ( note: it's called sarcasm, folks ) , you might want to guard against corrupting your data as much as possible. Of course, maybe you're using some half-assed database which doesn't include referential integrity support via triggers, or you just don't know how to do such things. I don't know. People build all sorts of crazy systems that end up being mission-critical.
Admin
No, you're not thinking enterprisey. It's:
Enterprisey my ass. Try
Admin
How I love this forum software. Sigh. I give up.
Admin
1) Could very well be.
2) Now why would someone do this? If it's in the database, why duplicate it on another layer?
3) Don't see the logic here ... either you use source control or you don't.
4) Like OO is the end to all means ...
5) Like those database are so easy to replace. Different locking & transaction modells, anyone?
6) That is quite the boldest statement I've ever heard.
And use a lot more ressources (with less performance) than without.
Not _can_, the are debateable. Database agnostic approach can have it's advantages, but all that you're doing is shifting the complexity of a given problem to another layer - and probably adding some (complexity) to it.
l.
Admin
I just have to say how inspiring I found this whole thing. I was moved to enhance it:
(pardon the syntax, I'm not a .net guy, consider it psuedocode in a language where you have an eval)
public const string SELECT = " SELECT ";
public const string STAR = " * ";
public const string FROM = " FROM ";
public const string SELECT_VAR_NAME = "SELECT";
public const string STAR_2VAR_NAME= "STAR";
public const string FROM_VAR_NAME= " FROM ";
public const string SPACE = " ";
String SELECT_STAR_FROM=eval("SELECT_VAR_NAME + STAR_VAR_NAME + FROM_VAR_NAME" );
...
public const string EVAL = "eval";
...
aaaaaaaaaaaaaaaaaaaah!
Admin
This is in many ways similar to code I see in my new job, except it's worse, much worse. The SQL string would actually look like this: (in Java)
public final String UPDATE_LOGON = new StringBuffer().append(SqlWords.UPDATE).append(SqlTables.CREDENTIALS).append(SqlWords.SET).append(SqlColumns.CREDENTIALS_LOGON_NAME). (etc....) .toString()
The reasoning behind this was that earlier versions of the java compiler was pretty darn stupid with regards to string concatenations, which is true, but still.. you gotta factor in the readability of such code when you decide to do such optimizations - thankfully today, the java compiler is much smarter and actually produces code that is faster than the above optimization, so I guess now we can optimize away the previous optimization.
Admin
???,????c???
?????????????
Admin
You can't really write a 100% generic data access layer unless it's a very trivial, read-only application (ie. list the tables in my database, pick a table, show the table columns and values etc...) and/or you use dynamic SQL all over the place essentially making your application a DAL generator at runtime. Essentially you'd end up writing a IDE for creating SQL queries against your database, and unless you're writing a database tool, it doesn't make sense.
Some reporting applications may use this kind of feature however, but usually you'd try to abstract your report designer to stick the domain you are working on, providing simpler expressions for the user to string together and evaluate the expressions at runtime.
For most scenarios, at some point you have to say what table/view/stored proc you are querying, and at some point you have to specify columns. Yes, it's very tedious, especially when the database schema changes.
However, you can use code generation against databases using generic templates. There are a ton of code generating programs that will build the DAL and BLL for you, then you can add custom code on top of that where the code generation can't do the job. CodeSmith is a good tool for this.
Admin
..."you're starting to embed application logic in the database" as opposed to embedding SQL queries in the application code?
WTF?
Why not start doing what my company has started doing. We have always been required to use stored procedures but now we make constants for the stored procedure names and parameter names in the application. Actually we are currently "enterprising" our development process so all of these constants are externalized in a configuration file so that changes (like stored procedure name or parameter changes) can be made without recompiling the application.
All we have to do then is go into the code and modify the classes to handle any new data fields, make sure the data is validated by the application, make sure any new parameters added to the configuration file are used properly.
THEN we recompile the application.
Sincerely,
- SQL Server DBA (being seduced by the Dark Side of Oracle)
Admin
What the hell? If someone puts a single DB Query in the app code, they should be shot. This includes a SP name.
Ever hear of an ORM? Look it up...seriously...
SPs have their place, but they should not contain business logic.
Admin
The point is, should you put any logic in the SPs or should it be outside the database? I am going to agree with the rest of the non-MS world and say "outside the db". The DB should be a receptacle, nothing more. No business logic should reside there. If you need one or two specific SPs for somehting silly, fine...I don't really care that much. But if you are going to use them to actually make business rules and things like that...you are just smoking crack.
And, speaking of this...the whole SP debate is one of those questions I ask when I am hiring someone for my consulting company. If they say "just create a SP", ..no thanks...
Not saying people who use them are stupid, but I have found they just don't understand complex systems enough to know why they are bad. Not enough real experience to know that SPs are not the way to get the job done.
Admin
Yes, I have. I find the best tool for dealing with these sorts of DBAs to be a 2 foot piece of iron rebar with a nice duct tape handle for the API. Evil Bill Paul had another fine tool, a hardened steel spline about 4 inches in diameter and 10 inches long. 30 pounds of hardened steel, with those lovely serrated splines on the business end. It was known throughout the office as "the damn thing."
Coding "application logic" out in the application that could be done with a trigger is stupid, that's why triggers were invented. Ditto for the performance benefits of stored procedures, etc. Use the tools in the ways that make the application perform, not based on some idiot voodoo rules.
Admin
Triggers, stored procedures and the like are great when you are doing data related tasks (moving data from one db to another (i.e replication)) and all those common, day to day DBA tasks. If you put application logic into a stored procedure or trigger , you should just give up your programming rights. Seriously.
Admin
Go sit in the corner.
Admin
...
i'm still laughing...
Admin
Sadly enough, I used the corporate-eese at the beginning of this post for the beginning of a proposal for management. Literally:
The boss word-smithed a few bullet points below that, but never blinked. Sad.
Admin
My company uses an application where the company has put ALL of their procedure code into fields in the db. So they call the procedure which in turn calls the database to see what it should do. Is this normal?!?!?!?!
Admin
???,????????????,????????
???????????????,??????????????,?????????????QQ:183808137
Admin
Actually, you don't need the separating spaces since the original has spaces surrounding each token. Of course, this means that concatenating them results in two spaces between tokens.
Admin
I know!
I mean, seriously - it's obviously:
public const string CHAR_E = "E";
public const string CHAR_L = "L";
public const string CHAR_S = "S";
!!
Admin
There is one good thing that happens when you use constants the way they are used in this WTF and that is that Java compilers do not check the syntactic correctness of your SQL when you compile. This way you at least can avoid typos.
"UDPATE * FORM FOO" will compile whereas
SqlWords.UDPATE + SqlWords.STAR + SqlWords.FORM + "FOO" will not (unless someone defines UDPATE and FORM)
Admin
Use embedded SQL and a preprocessor (like the one Oracle offers) and it will not only check the syntax, but table names, column names etc. as well; and the code might be more readable, but this is rather a matter of taste (at least in Java; in C+SQL, it's no question).
Admin
Amusing. :) I guess one actual reason is to protect against spelling errors in embedded strings, since the compiler will catch an attempt to use the wrong constant. I do know it'd drive me insane though, and not just only because one of the constants in the snippet seems to be ... missspelled. Heh. I'm thinking of the first line in the second class, i.e. SqlQueries.SELECT_ACTIVE_PRODCUTS. I'm pretty sure that ought to end in "PRODUCTS" ... The irony! :D
Admin
I'm not a DBA but just a practical developer with DB knowledge. I have used stored procedures (oracle, pl/sql) for years, but don't recommend them for anything but very simple logic and data handling. Indeed you are embedding application logic, and also spreading it out over multiple environments and languages. It will create a mess in a short time.
Views are, IMHO, the only exception.