• You might not be seeing a performance hit if your looking at events user by user - but it may get slower the longer you run this model (depending on activity rates?). Also, if using this generated key structure, store your dates as YYYYMMDD, then they'll be indexed by User and in date order (other wise you won't get all the events from one year together?!?)

    Surely you would be better storing this data in a binary column instead of a varchar column. It would take up 16 (GUID) + 4 (date) + 2 (seqno) = 22 bytes instead of the 50ish bytes taken up by the string. This allows for your required generated key (not questioning your choices of your primary key structure here - thats another topic!), just the data size. This would reduce your PK column size by half, improving index performance and size.

    If it's a hidden key, then it doesn't matter that it's binary column (ie not human readable), and it will be more efficient (slightly) to "decode" it as well.

    So you could generate the column data like this:

    DECLARE @UserUID uniqueidentifier

    DECLARE @Date datetime -- or char(8)

    DECLARE @SeqNo smallint

    DECLARE @GeneratedActivityKey binary(22)

    SET @UserUID = NEWID()

    SET @Date = GETDATE()

    SET @SeqNo = 22

    SET @GeneratedActivityKey = CONVERT(CONVERT(binary(16),@UserUID)+CONVERT(binary(4),@Date)+CONVERT(binary(2),@SeqNo))

    SELECT @GeneratedActivityKey

    will give something like

    0x00171A973D6A436E8536A0788420686C00012ABC0012

    Only taking up 22 bytes and still giving you your clustered pages (by user,date,seqno)

    It would probably be more efficient on selects to use a composite key however.