SQL Server 2005 Object Naming Standards - Introduction

Physical database objects are often treated likely the shirttail cousin of modern, object-oriented software development.  How often have you peaked below the covers of a seemingly well-designed and well-constructed application, and been appalled and totally baffled by the underlying physical database structure, with its mish-mash of CustInfoTbl, GENERALINFO and STUD_MASTER (as in student master) tables.  Some would argue that this nastiness can be wrapped up in a data access layer, and the underlying physical structure never seen again.  But the data in your application has to be physically stored somewhere  sooner or later, so you’re likely to run into the structure of that data at some point.  When you do, you’ll have to hope that the person who created it — maybe even you? — followed some simple and predicatable standard so that you can quickly and effectively unravel its mysteries.

In addition, SQL Server 2005 and just about every other database encourages the incorporation of an increasing amount of program logic right into the database itself.  Stored procedures, scalar and table-valued functions, views and other objects — with their increasingly sophisticated programming constructs — means more and more of what we traditionally expect to find in the application layer(s) will be done at the database level using tight, journalized transactions.  Further evidence of this trend is the fact that you can now write your stored procedures in C# directly.  Poorly named physical structure in your database will guarantee that your increasingly complex stored procedures will be ugly and obtuse, as well.

In the past, there were some pretty good excuses for having a lousy set of names for your physical data.  Even some relatively modern databases placed numerous restrictions around the length of name and characteristics that could be used.  In other cases, physical structure was inherited from legacy systems that had even more draconian naming rules.  In the interest of expediency, the old structure names were simply brought into the new database software without change.  Sadly, I have had the personal misfortune of seeing COBOL table structures adopted carte blanche into SQL Server tables — for goodness sake, what was the point of that?  Furthermore, modifications to the structure may have caused even more damage over time.  But a modern database tool not only has a liberal and flexible policy around naming of structures, it usually provides some fairly good tools for modifying them over time.  Hence, there is no longer any good excuse for substandard naming of database structures.

If you need still more convincing, experience has shown that decisions around database object names tend to subconciously influence higher level structures.  In other words, a poorly named table will tend to lead to a poorly named class in the data access layer, which may lead to poorly named application that employs that class.  I know in the object-oriented world that it really shouldn’t work that way, but it likely happens more often that most care to admit.  Clearly named physical structure encourages clear-headed thinking about the rest of the application.  Also, with ever-improving hardware and network performance, I see a future where the logical and physical structure of the data are almost the same.  At the very least, they will start out the same, and only grow apart to address specific issues of performance and functionality.

I have iterated through a series of naming standards for database objects over the years, and I finally stabilized on one particular approach, which I now follow with little variation.  In the next and subsequent  series of posts, I will attempt to methodically document the standard that I now use when creating physical database structure.  It’s hard to tell how long the series will run, but over the course of it, I hope to be able to address most aspects of physical design; tables and columns will constitute the first couple of posts, then procedures and functions, and then beyond that, I’m not quite sure.  I’ll just keep going until I run out of valuable things to say on the subject.

Of course, I encourage you, the reader, to contribute your thoughts, and I’ll do my best to respond to those in this series of posts. At the very least, tell me that I’ve got it all wrong, and I’ll do my best to further explain my logic.  If you present a better idea, I will certainly incorporate that thinking into the ideas presented.  First up, table naming standards, and until then, thanks for reading.
 

Querying the Text of SQL Server 2005 Objects (Improved)

Of course, it goes without saying that just a day or two after my first attempt at a post with some code, I find a much better way to build the DatabaseObject view in my previous post.  Turns out the curiously named sys.sql_modules view takes care of  the quirky way the text of database objects is stored.

I haven’t dissected the sys.sql_modules view (I’m not sure you can even do that), but I suspect that if I could (and did) it would reveal something not a lot different from ugly denormalization that was in the original version of the view.  I’m happy to use sys.sql_modules to eliminate the denormalization code from the original version of the view.

At first, I thought I would yank the earlier version, but then I figured there’s no sin in doing something one way until you find a better way of doing it.  So I’m going to leave both.

A couple of additional comments about the new version of DatabaseObject;  For instance, it may seem a little silly to code lines like;

SysObject.[name] AS nm

or

sys.schemas AS SysSchema

This creates a layer of abstraction between the underlying system view, and any code that is built on top of DatabaseObject.  The system tables can change, and the view can be recoded to reflect these changes without disturbing the code built over top DatabaseObject.  It’s also conceivable that the view could be recoded over top of the system tables of another database, and in theory, the code built on top of it could be moved over without change.

However, the new version of the view still contains the UNION, which I still think is a little ugly.  It’s to bring in the text of synonyms in a format consistent with the other database objects.  You really need to do this if you intend to use DatabaseObject to track down references to table names, which of course, synonym definitions will contain.

Next up — a view that pulls out permissions information in a similar manner.  I’ll see if I can get it right the first time, this time. 

Querying the Text of SQL Server 2005 Objects

I tend to push a fair amount of T-SQL code into the SQL Server database, so one of the things I find myself wanting to do fairly frequently is query the text of objects that have been created.  For example, let’s assume that a particular table name has changed, and you want to find all references to this table in the code of your stored procedures, functions, views and other database objects.  This rather mundane, but important, capability seems to be overlooked with the SQL Server team.  The solution, under normal circumstances, is to dig around SQL Server metadata.  Complex, and prone to error, it would seem.

SQL Server, of course, has system tables that contain this information, but there is some quirkiness in how it stores it.  The text of most (but not all) objects is stored in the text column of the syscomments table.  However, long texts will be split over multiple rows — likely a holdover when procedures were likely a whole lot simpler than they are today.  There’s a temptation to simply use a LIKE clause against this column, but you may miss an instance of the target string if it just happens to be split across multiple rows.  To avoid this, you really have to reassemble the rows into one long line of text.

While solving this problem, it also makes sense to do the necessary JOINs to bring together row from related system tables so that you actually have some result rows with useful information about the database objects.  The view DatabaseObject.sql responds to these requirements.

Its very simple to use.  Of course, you’ll first need to create the view using the .sql file attached.  Then, let’s say you want to find all instances of the table name dbo.Person, in all of database objects.  You would use something like the following.

SELECT
	*
FROM
	dbo.DatabaseObject
WHERE
	txt LIKE '%dbo.Person%'

Just like any old, simple table; no fuss, no muss.  The SQL Server documentation has lots of useful information on the LIKE clause that will allow you to find just about any combination of characters.

The next post will provide some additional information about how and why the code looks the way it does, but for the time being, you now have a method of tracking down those pesky strings of text that may have been missing in the past.   Have fun!

Introducing…butzi.ca/tech

Welcome to butzi.ca/tech.  Given that this is my first blogging effort, I’m going to stay away from narrowly defined content rules or making brash promises about posting frequencies, but it’s safe to say this blog will tend to meander around technical — mostly software — subjects that I run across from day-to-day.  Hopefully, there will be some fairly well constructed ‘how to’ postings describing software techniques that I have found useful in my work.  Some opinions about future technical directions will probably find their way in, as will the odd review of technically-oriented books I have read and from which I feel I have benefitted.  Also, given that I’m a sucker for the latest gadget, I may also wander into the area of consumer electronics from time-to-time.  Hopefully, over time, and assuming that I’m able to contribute steadily, the blog will take it’s own course, and I’ll just be along for the ride.

About the only thing I want to really hope to avoid is lambasting anybody’s product or service or idea.  If I don’t write about it, it can be assumed that I either have no useful knowledge of the subject, or don’t have anything good to say about it. 

I’m not big on talking about myself, so I’ll expose my resume as and when it relates to the material being presented.  Suffice to say for now that I got my first computer in 1977 (TRS-80 Model I with Level 2 BASIC) and wrote my first line of code for money in 1980.  I’ve had a series of positions of increasing management responsibility up until the fall of 2005.  At that time, I realized that people management was the ‘gift that just keeps on giving’, so with the co-operation of my employer, I chucked it all in and returned to the ranks of hands-on-the-keyboard coder.  I have been happily ensconced in that role since then.  I’ve got some ideas as to where I go from here, but I think I’ll just let those come out in due course in the days (and postings) ahead.

One of the things that got me out of my management grind was the apparent quality of the current generation of Microsoft tools; Visual Studio 2005 and SQL Server 2005 for the most part.  I’m not blind to Microsoft’s faults, but I’m pretty enthusiastic about these tools, and haven’t found much need to look for better products elsewhere.  The major exception to that rule is the various Dundas charting tools.  I have used this combination of tools to develop an application for the integration and presentation of corporate data, and found them very capable, if not quite complex.  I’ll be talking about them more in the future, for sure.

Welcome aboard, thank you for reading, and let me know what you think!