views:

27

answers:

3

This is just a general question irrespective of database architecture. I am maintaining an ASP.NET web application. The structure is such that,

Say on 'Add a new employee' webform

  • The primary key (or the record id to be saved with) is initially loaded on form load event & displayed as a label
    • So when the form loads, the record id to save with is shown to the user

Positives:

  • End user already knows what the id/serial of the form is (even before he saves the form)
  • So on form save when he is directed to gridview screen (with all entries) he can search recrods easily (although the most recent one is at the top anyway)

Negatives:

  • If he does not save the form, say he just cancels after loading the data entry form, the id/key initially fetched is wasted (in my case it is a sequence field fetched on form load from database)

What do you guys do in these scenarios ? Which approach would you recommend for 'web applications'? And how to facilitate the user with a different approach ? Is our current approach recommended (To me,it wastes the ids/sequence from database)

+1  A: 

I'd always recommend not presenting the identity field value for the record being created until the record has been created. The "create a temporary placeholder record first to obtain the identity field value ahead of time" approach can, as you mention, result in wasted IDs, unless you have a process in place to reclaim them.

You can always pop-up a message box when the user presses save that tells them the identity field value of the newly created record.

Rob
I hate popups that I have to dismiss. They are a nuisance and get way too much in the way of the flow of work. If you must take the approach of only to determine the id on save, add it as a message to the next form...(the gridview) screen. By the way, why is it so horrible to 'waste' id's? It would seem to me they are pretty cheap and bountiful (when is the last time you ran out of what can be stored in an int32, and if it really matters then use an int64). The user experience is way more important than wasting a couple of id values.
Marjan Venema
@Marjan - the OP has intimated that the end user needs to know the ID of the record saved, perhap to write onto a paper form that's being entered into an electronic system, hypothetically. Popups requiring me to dismiss them *as part of a defined process* don't bother me in the slightest. That's personal taste though. Another reason *not* to pre-allocate IDs is that if someones app crashes after pre-allocating one, it'll leave a "ghost" record in the database...
Rob
.... which would require having some form of offline process to clean them up. Bleurgh!
Rob
@Rob: Popups always bother me. They are intrusive. But yes, that is a matter of preference, though I find most users tend to agree. You don't have to create an entire record just to "reserve" a counter value for use as an primary key.
Marjan Venema
@Rob, just to expand on that last statement: I use ORM's and don't have auto-increment columns, but simply id columns that get their value through the ORM accessing a counter / auto-increment table / identity creator table/column to obtain new id values.
Marjan Venema
Ermm, popups are confusing in a multiuser environment. On a closing day where users are just punching entries like machines, they don't remember ID's much and in some environments the entries from other users supersede theirs. But that is certainly manageable.
Popo
+1  A: 

In this situation you could use a GUID created by the application itself. The database would then only have the PK set to be a Unique Identifier (GUID) and that it must not be null. In this situation you are not wasting any unique keys as each call to get a new GUID should be definition produce a (mathmatically) unique identifier. It is worth noting that if you use this method, it is best to make sure your PK is not set up to be clustered. The resulting index reorganisation upon insert could quickly result in an application that suffers performance hits.

Paul Hadfield
I get the impression from the OPs question that the end user will be using the ID, and I've learnt (the hard way!) never to give users GUIDs as something they have to work with. For uniqueness they're fantastic, but they don't roll off the tongue quite as easily as "the new employee id is 4,803"! =) That said, a very good point about not clustering your PK when it's a GUID!
Rob
Popo
+1  A: 

For one: I wouldn't care so much about wasted id values. When you are in danger of running out of int32 values (and when has that happened to you last?), use int64. The user experience is way much more important than wasting a few id values.

Having said that, I would not want the primary key to be anything the user would want to type in. If you are having a primary key that users need to type in, chances are it then is (or will be requested to be) more than just an int32/64 value and carries (will carry) meaning in its composition and/or formatting. Primary keys should not have that. (Tons of reasons google for meaningless primary keys or other such terms).

If you need a meaningful key, make it a secondary index that is in no way related to the primary key. If a part of that is still a sequential number taken from some counter value in your database. Decide whether functionally it is a problem for gaps to appear in the sequence. (The tax people generally don't want gaps in invoice numbers). If functionally it is no problem, then certainly don't start worrying about it technically. If functionally it is a problem, then yes, you have no option but to wait for the save in order to show it to the user. But, please, when you do, don't do it in a popup. They are horribly intrusive as they have to be dismissed. Just put up an informative message on the screen where the user is sent after (s)he saves the new employee. Much like gmail is telling you about actions you have performed just above the list of messages.

Marjan Venema
Thanks for the detailed reply Marjan. I am not entering the primary keys on form at all. You are absolutely right about the popup confusion, previously I tried that with a stored procedure returning the key but users got all confused on which record they saved after entering 2 or 3 entries as their entries got superseded in multi user environment.
Popo