So am a few months into a project and I realize that the PKs I chose might not fit enhancement planned for version 2. I also find that moving to either a compound PK or a surrogate PK will require a code change to virtually every part of the system.
For instance my DAL has GetPerson(string PersonID) methods that will need to take other types of parameters to function. Also most of the web pages take querystrings with PKs embedded in them (i.e. /GetPerson?PersonID=BILL)
It got me thinking that I wish I implemented some encapsulation where I protected myself from PK changes. Have abstract methods for placing and reading a PK from a querystring. Likewise instead of passing native types to the DAL, pass a PersonPK object and hide the implementation.
In theory I like the idea, I’m just not sure in practice, it’s possible to prevent this from becoming a “leaky abstraction”. For instance, once it’s time to generate DB calls, I have to crack open the PK object. And there still is going to be dozens of statements to rewrite.
So to my question….Does anybody successfully use PK abstraction in their projects? Has it saved you time? What are the keys to implementing this successfully?
EDIT:
Some of the replies suggest to me that I wasn’t clear on something.
I was never suggesting that I create some abstract primary key column in the database. I was merely contemplating that the Business Logic and front end code be designed in a way that was resistant to PK refactoring.
The encapsulation you’re looking for is the simple use of a surrogate key. That is: an identifier generated by the database (not the end user) to uniquely identify a row of data. They are usually auto-incrementing integers and sometimes GUIDs.
My rule of thumb: If a piece of data stored in the database has the slimmest chance of even appearing in front of the end user (much less being available for editing) then DO NOT use it as a primary key! An example: An email address can uniquely identify a user in a system. Yes, it can be used as a pkey but!
Many devs go as far as automatically creating a surrogate key for every table in the db. This is actually good practice, especially if surrogate keys don’t feel “natural” to you right away.