Your colleague is an idiot.
The solution won't be scalable, the UDF isn't concurrent (same reason as this). And how do you deal with multi-row inserts: this would require a UDF call per row
And migrating to other RDBMS doesn't happen often in real life... you may as well not use SQL Server now and use sequences on Oracle and hope you don't migrate away.
Edit:
Your update states that moving data is for refreshing non-production databases.
In that case, you ignore the identity columns when refreshing. You don't compromise your implementation to make non-prod loading easier. Or use temp tables to track the identity value changes.
Or use processes: we refresh our test system every night from production which avoids the issue entirely. (And ensures our prod backup can be restored too)
Ok, I am making a lot of assumptions (INT instead of VARCHAR(50) being one of them) with this answer, so feel free to correct me if needed. The problem with option B is that it introduces a new join to relate Users to Alerts without any real added benefit. If joining on the UserID, it is best to index the UserID, so you can utilize seeks for your joins.
For Option A, UserID will be the clustering key (index key for the clustered index) on the Users table. UserID will be a nonclustered index key on Alerts table. This will cost 16 bytes per Alert.
For Option B, UserID will be the clustering key on the Users table. UserId will probably be the clustering key in UserMap too, to make joining more efficient. UserKey (assuming this is an INT) would then be a nonclustered index key on the Alerts table. This will cost 4 bytes per Alert. And 20 bytes per UserMap.
Looking at the big picture, one relationship, for Option A, costs 16 bytes of storage, and involves 1 join operation. Whereas, one relationship, for Option B, costs 24 bytes of storage, and involves 2 join operations.
Furthermore, there are a possibility of 340,282,366,920,938,000,000,000,000,000,000,000,000 uniqueidentifiers and only 4,294,967,296 INTs. Implementing a uniqueidentifier to INT map for a this type of relationship could cause unexpected results when you start reusing INTs.
The only reason for creating this type map table, is if you plan on creating a Many to Many relationship between Users and Alerts.
Taking all of this into consideration, I would recommend Option A.
I hope this helps,
Matt
Best Answer
To explain ypercubeᵀᴹ's comment:
If the requirement is one
BatchId
perPartnerId
,Year
,Quarter
,Distribution_Type
then you will need a table such as:Of course you'd need the relevant FK references for
PartnerID
andBatch_ID
as well as something to ensure Quarter is only valid values (1,2,3,4).You would then modify your existing table with the foreign key constraint to ensure the rule is enforced:
From afar, there's a lot more work to be done, but at minimum I'd say you'd need to:
Distribution_Type
to only allow valid values.Distribution_Type
or substitute a shortname/code.Distribution
other than the row identifier.