The minimum requirements for generating UUIDs of each version are described in this

document. Everything else is an implementation detail,
and it is up to the implementer to decide what is appropriate for a
given implementation. Various relevant factors are covered below to help
guide an implementer through the different trade-offs among differing
UUID implementations.
UUID timestamp source, precision, and length were topics of great
debate while creating UUIDv7 for this specification. Choosing the
right timestamp for your application is very important. This
section will detail some of the most common points on this issue.
Monotonicity (each subsequent value being greater than the last) is
the backbone of time-based sortable UUIDs. Normally, time-based UUIDs
from this document will be monotonic due to an embedded timestamp;
however, implementations can guarantee additional monotonicity via the
concepts covered in this section.
Take care to ensure UUIDs generated in batches are also
monotonic. That is, if one thousand UUIDs are generated for the same
timestamp, there should be sufficient logic for organizing the
creation order of those one thousand UUIDs. Batch UUID creation
implementations utilize a monotonic counter that
increments for each UUID created during a given timestamp.
For single-node UUID implementations that do not need to create
batches of UUIDs, the embedded timestamp within UUIDv6 and UUIDv7
can provide sufficient monotonicity guarantees by simply ensuring that
timestamp increments before creating a new UUID. Distributed nodes are
discussed in .
Implementations employ the following methods
for single-node UUID implementations that require batch UUID creation
or are otherwise concerned about monotonicity with high-frequency UUID
generation.
The following sub-topics cover issues related solely to creating reliable
fixed bit-length dedicated counters:
The following sub-topics cover rollover handling with either type of counter
method:
Implementations use the following logic to
ensure UUIDs featuring embedded counters are monotonic in nature:
The (optional) UUID generator state only needs to be read from
stable storage once at boot time, if it is read into a system-wide
shared volatile store (and updated whenever the stable store is
updated).
This stable storage be used to record various
portions of the UUID generation, which prove useful for batch UUID
generation purposes and monotonic error checking with UUIDv6 and
UUIDv7. These stored values include but are not limited to last known
timestamp, clock sequence, counters, and random data.
If an implementation does not have any stable store available, then
it proceed with UUID generation as if this were the
first UUID created within a batch. This is the least desirable
implementation because it will increase the frequency of creation of
values such as clock sequence, counters, or random data, which
increases the probability of duplicates. Further, frequent generation
of random numbers also puts more stress on any entropy source and/or
entropy pool being used as the basis for such random numbers.
An implementation also return an application
error in the event that collision resistance is of the utmost concern.
The semantics of this error are up to the application and
implementation. See for more
information on weighting collision tolerance in applications.
For UUIDv1 and UUIDv6, if the Node ID can never change (e.g., the
network interface card from which the Node ID is derived is
inseparable from the system), or if any change also re-initializes the
clock sequence to a random value, then instead of keeping it in stable
store, the current Node ID may be returned.
For UUIDv1 and UUIDv6, the state does not always need to be written
to stable store every time a UUID is generated. The timestamp in the
stable store can periodically be set to a value larger than any yet
used in a UUID. As long as the generated UUIDs have timestamps less
than that value, and the clock sequence and Node ID remain unchanged,
only the shared volatile copy of the state needs to be updated.
Furthermore, if the timestamp value in stable store is in the future
by less than the typical time it takes the system to reboot, a crash
will not cause a re-initialization of the clock sequence.
If it is too expensive to access shared state each time a UUID is
generated, then the system-wide generator can be implemented to
allocate a block of timestamps each time it is called; a per-process
generator can allocate from that block until it is exhausted.
Some implementations desire the utilization of
multi-node, clustered, applications that involve two or more nodes
independently generating UUIDs that will be stored in a common
location. While UUIDs already feature sufficient entropy to ensure
that the chances of collision are low, as the total number of UUID
generating nodes increases, so does the likelihood of a collision.
This section will detail the two additional collision resistance
approaches that have been observed by multi-node UUID implementations
in distributed environments.
It should be noted that, although this section details two methods
for the sake of completeness, implementations should utilize the
pseudorandom Node ID option if additional collision resistance for
distributed UUID generation is a requirement. Likewise, utilization
of either method is not required for implementing UUID generation in
distributed environments.
Distributed applications generating UUIDs at a variety of hosts
be willing to rely on the random number source at all hosts.
Although some prefer to use the word "hash-based" to describe UUIDs
featuring hashing algorithms (MD5 or SHA-1), this document retains the
usage of the term "name-based" in order to maintain consistency with
previously published documents and existing implementations.
The requirements for name-based UUIDs are as follows:
A note on names:
The concept of name (and namespace) should be broadly
construed and not limited to textual names. A canonical sequence of
octets is one that conforms to the specification for that name
form's canonical representation. A name can have many usual forms,
only one of which can be canonical. An implementer of new namespaces
for UUIDs needs to reference the specification for the canonical
form of names in that space or define such a canonical form for the
namespace if it does not exist. For example, at the time of
writing, Domain Name System (DNS) [] has three
conveyance formats: common (www.example.com), presentation
(www.example.com.), and wire format (3www7example3com0). Looking at
[] Distinguished Names (DNs), [] allowed either text-based or
binary DER-based names as inputs. For Uniform Resource Locators
(URLs) [], one could provide a Fully Qualified
Domain Name (FQDN) with or without the protocol identifier
www.example.com or https://www.example.com. When it comes to Object
Identifiers (OIDs) [], one could choose dot
notation without the leading dot (2.999), choose to include the
leading dot (.2.999), or select one of the many formats from [] such as OID Internationalized Resource Identifier
(OID-IRI) (/Joint-ISO-ITU-T/Example). While most users may default
to the common format for DNS, FQDN format for a URL, text format for
X.500, and dot notation without a leading dot for OID, name-based
UUID implementations generally allow arbitrary
input that will compute name-based UUIDs for any of the
aforementioned example names and others not defined here. Each name
format within a namespace will output different UUIDs. As such, the
mechanisms or conventions used for allocating names and ensuring
their uniqueness within their namespaces are beyond the scope of
this specification.
This section details the namespace
IDs for some potentially interesting namespaces such as those for DNS
[], URLs [], OIDs [], and DNs [].
Further, this section also details allocation, IANA registration,
and other details pertinent to Namespace IDs.
Items may be added to this registry using the Specification Required
policy as per [].
For designated experts, generally speaking, Namespace IDs are
allocated as follows:
Note that the Namespace ID value
"6ba7b813-9dad-11d1-80b4-00c04fd430c8" and its usage are not defined by
this document or by []; thus, it be used as a Namespace ID value.
New Namespace ID values be documented as per
if they are to be globally available and fully
interoperable. Implementations continue to use
vendor-specific, application-specific, and deployment-specific
Namespace ID values; but know that interoperability is not guaranteed.
These custom Namespace ID values use the logic
above; instead, generating a
UUIDv4 or UUIDv7 Namespace ID value is . If collision probability () and uniqueness () of the final name-based UUID are
not a problem, an implementation also leverage
UUIDv8 instead to create a custom, application-specific Namespace ID
value.
Implementations provide the ability to input
a custom namespace to account for newly registered IANA Namespace ID
values outside of those listed in this section or custom,
application-specific Namespace ID values.
Implementations should weigh the consequences of UUID collisions
within their application and when deciding between UUID versions that
use entropy (randomness) versus the other components such as those in
Sections
and . This is
especially true for distributed node collision resistance as defined
by .
There are two example scenarios below that help illustrate the
varying seriousness of a collision within an application.
UUIDs created by this specification be used to
provide local uniqueness guarantees. For example, ensuring UUIDs
created within a local application context are unique within a
database be sufficient for some implementations
where global uniqueness outside of the application context, in other
applications, or around the world is not required.
Although true global uniqueness is impossible to guarantee without
a shared knowledge scheme, a shared knowledge scheme is not required
by a UUID to provide uniqueness for practical implementation purposes.
Implementations use a shared knowledge
scheme, introduced in ,
as they see fit to extend the uniqueness guaranteed by this
specification.
Implementations utilize a cryptographically
secure pseudorandom number generator (CSPRNG) to provide values that
are both difficult to predict ("unguessable") and have a low
likelihood of collision ("unique"). The exception is when a suitable
CSPRNG is unavailable in the execution environment. Take care to
ensure the CSPRNG state is properly reseeded upon state changes, such
as process forks, to ensure proper CSPRNG operation. CSPRNG ensures
the best of Sections and are
present in modern UUIDs.
Further advice on generating cryptographic-quality random numbers
can be found in [], [],
and [].
This section describes how to generate a UUIDv1 or UUIDv6 value if
an IEEE 802 address is not available or its use is not desired.
Implementations leverage MAC address
randomization techniques [] as an alternative to the pseudorandom logic
provided in this section.
Alternatively, implementations elect to obtain a
48-bit cryptographic-quality random number as per to use as the Node ID. After generating the
48-bit fully randomized node value, implementations
set the least significant bit of the first octet
of the Node ID to 1. This bit is the unicast or multicast bit, which
will never be set in IEEE 802 addresses obtained from network cards.
Hence, there can never be a conflict between UUIDs generated by
machines with and without network cards. An example of generating a
randomized 48-bit node value and the subsequent bit modification is
detailed in . For more information about
IEEE 802 address and the unicast or multicast or local/global bits,
please review [].
For compatibility with earlier specifications, note that this
document uses the unicast or multicast bit instead of the arguably more
correct local/global bit because MAC addresses with the local/global
bit set or not set are both possible in a network. This is not the case
with the unicast or multicast bit. One node cannot have a MAC address
that multicasts to multiple nodes.
In addition, items such as the computer's name and the name of the
operating system, while not strictly speaking random, will help
differentiate the results from those obtained by other systems.
The exact algorithm to generate a Node ID using these data is
system specific because both the data available and the functions to
obtain them are often very system specific. However, a generic approach
is to accumulate as many sources as possible into a buffer, use a
message digest (such as SHA-256 or SHA-512 defined by []), take an arbitrary 6 bytes from the hash value,
and set the multicast bit as described above.
UUIDv6 and UUIDv7 are designed so that implementations that require
sorting (e.g., database indexes) sort as opaque raw bytes without the
need for parsing or introspection.
Time-ordered monotonic UUIDs benefit from greater database-index
locality because the new values are near each other in the index. As
a result, objects are more easily clustered together for better
performance. The real-world differences in this approach of index
locality versus random data inserts can be one order of magnitude or
more.
UUID formats created by this specification are intended to be
lexicographically sortable while in the textual representation.
UUIDs created by this specification are crafted with big-endian
byte order (network byte order) in mind. If little-endian style is
required, UUIDv8 is available for custom UUID formats.
As general guidance, avoiding parsing UUID values
unnecessarily is recommended; instead, treat UUIDs as opaquely as possible.
Although application-specific concerns could, of course, require some
degree of introspection (e.g., to examine Sections or or perhaps the timestamp of
a UUID), the advice here is to avoid this or other parsing unless
absolutely necessary. Applications typically tend to be simpler, be more
interoperable, and perform better when this advice is followed.
For many applications, such as databases, storing UUIDs as text is
unnecessarily verbose, requiring 288 bits to represent 128-bit UUID
values. Thus, where feasible, UUIDs be stored
within database applications as the underlying 128-bit binary
value.
For other systems, UUIDs be stored in binary
form or as text, as appropriate. The trade-offs to both approaches
are as follows:
DBMS vendors are encouraged to provide functionality to generate
and store UUID formats defined by this specification for use as
identifiers or left parts of identifiers such as, but not limited to,
primary keys, surrogate keys for temporal databases, foreign keys
included in polymorphic relationships, and keys for key-value pairs in
JSON columns and key-value databases. Applications using a monolithic
database may find using database-generated UUIDs (as opposed to
client-generated UUIDs) provides the best UUID monotonicity. In
addition to UUIDs, additional identifiers be used
to ensure integrity and feedback.
Designers of database schema are cautioned against using name-based
UUIDs (see Sections and ) as primary keys in tables. A
common issue observed in database schema design is the assumption that
a particular value will never change, which later turns out to be
an incorrect assumption. Postal codes, license or other
identification numbers, and numerous other such identifiers seem
unique and unchanging at a given point time -- only later to have edge
cases where they need to change. The subsequent change of the
identifier, used as a "name" input for name-based UUIDs, can
invalidate a given database structure. In such scenarios, it is
observed that using any non-name-based UUID version would have
resulted in the field in question being placed somewhere that would
have been easier to adapt to such changes (primary key excluded from
this statement). The general advice is to avoid name-based UUID
natural keys and, instead, to utilize time-based UUID surrogate keys
based on the aforementioned problems detailed in this section.
2025年国内旅游收入预计将突破历史新高,以下是综合多方数据的预测与分析:
一、核心数据预测

工作时间:8:00-18:00
电子邮件
扫码二维码
获取最新动态
