tags:

views:

35

answers:

2

What I want to do is have a table structure like this:

TypeID   int       not null (foreign key)
ItemID   int       (computed value +1 for each value with same TypeId) 
Data     string

e.g.

TypeId  ItemId  Data 
1       1       "some data"
1       2       "some data"
2       1       "some data"
3       1       "some data"
3       2       "some data"

If I have computed columns as a key, am I going to have issues with concurrency as opposed to identity columns?

+2  A: 

The ItemId column seems to be the result of a ROW_NUMBER OVER(PARTITION BY TypeID) (see the docs) -- is that how you're computing it? As such it's not really suitable as part of a key due to concurrency issues (two transactions inserting rows with the same TypeID, as you mention). But what does that have to do with "how to increment a subset"? What subset of what? And what's your question? Why not just make something else the key instead (typically an artificial auto-increment column)?

Alex Martelli
The above example is somewhat contrived, currently I am using identity columns (and not using the computed "ItemId" above) However I have a requirement from the users for a "meaningful" key to be displayed (the identity column is not appropriate). From what I have read on the subject I did not think that I could simply increment the ItemId for each unique TypeID (and use that as part of a primary key) - but wanted to check if there was a cunning way.
Grayson Mitchell
@Grayson, why does the "suitable to be displayed" column set have to be a _key_? If the display doesn't happen smack in the middle of a transaction (which would be a mess for other reasons too!-), the pair of columns in question _will_ be unique (whether you generate `ItemId` my way, or in any other way;-).
Alex Martelli
You are right, it doesn't. I will do as you suggested. If there was a "reasonable" way of setting up the keys as I was proposing, then (in the context of the database) I could simply things (remove a table). However, that is not a big deal... I just want to make sure I had the "best" option.
Grayson Mitchell
Can't get the syntax quite right on the computed column: ROW_NUMBER() over(partition BY modelentityid ORDER BY datainstanceid DESC) I get the error: "Windowed functions can only appear in the SELECT or ORDER BY clauses."
Grayson Mitchell
What clause are you using row_number in? I'm also perplexed by the message (I've used it in a WHERE clause in the past).
Alex Martelli
I just directly put it in sql server management studio (created a new column, and put the script in the computed column section... I have been googling without much luck on this error
Grayson Mitchell
+2  A: 

I concur with Alex that your computed column could be reproduced with native analytic functionality (ROW_NUMBER, RANK, DENSE_RANK) rather than as a computed column, which likely would require using a CLR or just be better off with a trigger to populate the itemid column in the manner you desire.

I recommend having the itemid column as an identity column. What you want sounds like a surrogate key, a fake key (not to be mixed up with natural & artificial keys) that you can use to reference & display to users without giving away underlying data modelling. What I still don't like about the approach for your situation is that to use it, you still require two pieces of data to get a unique row/record - the typeid and the surrogate key.

OMG Ponies