Last week I posted an article about something I call 'Worst Practices', or WP for short. These are concepts that are on the other end of the spectrum from 'Best Practices' (BP), yet I see them used all too often. My goal in this series is to bring up some of these practices and discuss why they are bad ideas. If we can't always engage in best practices due to time constraints and other practical matters, we can at least try to avoid the worst mistakes!
This week I'd like to discuss object ownership. In my opinion, having an object owned by ANYONE other than DBO is a worst practice! Now let's talk about why.
For those of you new to SQL or maybe just not familiar with the concept, every object (table, view, stored procedure, etc) in SQL has an owner. You get to be an object owner by being a valid database user, having the permissions to create an object, and then by actually creating an object. You can easily see who owns an object using Enterprise Manager, there is a column that shows the owner for each object. The bottom line - by using ownership you can have multiple objects with the same name.
Even if you don't think about it, you're using ownership when you right a select statement that refers to a table, like this:
select * from Categories
When that statement is executed, SQL first tries to execute the statement by assuming that you own the object. 'You' being defined as how you're connected. Let's say I'm current connected as user 'wp'. That means what SQL tries to do is this:
select * from wp.Categories
If that object doesn't exist, it then tries to do this:
select * from dbo.Categories
Having to do that little bit of work to figure out the correct object takes a bit of time. You could make the argument that you should always qualify objects with an owner - but that would be a best practice and I'll leave it to others to write about those for now!
You know and I know that we don't qualify all objects. It takes time, makes the code bigger, maybe a bit less readable. But the number one reason? When we wrote the code, everything was owned by dbo, what would we gain by adding dbo. to every object name?
Take the situation where you've allowed objects to be owned by someone other than dbo. You've got multiple copies of various tables and stored procedures, even two Categories tables, one owned by dbo, one owned by wp. Your development team writes a small app that uses the Categories table...the one owned by dbo, though they don't fully qualify the object. Works fine in testing. You install the app for user WP, it runs, but WP reports that he only sees five categories, but user BP across the hall sees eight? You can step through the code all day and not find an error. BP and WP are using different tables, but it's hidden from the developer!
Contrived? Sure. But lot's of variations of that problem are possible.
Let's move on to part two of why this idea is such a bad idea - ownership chains. If you've take the SQL exams, you know MS likes to throw in a question or two about ownership chains. Avoid them! Keep your permissions as simple and as clear as you can. Again, for those of you who aren't familiar with ownership chains, it's the process SQL has to go through to figure out if a user should be allowed access to an object/data. As long as all objects are owned by the same user, the process is simple. Once the ownership chain is "broken" SQL is forced to do more checking. Books Online has a pretty good explanation, search for "Ownership Chains".
The fact is that few developers or DBA's intentionally use object ownership, it usually happens by mistake. You can prevent it from happening, either by not giving users the permissions to create objects unless they are a member of the db_owner role, or you can let them proceed and then use sp_changeobjectowner to make dbo the owner before you deploy the code. Of the two, I believe the first is the better solution.
Agree with me on this one? Or think I'm way off? Either way, let's discuss it - post your comments by clicking the discussion tab below.