Storing UUID and Generated Columns: How to Decompose and Recompose UUIDs in MySQL
- biobiidistalsnews
- Aug 14, 2023
- 4 min read
The Postgres documentation on uuid-ossp suggests using gen_random_uuid(). If you only need randomly-generated (version 4) UUIDs. Furthermore, the uuid-ossp extension provides other types of UUID (such as mac-addresses based).Another factor to consider is the different methods these tools use to generate their random values: uuid_generate_v4() uses arc4random to determine the random part, while gen_random_uuid() uses fortuna instead.
Storing UUID and Generated Columns
Database columns can have their values generated in various ways: primary key columns are frequently auto-incrementing integers, other columns have default or computed values, etc. This page details various patterns for configuration value generation with EF Core.
Unlike with default values or computed columns, we are not specifying how the values are to be generated; that depends on the database provider being used. Database providers may automatically set up value generation for some property types, but others may require you to manually set up how the value is generated.
A common request is to have a database column which contains the date/time for when the column was first inserted (value generated on add), or for when it was last updated (value generated on add or update). As there are various strategies to do this, EF Core providers usually don't set up value generation automatically for date/time columns - you have to configure this yourself.
This can be especially useful when seeding data. Seeded data must explicitly specify all columns - including database-generated ones - but the backing sequence for identity columns isn't aware that the values are in use, and will generate conflicting values. This technique allows to start your identity sequence at a value higher than all seeded data values. Another strategy is to seed negative values only, allowing your identity column to start at 1.
In other scenarios, a "last updated" is needed, which is automatically updated every time is modified. Unfortunately, while PostgreSQL supports generated columns, the use of functions such as now() isn't supported. It's still possible to use database trigger to set this up; triggers can be managed by adding raw SQL to your migrations, as follows:
When you later use into(preferences).insert(PreferencesCompanion.forInsert(name: 'foo'));, the new row will have its enabled column set to false (and not to null, as it normally would). Note that columns with a default value (either through autoIncrement or by using a default), are still marked as @required in generated data classes. This is because they are meant to represent a full row, and every row will have those values. Use companions when representing partial rows, like for inserts or updates.
This is a simplified structure and only has a minimum number of columns. Storing an unsalted password hash is not recommended. Look up best practices of storing passwords in the database when creating the final structure.
Alternatively, you could use UUID v6 to generate sequentially ordered values. uuid_v6 gem allows you to generate them using Ruby. UUIDs v6 are partially generated based on the current time, so they are orderable.
*This is a simplified structure and only has a minimum number of columns. Storing an unsalted password hash is not recommended. Look up best practices of storing passwords in the database when creating the final structure.We want the ID to be unique so we will be using the Java UUID in our domain object. Because we want all the information to be human readable as well, the ID should be stored as a String. Since we know the format of the UUID when represented as a String, we know that it has a length of 36 characters, so we can define the column as VARCHAR(36). The rest of the table structure can be similar to the image.
Timestamp-first (also, called "timestamp-first" or "ordered UUIDs") are similar to version-1 and version-4 UUIDs.These UUIDs have the current timestamp embedded in them to insure uniqueness.What is special about Timestamp-first UUIDs is that timestamp is at the beginning of the UUID so when stored in a database they will appear in the order they were created.This can be useful for many purposes and also is more efficient for storing in indexed database columns.
Knex currently does not support generated columns, so the schema generatorcannot properly diff them. To work around this, we can set ignoreSchemaChangeson a property to avoid a perpetual diff from the schema generator
In Microsoft SQL we have UNIQUEIDENTIFIER type while creating table and when inserted it fills auto-generated string into that row. Is there any equivalent type in Drupal 8 or should I use some function in php to generate the string and while saving the row send the string as parameter(something like this $uuid = UUID::v4();). Currently I am creating the schema for that column as below. Is there a better way to implement this.
The easiest way is to use a random UUID v4 id for every record. With 128 random bits a UUID is not guessable, collisions are improbable, and they are well-supported in every language and framework. PostgreSQL provides the storage-efficient gen_random_uuid() function to create UUID v4 strings. For MySQL the support for UUIDs is a lot more complex: Only the UUID v1 standard is implemented which generates UUIDs by the server's MAC address and current time. Those generated UUIDs do not include any randomness and are more likely to be guessed by attackers. Random UUIDs need to be generated by the application or user-generated database functions. A space-efficient storage format is not available either. A UUID can be stored in a UUID_TO_BIN and
despite the problems with uuid, people still prefer it because it is unique across every table, can be generated anywhere. in this blog, i will explain how to store uuid in an efficient way by re-arranging timestamp part of uuid. 2ff7e9595c
Comments