How to generate globally unique ids for different tables of the same database?Stored Procedure to return dynamically created table dataHow can I keep two tables in two different databases with different schemas the same in real-time?Deadlocks From Locks on Same Temporary Tables In Different ProcessesBest Possible Solution for Reporting Mirroring or Replication?Index optimization for table that is truncated every dayDatabase design considerations for unused columns with every table has same schemaQuery that Searches Duplicate Values Based on a Specific ValueGenerate an increment ID that is unique for a given value of a foreign keyTwo SQL Server databases share the same MDF and LDF files but have different dataHow do I compare Schemas for Multiple Databases to a True Copy?
How to write cleanly even if my character uses expletive language?
Employee lack of ownership
What does it mean to make a bootable LiveUSB?
Instead of Universal Basic Income, why not Universal Basic NEEDS?
How is the Swiss post e-voting system supposed to work, and how was it wrong?
How do I hide Chekhov's Gun?
Fantasy series where a Vietnam vet is transported to a fantasy land
Backup with Hanoi Strategy
Life insurance that covers only simultaneous/dual deaths
Is it possible to upcast ritual spells?
What options are left, if Britain cannot decide?
"Se" and "le" with "usted", but always "te" with "tú"
Is having access to past exams cheating and, if yes, could it be proven just by a good grade?
Will a pinhole camera work with instant film?
How to explain that I do not want to visit a country due to personal safety concern?
Rules about breaking the rules. How do I do it well?
Python if-else code style for reduced code
Are the common programs (for example: "ls", "cat") in Linux and BSD come from the same source code?
Why doesn't the EU now just force the UK to choose between referendum and no-deal?
Would it take an action or something similar to activate the blindsight property of a Dragon Mask?
Why are there 40 737 Max planes in flight when they have been grounded as not airworthy?
I need to drive a 7/16" nut but am unsure how to use the socket I bought for my screwdriver
How to change two letters closest to a string and one letter immediately after a string using notepad++
How to make healing in an exploration game interesting
How to generate globally unique ids for different tables of the same database?
Stored Procedure to return dynamically created table dataHow can I keep two tables in two different databases with different schemas the same in real-time?Deadlocks From Locks on Same Temporary Tables In Different ProcessesBest Possible Solution for Reporting Mirroring or Replication?Index optimization for table that is truncated every dayDatabase design considerations for unused columns with every table has same schemaQuery that Searches Duplicate Values Based on a Specific ValueGenerate an increment ID that is unique for a given value of a foreign keyTwo SQL Server databases share the same MDF and LDF files but have different dataHow do I compare Schemas for Multiple Databases to a True Copy?
In a production system on SQL Server all ids (mostly PKs) in all tables are generated automatically and I am informed that they are unique globally. I mean no 2 ids are the same in the database, even if tables are different. I want to know how this can be done? If there are multiple ways please list them all. Thanks.
sql-server unique-constraint
add a comment |
In a production system on SQL Server all ids (mostly PKs) in all tables are generated automatically and I am informed that they are unique globally. I mean no 2 ids are the same in the database, even if tables are different. I want to know how this can be done? If there are multiple ways please list them all. Thanks.
sql-server unique-constraint
2
NEWID()
has this functionality. Please check this answer stackoverflow.com/a/28218084/4608204
– EzLo
yesterday
add a comment |
In a production system on SQL Server all ids (mostly PKs) in all tables are generated automatically and I am informed that they are unique globally. I mean no 2 ids are the same in the database, even if tables are different. I want to know how this can be done? If there are multiple ways please list them all. Thanks.
sql-server unique-constraint
In a production system on SQL Server all ids (mostly PKs) in all tables are generated automatically and I am informed that they are unique globally. I mean no 2 ids are the same in the database, even if tables are different. I want to know how this can be done? If there are multiple ways please list them all. Thanks.
sql-server unique-constraint
sql-server unique-constraint
edited 2 hours ago
Michael Green
15k83062
15k83062
asked yesterday
ElGrigElGrig
67815
67815
2
NEWID()
has this functionality. Please check this answer stackoverflow.com/a/28218084/4608204
– EzLo
yesterday
add a comment |
2
NEWID()
has this functionality. Please check this answer stackoverflow.com/a/28218084/4608204
– EzLo
yesterday
2
2
NEWID()
has this functionality. Please check this answer stackoverflow.com/a/28218084/4608204– EzLo
yesterday
NEWID()
has this functionality. Please check this answer stackoverflow.com/a/28218084/4608204– EzLo
yesterday
add a comment |
3 Answers
3
active
oldest
votes
Back in the day we had an ID
table. Single column, single row with an int
value. Every transaction first updated that table to get a new value, which was then used wherever it was needed. This was, of course, a great source of concurrency errors.
Later, sequences were introduced. A single sequence used across the whole database would show the behaviour you describe. There's an example in the documentation that illustrates this:
CREATE TABLE Audit.ProcessEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different table
<other columns>
);
CREATE TABLE Audit.ErrorEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different tables
<other columns>
);
I've edited the example to highlight this usage.
An identical outcome could be achieved by generating the globally unique numbers in the application code, before they are passed to the database. Were I to implement this I imagine it would be as a static method of some utility class compiled into the executable (though other implementations would be possible). Say the application needs to write a customer's details to the database. As it is marshaling the customer name, address, telephone number etc. it also generates a new global ID. The ID is passed to the INSERT statement (or stored procedure) as just another parameter value.
Whether the ID values are produced by the application architectural tier or the database tier would depend on the specific design considerations. If the app can scale out coordination between instances becomes problematic. After an application re-start the code must figure out the next value to use. The DB server has these features, and others, written into it already.
What I would definitely not do is have the application call the database just for the next ID, then marshal that with the business data into an INSERT. That's too many round-trips to the database when only one is required.
add a comment |
For unique ID values in the same table, I presume you are aware of the commonly used IDENTITY
option, usually using a 32-bit value starting from 1 (so for defining a PK this way something like ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY
). You can of course use a larger (BIGINT
) if the table might need more than 2,147,483,647 rows.
SQL Server has the option of defining your own sequence which can be shared between multiple tables, potentially all of them. See https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql for details. You then define each ID column as ID INTEGER DEFAULT NEXT VALUE FOR The_sequence_You_Defined PRIMARY KEY
. There are some things to be aware of here though. Unlike with IDENTITY
you are not blocked from dropping in any old value (that isn't already present) as the sequence value is applied by the default only if one is not explicitly given, which could be problematical. Also, using a sequence performs a little more slowly and can become a bottleneck as all tables rely on the same object, though both of these issues are only a concern if your database sees a lot of insert activity in a short space of time. NEXT VALUE FOR The_sequence_You_Defined
can be used elsewhere too (i.e. SET @someVariable = NEXT VALUE FOR The_sequence_You_Defined;
) which means that if you need IDs to be generated elsewhere in your application logic you can have it done this way (in fact I've seen this used even for a single identity, not just sharing a sequence between multiple objects).
A more hacky approach could be to use a BIGINT
for each identity column and start each at a different multiple of (for example) 4,000,000,000. This will work in other DBs and avoids the bottleneck issue, but does double the size of your key and could give you a maintenance nightmare if you accidentally define two tables with IDs starting at the same point. You may wish to add check constraints to make sure an identity value defined this way can't overflow into another value's number space, which adds back in some performance concern.
If you don't mind the larger key, then UUIDs are useful and have the added advantage of being unique between databases (all databases, as the name suggests) not just between tables in one database. As with a sequence these are applied with a default constraint, i.e. ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID()
. These are 128-bit values though, twice the size of BITINT
and four times the size of a "standard" 32-bit INTEGER
. If you are concerned about the potential for extra fragmentation caused by the randomness of v4 UUIDs you can use NEWSEQUENTIALID()
instead of NEWID()
which should still be unique enough (the chance of a collision in the lifetime of this galaxy is vanishingly small).
add a comment |
First of all, I have to mention that I did not work with SQL Server, so I cannot point out some specific features.
I have two concepts of how this can be done on my mind:
- One sequence to rule them all: This concept is easy as it sounds. You have one sequence which is responsible for generating IDs for every row inserted to any table. In my last job, we were using this concept. Implementation depends on a lot of circumstances, so I will let you decide. But one way is to have some stored procedure which will retrieve the next value of the sequence before any insert.
- Timestamp: You can somehow incorporate timestamps into your IDs
In the SQL Server world you can refer to this:
NEWID() documentation - newid is compliant with RFC4122
New contributor
2
How would a timestamp prevent duplicate ids? Events can happen simultaneously.
– ddunn801
21 hours ago
3
Timestamps don't prevent them, but timestamp + other uniqueness is a fairly common tactic for building unique identifiers.NEWSEQUENTIALID()
in sql server utilizes this, for example.
– dvlsg
13 hours ago
Yeah... that's what I meant. :-)
– Tomáš Na'vi Koválik
4 hours ago
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "182"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f232120%2fhow-to-generate-globally-unique-ids-for-different-tables-of-the-same-database%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Back in the day we had an ID
table. Single column, single row with an int
value. Every transaction first updated that table to get a new value, which was then used wherever it was needed. This was, of course, a great source of concurrency errors.
Later, sequences were introduced. A single sequence used across the whole database would show the behaviour you describe. There's an example in the documentation that illustrates this:
CREATE TABLE Audit.ProcessEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different table
<other columns>
);
CREATE TABLE Audit.ErrorEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different tables
<other columns>
);
I've edited the example to highlight this usage.
An identical outcome could be achieved by generating the globally unique numbers in the application code, before they are passed to the database. Were I to implement this I imagine it would be as a static method of some utility class compiled into the executable (though other implementations would be possible). Say the application needs to write a customer's details to the database. As it is marshaling the customer name, address, telephone number etc. it also generates a new global ID. The ID is passed to the INSERT statement (or stored procedure) as just another parameter value.
Whether the ID values are produced by the application architectural tier or the database tier would depend on the specific design considerations. If the app can scale out coordination between instances becomes problematic. After an application re-start the code must figure out the next value to use. The DB server has these features, and others, written into it already.
What I would definitely not do is have the application call the database just for the next ID, then marshal that with the business data into an INSERT. That's too many round-trips to the database when only one is required.
add a comment |
Back in the day we had an ID
table. Single column, single row with an int
value. Every transaction first updated that table to get a new value, which was then used wherever it was needed. This was, of course, a great source of concurrency errors.
Later, sequences were introduced. A single sequence used across the whole database would show the behaviour you describe. There's an example in the documentation that illustrates this:
CREATE TABLE Audit.ProcessEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different table
<other columns>
);
CREATE TABLE Audit.ErrorEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different tables
<other columns>
);
I've edited the example to highlight this usage.
An identical outcome could be achieved by generating the globally unique numbers in the application code, before they are passed to the database. Were I to implement this I imagine it would be as a static method of some utility class compiled into the executable (though other implementations would be possible). Say the application needs to write a customer's details to the database. As it is marshaling the customer name, address, telephone number etc. it also generates a new global ID. The ID is passed to the INSERT statement (or stored procedure) as just another parameter value.
Whether the ID values are produced by the application architectural tier or the database tier would depend on the specific design considerations. If the app can scale out coordination between instances becomes problematic. After an application re-start the code must figure out the next value to use. The DB server has these features, and others, written into it already.
What I would definitely not do is have the application call the database just for the next ID, then marshal that with the business data into an INSERT. That's too many round-trips to the database when only one is required.
add a comment |
Back in the day we had an ID
table. Single column, single row with an int
value. Every transaction first updated that table to get a new value, which was then used wherever it was needed. This was, of course, a great source of concurrency errors.
Later, sequences were introduced. A single sequence used across the whole database would show the behaviour you describe. There's an example in the documentation that illustrates this:
CREATE TABLE Audit.ProcessEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different table
<other columns>
);
CREATE TABLE Audit.ErrorEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different tables
<other columns>
);
I've edited the example to highlight this usage.
An identical outcome could be achieved by generating the globally unique numbers in the application code, before they are passed to the database. Were I to implement this I imagine it would be as a static method of some utility class compiled into the executable (though other implementations would be possible). Say the application needs to write a customer's details to the database. As it is marshaling the customer name, address, telephone number etc. it also generates a new global ID. The ID is passed to the INSERT statement (or stored procedure) as just another parameter value.
Whether the ID values are produced by the application architectural tier or the database tier would depend on the specific design considerations. If the app can scale out coordination between instances becomes problematic. After an application re-start the code must figure out the next value to use. The DB server has these features, and others, written into it already.
What I would definitely not do is have the application call the database just for the next ID, then marshal that with the business data into an INSERT. That's too many round-trips to the database when only one is required.
Back in the day we had an ID
table. Single column, single row with an int
value. Every transaction first updated that table to get a new value, which was then used wherever it was needed. This was, of course, a great source of concurrency errors.
Later, sequences were introduced. A single sequence used across the whole database would show the behaviour you describe. There's an example in the documentation that illustrates this:
CREATE TABLE Audit.ProcessEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different table
<other columns>
);
CREATE TABLE Audit.ErrorEvents
(
EventID int DEFAULT (NEXT VALUE FOR Audit.EventCounter), -- same sequence, different tables
<other columns>
);
I've edited the example to highlight this usage.
An identical outcome could be achieved by generating the globally unique numbers in the application code, before they are passed to the database. Were I to implement this I imagine it would be as a static method of some utility class compiled into the executable (though other implementations would be possible). Say the application needs to write a customer's details to the database. As it is marshaling the customer name, address, telephone number etc. it also generates a new global ID. The ID is passed to the INSERT statement (or stored procedure) as just another parameter value.
Whether the ID values are produced by the application architectural tier or the database tier would depend on the specific design considerations. If the app can scale out coordination between instances becomes problematic. After an application re-start the code must figure out the next value to use. The DB server has these features, and others, written into it already.
What I would definitely not do is have the application call the database just for the next ID, then marshal that with the business data into an INSERT. That's too many round-trips to the database when only one is required.
edited 2 hours ago
answered yesterday
Michael GreenMichael Green
15k83062
15k83062
add a comment |
add a comment |
For unique ID values in the same table, I presume you are aware of the commonly used IDENTITY
option, usually using a 32-bit value starting from 1 (so for defining a PK this way something like ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY
). You can of course use a larger (BIGINT
) if the table might need more than 2,147,483,647 rows.
SQL Server has the option of defining your own sequence which can be shared between multiple tables, potentially all of them. See https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql for details. You then define each ID column as ID INTEGER DEFAULT NEXT VALUE FOR The_sequence_You_Defined PRIMARY KEY
. There are some things to be aware of here though. Unlike with IDENTITY
you are not blocked from dropping in any old value (that isn't already present) as the sequence value is applied by the default only if one is not explicitly given, which could be problematical. Also, using a sequence performs a little more slowly and can become a bottleneck as all tables rely on the same object, though both of these issues are only a concern if your database sees a lot of insert activity in a short space of time. NEXT VALUE FOR The_sequence_You_Defined
can be used elsewhere too (i.e. SET @someVariable = NEXT VALUE FOR The_sequence_You_Defined;
) which means that if you need IDs to be generated elsewhere in your application logic you can have it done this way (in fact I've seen this used even for a single identity, not just sharing a sequence between multiple objects).
A more hacky approach could be to use a BIGINT
for each identity column and start each at a different multiple of (for example) 4,000,000,000. This will work in other DBs and avoids the bottleneck issue, but does double the size of your key and could give you a maintenance nightmare if you accidentally define two tables with IDs starting at the same point. You may wish to add check constraints to make sure an identity value defined this way can't overflow into another value's number space, which adds back in some performance concern.
If you don't mind the larger key, then UUIDs are useful and have the added advantage of being unique between databases (all databases, as the name suggests) not just between tables in one database. As with a sequence these are applied with a default constraint, i.e. ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID()
. These are 128-bit values though, twice the size of BITINT
and four times the size of a "standard" 32-bit INTEGER
. If you are concerned about the potential for extra fragmentation caused by the randomness of v4 UUIDs you can use NEWSEQUENTIALID()
instead of NEWID()
which should still be unique enough (the chance of a collision in the lifetime of this galaxy is vanishingly small).
add a comment |
For unique ID values in the same table, I presume you are aware of the commonly used IDENTITY
option, usually using a 32-bit value starting from 1 (so for defining a PK this way something like ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY
). You can of course use a larger (BIGINT
) if the table might need more than 2,147,483,647 rows.
SQL Server has the option of defining your own sequence which can be shared between multiple tables, potentially all of them. See https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql for details. You then define each ID column as ID INTEGER DEFAULT NEXT VALUE FOR The_sequence_You_Defined PRIMARY KEY
. There are some things to be aware of here though. Unlike with IDENTITY
you are not blocked from dropping in any old value (that isn't already present) as the sequence value is applied by the default only if one is not explicitly given, which could be problematical. Also, using a sequence performs a little more slowly and can become a bottleneck as all tables rely on the same object, though both of these issues are only a concern if your database sees a lot of insert activity in a short space of time. NEXT VALUE FOR The_sequence_You_Defined
can be used elsewhere too (i.e. SET @someVariable = NEXT VALUE FOR The_sequence_You_Defined;
) which means that if you need IDs to be generated elsewhere in your application logic you can have it done this way (in fact I've seen this used even for a single identity, not just sharing a sequence between multiple objects).
A more hacky approach could be to use a BIGINT
for each identity column and start each at a different multiple of (for example) 4,000,000,000. This will work in other DBs and avoids the bottleneck issue, but does double the size of your key and could give you a maintenance nightmare if you accidentally define two tables with IDs starting at the same point. You may wish to add check constraints to make sure an identity value defined this way can't overflow into another value's number space, which adds back in some performance concern.
If you don't mind the larger key, then UUIDs are useful and have the added advantage of being unique between databases (all databases, as the name suggests) not just between tables in one database. As with a sequence these are applied with a default constraint, i.e. ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID()
. These are 128-bit values though, twice the size of BITINT
and four times the size of a "standard" 32-bit INTEGER
. If you are concerned about the potential for extra fragmentation caused by the randomness of v4 UUIDs you can use NEWSEQUENTIALID()
instead of NEWID()
which should still be unique enough (the chance of a collision in the lifetime of this galaxy is vanishingly small).
add a comment |
For unique ID values in the same table, I presume you are aware of the commonly used IDENTITY
option, usually using a 32-bit value starting from 1 (so for defining a PK this way something like ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY
). You can of course use a larger (BIGINT
) if the table might need more than 2,147,483,647 rows.
SQL Server has the option of defining your own sequence which can be shared between multiple tables, potentially all of them. See https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql for details. You then define each ID column as ID INTEGER DEFAULT NEXT VALUE FOR The_sequence_You_Defined PRIMARY KEY
. There are some things to be aware of here though. Unlike with IDENTITY
you are not blocked from dropping in any old value (that isn't already present) as the sequence value is applied by the default only if one is not explicitly given, which could be problematical. Also, using a sequence performs a little more slowly and can become a bottleneck as all tables rely on the same object, though both of these issues are only a concern if your database sees a lot of insert activity in a short space of time. NEXT VALUE FOR The_sequence_You_Defined
can be used elsewhere too (i.e. SET @someVariable = NEXT VALUE FOR The_sequence_You_Defined;
) which means that if you need IDs to be generated elsewhere in your application logic you can have it done this way (in fact I've seen this used even for a single identity, not just sharing a sequence between multiple objects).
A more hacky approach could be to use a BIGINT
for each identity column and start each at a different multiple of (for example) 4,000,000,000. This will work in other DBs and avoids the bottleneck issue, but does double the size of your key and could give you a maintenance nightmare if you accidentally define two tables with IDs starting at the same point. You may wish to add check constraints to make sure an identity value defined this way can't overflow into another value's number space, which adds back in some performance concern.
If you don't mind the larger key, then UUIDs are useful and have the added advantage of being unique between databases (all databases, as the name suggests) not just between tables in one database. As with a sequence these are applied with a default constraint, i.e. ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID()
. These are 128-bit values though, twice the size of BITINT
and four times the size of a "standard" 32-bit INTEGER
. If you are concerned about the potential for extra fragmentation caused by the randomness of v4 UUIDs you can use NEWSEQUENTIALID()
instead of NEWID()
which should still be unique enough (the chance of a collision in the lifetime of this galaxy is vanishingly small).
For unique ID values in the same table, I presume you are aware of the commonly used IDENTITY
option, usually using a 32-bit value starting from 1 (so for defining a PK this way something like ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY
). You can of course use a larger (BIGINT
) if the table might need more than 2,147,483,647 rows.
SQL Server has the option of defining your own sequence which can be shared between multiple tables, potentially all of them. See https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql for details. You then define each ID column as ID INTEGER DEFAULT NEXT VALUE FOR The_sequence_You_Defined PRIMARY KEY
. There are some things to be aware of here though. Unlike with IDENTITY
you are not blocked from dropping in any old value (that isn't already present) as the sequence value is applied by the default only if one is not explicitly given, which could be problematical. Also, using a sequence performs a little more slowly and can become a bottleneck as all tables rely on the same object, though both of these issues are only a concern if your database sees a lot of insert activity in a short space of time. NEXT VALUE FOR The_sequence_You_Defined
can be used elsewhere too (i.e. SET @someVariable = NEXT VALUE FOR The_sequence_You_Defined;
) which means that if you need IDs to be generated elsewhere in your application logic you can have it done this way (in fact I've seen this used even for a single identity, not just sharing a sequence between multiple objects).
A more hacky approach could be to use a BIGINT
for each identity column and start each at a different multiple of (for example) 4,000,000,000. This will work in other DBs and avoids the bottleneck issue, but does double the size of your key and could give you a maintenance nightmare if you accidentally define two tables with IDs starting at the same point. You may wish to add check constraints to make sure an identity value defined this way can't overflow into another value's number space, which adds back in some performance concern.
If you don't mind the larger key, then UUIDs are useful and have the added advantage of being unique between databases (all databases, as the name suggests) not just between tables in one database. As with a sequence these are applied with a default constraint, i.e. ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID()
. These are 128-bit values though, twice the size of BITINT
and four times the size of a "standard" 32-bit INTEGER
. If you are concerned about the potential for extra fragmentation caused by the randomness of v4 UUIDs you can use NEWSEQUENTIALID()
instead of NEWID()
which should still be unique enough (the chance of a collision in the lifetime of this galaxy is vanishingly small).
answered yesterday
David SpillettDavid Spillett
22.9k23267
22.9k23267
add a comment |
add a comment |
First of all, I have to mention that I did not work with SQL Server, so I cannot point out some specific features.
I have two concepts of how this can be done on my mind:
- One sequence to rule them all: This concept is easy as it sounds. You have one sequence which is responsible for generating IDs for every row inserted to any table. In my last job, we were using this concept. Implementation depends on a lot of circumstances, so I will let you decide. But one way is to have some stored procedure which will retrieve the next value of the sequence before any insert.
- Timestamp: You can somehow incorporate timestamps into your IDs
In the SQL Server world you can refer to this:
NEWID() documentation - newid is compliant with RFC4122
New contributor
2
How would a timestamp prevent duplicate ids? Events can happen simultaneously.
– ddunn801
21 hours ago
3
Timestamps don't prevent them, but timestamp + other uniqueness is a fairly common tactic for building unique identifiers.NEWSEQUENTIALID()
in sql server utilizes this, for example.
– dvlsg
13 hours ago
Yeah... that's what I meant. :-)
– Tomáš Na'vi Koválik
4 hours ago
add a comment |
First of all, I have to mention that I did not work with SQL Server, so I cannot point out some specific features.
I have two concepts of how this can be done on my mind:
- One sequence to rule them all: This concept is easy as it sounds. You have one sequence which is responsible for generating IDs for every row inserted to any table. In my last job, we were using this concept. Implementation depends on a lot of circumstances, so I will let you decide. But one way is to have some stored procedure which will retrieve the next value of the sequence before any insert.
- Timestamp: You can somehow incorporate timestamps into your IDs
In the SQL Server world you can refer to this:
NEWID() documentation - newid is compliant with RFC4122
New contributor
2
How would a timestamp prevent duplicate ids? Events can happen simultaneously.
– ddunn801
21 hours ago
3
Timestamps don't prevent them, but timestamp + other uniqueness is a fairly common tactic for building unique identifiers.NEWSEQUENTIALID()
in sql server utilizes this, for example.
– dvlsg
13 hours ago
Yeah... that's what I meant. :-)
– Tomáš Na'vi Koválik
4 hours ago
add a comment |
First of all, I have to mention that I did not work with SQL Server, so I cannot point out some specific features.
I have two concepts of how this can be done on my mind:
- One sequence to rule them all: This concept is easy as it sounds. You have one sequence which is responsible for generating IDs for every row inserted to any table. In my last job, we were using this concept. Implementation depends on a lot of circumstances, so I will let you decide. But one way is to have some stored procedure which will retrieve the next value of the sequence before any insert.
- Timestamp: You can somehow incorporate timestamps into your IDs
In the SQL Server world you can refer to this:
NEWID() documentation - newid is compliant with RFC4122
New contributor
First of all, I have to mention that I did not work with SQL Server, so I cannot point out some specific features.
I have two concepts of how this can be done on my mind:
- One sequence to rule them all: This concept is easy as it sounds. You have one sequence which is responsible for generating IDs for every row inserted to any table. In my last job, we were using this concept. Implementation depends on a lot of circumstances, so I will let you decide. But one way is to have some stored procedure which will retrieve the next value of the sequence before any insert.
- Timestamp: You can somehow incorporate timestamps into your IDs
In the SQL Server world you can refer to this:
NEWID() documentation - newid is compliant with RFC4122
New contributor
New contributor
answered yesterday
Tomáš Na'vi KoválikTomáš Na'vi Koválik
312
312
New contributor
New contributor
2
How would a timestamp prevent duplicate ids? Events can happen simultaneously.
– ddunn801
21 hours ago
3
Timestamps don't prevent them, but timestamp + other uniqueness is a fairly common tactic for building unique identifiers.NEWSEQUENTIALID()
in sql server utilizes this, for example.
– dvlsg
13 hours ago
Yeah... that's what I meant. :-)
– Tomáš Na'vi Koválik
4 hours ago
add a comment |
2
How would a timestamp prevent duplicate ids? Events can happen simultaneously.
– ddunn801
21 hours ago
3
Timestamps don't prevent them, but timestamp + other uniqueness is a fairly common tactic for building unique identifiers.NEWSEQUENTIALID()
in sql server utilizes this, for example.
– dvlsg
13 hours ago
Yeah... that's what I meant. :-)
– Tomáš Na'vi Koválik
4 hours ago
2
2
How would a timestamp prevent duplicate ids? Events can happen simultaneously.
– ddunn801
21 hours ago
How would a timestamp prevent duplicate ids? Events can happen simultaneously.
– ddunn801
21 hours ago
3
3
Timestamps don't prevent them, but timestamp + other uniqueness is a fairly common tactic for building unique identifiers.
NEWSEQUENTIALID()
in sql server utilizes this, for example.– dvlsg
13 hours ago
Timestamps don't prevent them, but timestamp + other uniqueness is a fairly common tactic for building unique identifiers.
NEWSEQUENTIALID()
in sql server utilizes this, for example.– dvlsg
13 hours ago
Yeah... that's what I meant. :-)
– Tomáš Na'vi Koválik
4 hours ago
Yeah... that's what I meant. :-)
– Tomáš Na'vi Koválik
4 hours ago
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f232120%2fhow-to-generate-globally-unique-ids-for-different-tables-of-the-same-database%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
NEWID()
has this functionality. Please check this answer stackoverflow.com/a/28218084/4608204– EzLo
yesterday