<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ban Duong</title>
    <description>The latest articles on Forem by Ban Duong (@banduong_).</description>
    <link>https://forem.com/banduong_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1423934%2Fbca8b550-2a3d-406b-8cb1-2337825c03eb.jpeg</url>
      <title>Forem: Ban Duong</title>
      <link>https://forem.com/banduong_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/banduong_"/>
    <language>en</language>
    <item>
      <title>The Evolution of UUIDs: How v7 Improves Database Efficiency</title>
      <dc:creator>Ban Duong</dc:creator>
      <pubDate>Sat, 22 Feb 2025 10:47:45 +0000</pubDate>
      <link>https://forem.com/banduong_/understanding-uuids-why-uuid-v7-is-the-best-choice-for-databases-a8c</link>
      <guid>https://forem.com/banduong_/understanding-uuids-why-uuid-v7-is-the-best-choice-for-databases-a8c</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
What is a UUID?
&lt;/li&gt;
&lt;li&gt;
UUID Format and Generation Methods
&lt;/li&gt;
&lt;li&gt;
Comparing UUID v1, v4, and v7
&lt;/li&gt;
&lt;li&gt;
How UUID v4 and UUID v7 Affect Databases

&lt;ul&gt;
&lt;li&gt;
Understanding B-Tree Indexing
&lt;/li&gt;
&lt;li&gt;
Page Splits in B-Trees &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Why UUID v4 Causes Fragmentation and Cache Inefficiency

&lt;ul&gt;
&lt;li&gt;
Example of UUID v4 Inserts
&lt;/li&gt;
&lt;li&gt;
How Random Writes Lead to Cache Inefficiency
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Why UUID v7 is Better for Databases

&lt;ul&gt;
&lt;li&gt;
Example of UUID v7 Inserts
&lt;/li&gt;
&lt;li&gt;
Comparison of UUID v4 vs UUID v7 in Databases
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Conclusion

&lt;ul&gt;
&lt;li&gt;
TL;DR
&lt;/li&gt;
&lt;li&gt;Long Version&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What is a UUID?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;UUID (Universally Unique Identifier)&lt;/strong&gt; is a &lt;strong&gt;128-bit unique identifier&lt;/strong&gt; used in computing and data management. It ensures global uniqueness without requiring a central authority, making it ideal for distributed systems.&lt;/p&gt;

&lt;p&gt;UUIDs are commonly used in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Databases&lt;/strong&gt; (as primary keys to uniquely identify records).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed systems&lt;/strong&gt; (ensuring uniqueness across multiple nodes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session tracking&lt;/strong&gt; (assigning unique session IDs for users).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction identifiers&lt;/strong&gt; (maintaining consistency in financial systems).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. UUID Format and Generation Methods
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdiinvq10ndrooua6fmga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdiinvq10ndrooua6fmga.png" alt="UUID v1" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
A UUID is represented as a &lt;strong&gt;36-character string&lt;/strong&gt; with a standardized format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;M → UUID version (1, 4, 7, etc.).&lt;/li&gt;
&lt;li&gt;N → Variant (typically 8, 9, A, or B).&lt;/li&gt;
&lt;li&gt;Other parts contain timestamps, random values, or hashed data, depending on the UUID version.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How UUIDs Are Generated
&lt;/h3&gt;

&lt;p&gt;UUIDs can be created using different methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time-based (e.g., UUID v1, UUID v7)&lt;/strong&gt; → Uses timestamps, sometimes combined with MAC addresses or randomness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random (e.g., UUID v4)&lt;/strong&gt; → Generated using a random number generator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash-based (e.g., UUID v3, UUID v5)&lt;/strong&gt; → Generated using hashes of fixed input values.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Comparing UUID v1, v4, and v7
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;UUID v1 (Timestamp + MAC)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;UUID v4 (Random)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;UUID v7 (Timestamp + Random)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Generation Method&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Time-based + MAC address&lt;/td&gt;
&lt;td&gt;Fully random&lt;/td&gt;
&lt;td&gt;Time-based + Random&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Uniqueness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High (MAC ensures uniqueness)&lt;/td&gt;
&lt;td&gt;High (randomized)&lt;/td&gt;
&lt;td&gt;High (timestamp + random)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sortability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Mostly ordered, but has imperfections&lt;/td&gt;
&lt;td&gt;❌ Not sortable&lt;/td&gt;
&lt;td&gt;✅ Fully sequential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Database Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Causes minor fragmentation due to timestamp format&lt;/td&gt;
&lt;td&gt;❌ Random inserts (poor indexing)&lt;/td&gt;
&lt;td&gt;✅ Optimized for indexing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Privacy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ MAC address is exposed&lt;/td&gt;
&lt;td&gt;✅ Secure&lt;/td&gt;
&lt;td&gt;✅ Secure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Legacy systems&lt;/td&gt;
&lt;td&gt;General purpose, distributed systems&lt;/td&gt;
&lt;td&gt;Databases, logs, event tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  4. How UUID v4 and UUID v7 Affect Databases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Understanding B-Tree Indexing
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vavxuksyh7squn6u356.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vavxuksyh7squn6u356.png" alt="marita-kavelashvili-ugnrXk1129g-unsplash" width="800" height="531"&gt;&lt;/a&gt;&lt;br&gt;
Most relational databases (like MySQL InnoDB, PostgreSQL, and SQLite) use &lt;strong&gt;B-Tree indexes&lt;/strong&gt; to organize primary keys efficiently.&lt;/p&gt;
&lt;h3&gt;
  
  
  How B-Trees Work
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A B-Tree is a self-balancing tree structure where nodes store multiple sorted keys.&lt;/li&gt;
&lt;li&gt;When searching for a key (like a UUID), the database traverses the tree from root to leaf.&lt;/li&gt;
&lt;li&gt;Since data is sorted, operations like searching, inserting, and deleting run in &lt;strong&gt;O(log n) time complexity&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Page Splits in B-Trees
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48h8tc5d7wmohkrsfwc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48h8tc5d7wmohkrsfwc3.png" alt="B-Tree" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each node (page) has a &lt;strong&gt;fixed size&lt;/strong&gt; (e.g., 16KB in MySQL InnoDB).&lt;/li&gt;
&lt;li&gt;When a new key is inserted in sorted order, it usually fits into an existing page.&lt;/li&gt;
&lt;li&gt;But if the page is full, the database &lt;strong&gt;splits&lt;/strong&gt; it into two new pages, increasing fragmentation.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  5. Why UUID v4 Causes Fragmentation and Cache Inefficiency
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlifu7ar86rvzy585xwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlifu7ar86rvzy585xwc.png" alt="UUID v4" width="800" height="459"&gt;&lt;/a&gt;&lt;br&gt;
UUID v4 is &lt;strong&gt;fully random&lt;/strong&gt;, meaning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New inserts land anywhere in the index, not in a predictable order.&lt;/li&gt;
&lt;li&gt;The database must modify different pages, causing frequent page splits and fragmentation.&lt;/li&gt;
&lt;li&gt;Queries on recent records require loading multiple scattered pages, making caching inefficient.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example of UUID v4 Inserts
&lt;/h3&gt;

&lt;p&gt;Imagine a &lt;strong&gt;B-Tree index with 4 pages&lt;/strong&gt;, each storing sorted UUIDs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Page 1: [ UUID1 | UUID5 | UUID8 | UUID12 ]  
Page 2: [ UUID15 | UUID18 | UUID22 | UUID26 ]  
Page 3: [ UUID30 | UUID35 | UUID40 | UUID45 ]  
Page 4: [ UUID50 | UUID55 | UUID60 | UUID65 ]  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, inserting a &lt;strong&gt;random UUID v4 (&lt;code&gt;UUID33&lt;/code&gt;)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It lands between &lt;code&gt;UUID30&lt;/code&gt; and &lt;code&gt;UUID35&lt;/code&gt; in Page 3.&lt;/li&gt;
&lt;li&gt;If Page 3 is full, the database splits it into two pages.&lt;/li&gt;
&lt;li&gt;More inserts increase fragmentation, making reads slower.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Random Writes Lead to Cache Inefficiency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Databases store frequently accessed pages in memory (buffer pool).&lt;/li&gt;
&lt;li&gt;But since UUID v4 spreads inserts randomly, each query loads different pages, constantly evicting older pages.&lt;/li&gt;
&lt;li&gt;This leads to more disk I/O and poorer cache performance.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Why UUID v7 is Better for Databases
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsuo13jurzq4rohl11ay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsuo13jurzq4rohl11ay.png" alt="UUID v7" width="800" height="459"&gt;&lt;/a&gt;&lt;br&gt;
UUID v7 &lt;strong&gt;solves the fragmentation issue&lt;/strong&gt; because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first 48 bits are a timestamp, making it &lt;strong&gt;sequentially ordered&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The last 80 bits are random, ensuring uniqueness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New inserts always go to the last page&lt;/strong&gt; in a B-Tree index, avoiding fragmentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example of UUID v7 Inserts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Page 1: [ UUID1 | UUID5 | UUID8 | UUID12 ]  
Page 2: [ UUID15 | UUID18 | UUID22 | UUID26 ]  
Page 3: [ UUID30 | UUID35 | UUID40 | UUID45 ]  
Page 4: [ UUID50 | UUID55 | UUID60 | UUID65 ]  
Page 5: [ UUID70 | UUID75 | UUID80 | UUID85 ]  ← New inserts go here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since new entries always append to the last page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fewer page splits → Less fragmentation → Faster inserts.
&lt;/li&gt;
&lt;li&gt;Queries on recent data remain in memory → Better cache performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comparison of UUID v4 vs UUID v7 in Databases
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Factor&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;UUID v4 (Random Inserts)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;UUID v7 (Sequential Inserts)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write Pattern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inserts anywhere, causing fragmentation&lt;/td&gt;
&lt;td&gt;Writes append to the last page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Page Splits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Frequent, due to random insert locations&lt;/td&gt;
&lt;td&gt;✅ Rare, only when last page is full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cache Efficiency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Poor – random pages evicted frequently&lt;/td&gt;
&lt;td&gt;✅ High – recent data stays in memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Slow – queries require loading multiple pages from disk&lt;/td&gt;
&lt;td&gt;✅ Fast – queries read from cached pages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  7. Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gt8s1xgpptd0150smc1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gt8s1xgpptd0150smc1.jpg" alt="rene-bohmer-YeUVDKZWSZ4-unsplash" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Why UUID v4 is inefficient:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Random inserts cause index fragmentation and frequent page splits.&lt;/li&gt;
&lt;li&gt;Sequential queries suffer, requiring multiple page fetches.&lt;/li&gt;
&lt;li&gt;Cache performance drops, as pages are constantly replaced.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why UUID v7 is better:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sorted inserts lead to fewer page splits.&lt;/li&gt;
&lt;li&gt;Faster sequential reads, as queries load a single page.&lt;/li&gt;
&lt;li&gt;Recent data remains in memory, improving database performance.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Long Version
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Why UUID v4 is Inefficient
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Random Inserts Cause Index Fragmentation&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;UUIDv4 values are completely random, meaning new entries can be inserted anywhere in the B-Tree index. This leads to &lt;strong&gt;data fragmentation&lt;/strong&gt;, as records are scattered across different pages instead of being grouped together.  &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Frequent Page Splits Increase Write Overhead&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;When a UUID v4 is inserted into a full page, the database must &lt;strong&gt;split the page&lt;/strong&gt; to make room for new values. Since inserts happen randomly, page splits occur more frequently, increasing the database's workload and reducing efficiency.  &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Poor Sequential Read Performance&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Because UUID v4 values are unordered, reading a range of UUIDs requires fetching data from multiple non-contiguous pages. This results in:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More disk I/O, slowing down queries.
&lt;/li&gt;
&lt;li&gt;Inefficient caching, as different pages are loaded into memory instead of reusing recently accessed ones.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why UUID v7 is Better
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Sequential Inserts Improve Write Performance&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;UUID v7 is &lt;strong&gt;sorted by timestamp&lt;/strong&gt;, meaning new values are always appended to the latest page. This results in:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fewer random writes&lt;/strong&gt;, reducing fragmentation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal page splits&lt;/strong&gt;, since new entries naturally go to the end of the index.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Faster Sequential Reads&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Since UUID v7 values are stored in increasing order, sequential queries can &lt;strong&gt;retrieve data from a single page or adjacent pages&lt;/strong&gt;, making range scans much faster.  &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Better Cache Efficiency&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;With UUID v7, recent data remains in memory longer because:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New records are appended rather than scattered.
&lt;/li&gt;
&lt;li&gt;Queries accessing recent entries will likely hit cached pages, reducing disk reads and improving performance.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>uuid</category>
      <category>database</category>
      <category>programming</category>
    </item>
    <item>
      <title>[Java] Overriding and Hiding</title>
      <dc:creator>Ban Duong</dc:creator>
      <pubDate>Sun, 28 Apr 2024 08:44:08 +0000</pubDate>
      <link>https://forem.com/banduong_/java-overriding-and-hiding-365a</link>
      <guid>https://forem.com/banduong_/java-overriding-and-hiding-365a</guid>
      <description>&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;In Java, static methods can't be overridden. But in a child class, we can still have the same static method as in the parent class, and the compiler doesn't throw any error about that. In this case, it's not called method overriding; it's called method hiding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Parent {

    public static void staticMethod() {
        System.out.println("Static method of parent class");
    }

    public void instanceMethod() {
        System.out.println("Instance method of parent class");
    }
}

public class Child extends Parent {

    public static void staticMethod() {
        System.out.println("Static method of child class");
    }

    @Override
    public void instanceMethod() {
        System.out.println("Instance method of child class");
    }

}

public class App {

    public static void main(String[] args) {
        Parent p = new Child();
        //it invokes an instance method of the child class
        p.instanceMethod();
        //it invokes a static method of the parent class
        p.staticMethod();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is the difference?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.Overriding
&lt;/h3&gt;

&lt;p&gt;Let's take a look at the above example. We can see that the Child class has overridden the 'instanceMethod' in the Parent class. So when we invoke 'p.instanceMethod()', it invokes the method in the Child class instead of the method in the Parent class. This is called polymorphism. Although we declare the variable 'p' with the declared type Parent, we create it as a Child. So, at runtime, the JVM (Java Virtual Machine) finds that 'p' is a Child instance, and it will invoke the method in Child.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.Hiding
&lt;/h3&gt;

&lt;p&gt;Unlike with overriding, when we invoke 'p.staticMethod()', it invokes the method in the Parent class instead of the Child class. So, what happens here? The static method is resolved at compile time, not at runtime, so it can't exhibit polymorphism. At compile time, 'p' is seen as a Parent instance, while 'p' is only seen as a Child instance at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We can't override a static method, so when invoking a static method, instead of using 'p.staticMethod()', which can lead to confusion, we should use 'Parent.staticMethod()' or 'Child.staticMethod()' to provide clearer clarification.&lt;/p&gt;

</description>
      <category>java</category>
    </item>
    <item>
      <title>[Java] Singleton and Static</title>
      <dc:creator>Ban Duong</dc:creator>
      <pubDate>Thu, 18 Apr 2024 17:18:40 +0000</pubDate>
      <link>https://forem.com/banduong_/java-singleton-and-static-14ap</link>
      <guid>https://forem.com/banduong_/java-singleton-and-static-14ap</guid>
      <description>&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Both the singleton pattern and the static keyword are concepts that involve shared resources within an application. But when should we use each of them? This article aims to provide clarity on this matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is singleton pattern?
&lt;/h2&gt;

&lt;p&gt;The singleton pattern is one of the common design patterns. It ensures that the class has only one instance created. For example, we only need one instance when using a logger or accessing the configuration of the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Logger {
    private static Logger instance;

    private Logger() {
        // Private constructor to prevent instantiation outside this class
    }

    public static Logger getInstance() {
        if (instance == null) {
            instance = new Logger();
        }
        return instance;
    }

    public void log(String message) {
        System.out.println("[LOG] " + message);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is static keyword in Java?
&lt;/h2&gt;

&lt;p&gt;In Java, the static keyword can be used for variables, methods, and classes.&lt;/p&gt;

&lt;p&gt;With static variables and methods, it means these entities belong to the class itself rather than to individual objects. They can be accessed through the class without the need to create an instance.&lt;/p&gt;

&lt;p&gt;Regarding static classes, only nested classes can be static; the outer class cannot be static. However, a common use case is to make the class final and have static methods inside it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public final class Utility {

    public static final int num = 10;

    public static void doSomething() {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  So which one we should use?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.Initialization
&lt;/h3&gt;

&lt;p&gt;If initialization is required for an instance, we should use a singleton because it allows initialization in the singleton constructor, while static methods provide straightforward access without initialization. Conversely, if initialization is not needed, we can use a static class because it simplifies the code and offers better performance due to static binding at compile time.&lt;/p&gt;

&lt;p&gt;Example of the singleton approach&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Logger {
    private static Logger instance;
    private PrintWriter writer;

    private Logger() {
        try {
            writer = new PrintWriter(new FileWriter("log.txt", true));
            writer.println("Log file initialized.");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Logger getInstance() {
        if (instance == null) {
            instance = new Logger();
        }
        return instance;
    }

    public void log(String message) {
        writer.println(message);
        writer.flush();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example of the static approach&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Logger {
    private static PrintWriter writer;

    static {
        try {
            writer = new PrintWriter(new FileWriter("log.txt", true));
            writer.println("Log file initialized.");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void log(String message) {
        writer.println(message);
        writer.flush();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the static approach, the 'writer' isn't initialized in the constructor method; instead, it's initialized in a static block and will be created when the class is loaded. In the singleton approach, the 'writer' is initialized in the constructor method and is created when we call the getInstance method.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.Extension
&lt;/h3&gt;

&lt;p&gt;With singletons, we can utilize inheritance and polymorphism to extend a base class, implement an interface, and provide different implementations through method overriding. However, static methods cannot be overridden since their resolution occurs at compile time rather than runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Animal {
    void makeSound() {
        System.out.println("Animal makes a sound");
    }

    static void eat() {
        System.out.println("Animal eats");
    }
}

class Dog extends Animal {
    // Overriding the makeSound method
    @Override
    void makeSound() {
        System.out.println("Dog barks");
    }

    // Hiding the eat method (not overriding)
    static void eat() {
        System.out.println("Dog eats bones");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Animal dog = new Dog();

        // Calling non-static method, resolved at runtime
        animal.makeSound(); // Output: Animal makes a sound
        dog.makeSound();    // Output: Dog barks (method overridden)

        // Calling static method, resolved at compile time
        Animal.eat(); // Output: Animal eats
        Dog.eat();    // Output: Dog eats bones (method hidden)
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.Loading
&lt;/h3&gt;

&lt;p&gt;Singletons can be initialized via lazy loading, while static classes are initialized during the first load.&lt;/p&gt;

&lt;p&gt;Let's use the example in section one: Initialization. In the singleton approach, the 'writer' will only be created when the constructor method is invoked through the getInstance method. This means if we haven't used the Logger instance yet, it won't be initialized. However, with the static approach, the 'writer' will be created when the class is loaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.Managing State
&lt;/h3&gt;

&lt;p&gt;Singletons are a better option when state management is required because they offer control over initialization and finalization, which static classes do not provide.&lt;/p&gt;

&lt;p&gt;Example of the singleton approach&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DatabaseConnection {
    private static DatabaseConnection instance;
    private boolean isConnected;

    private DatabaseConnection() {
        isConnected = false;
    }

    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }

    public void connect() {
        isConnected = true;
        System.out.println("Connected to database");
    }

    public void disconnect() {
        isConnected = false;
        System.out.println("Disconnected from database");
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example of the static approach&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DatabaseConnection {
    private static boolean isConnected;

    private DatabaseConnection() {}

    public static void connect() {
        isConnected = true;
        System.out.println("Connected to database");
    }

    public static void disconnect() {
        isConnected = false;
        System.out.println("Disconnected from database");
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a static approach, everything from methods to variables needs to be static as well. This makes it less encapsulated, and it doesn't have an instance state to manage because static variables belong to the class itself, not the instance. With a singleton, we can control initialization and finalization at runtime, but with static, it's automatically created when the application starts and only destroyed when the application exits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If the purpose is a class with utility functions, requiring no state or initialization, opt for a static class. Otherwise, if state management or initialization is necessary, choose a singleton instead.&lt;/p&gt;

</description>
      <category>java</category>
      <category>designpatterns</category>
    </item>
  </channel>
</rss>
