UUID Library v1.3.0
Binary UUID Functions
webpatser@dev:
~/uuid/1.3.0
$ cat binary-functions.md
Binary UUID Functions - UUID Library v1.3.0
Comprehensive guide to binary UUID operations for storage optimization, database performance, and memory efficiency. Learn how to work with UUIDs in their native 16-byte binary format.
Basic Binary Operations
Converting to Binary Format
use Webpatser\Uuid\Uuid; // Generate a UUID and get its binary representation$uuid = Uuid::v4(); // Method 1: Using the bytes property$binaryData = $uuid->bytes;echo "Binary length: " . strlen($binaryData) . " bytes\n"; // 16 bytes // Method 2: Converting from string$uuidString = $uuid->string; // e.g., "550e8400-e29b-41d4-a716-446655440000"$binaryFromString = pack('H*', str_replace('-', '', $uuidString)); // Verify they're identicalvar_dump($binaryData === $binaryFromString); // true
Converting from Binary Format
// Convert binary data back to UUID stringfunction binaryToUuidString(string $binaryData): string{ if (strlen($binaryData) !== 16) { throw new InvalidArgumentException('Binary UUID must be exactly 16 bytes'); } $hex = bin2hex($binaryData); // Insert dashes at proper positions return sprintf( '%s-%s-%s-%s-%s', substr($hex, 0, 8), substr($hex, 8, 4), substr($hex, 12, 4), substr($hex, 16, 4), substr($hex, 20, 12) );} // Convert binary back to Uuid objectfunction binaryToUuid(string $binaryData): Uuid{ $uuidString = binaryToUuidString($binaryData); return Uuid::import($uuidString);} // Usage example$originalUuid = Uuid::v4();$binary = $originalUuid->bytes;$restoredUuid = binaryToUuid($binary); echo "Original: " . $originalUuid->string . "\n";echo "Restored: " . $restoredUuid->string . "\n";echo "Match: " . ($originalUuid->string === $restoredUuid->string ? "✓" : "✗") . "\n";
Database Storage Optimization
MySQL Binary Storage
-- Create table with binary UUID storageCREATE TABLE users ( id BINARY(16) PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Add index for performance INDEX idx_users_id (id)); -- MySQL 8.0+ has built-in UUID functions-- But we'll show manual approach for compatibility
// PHP class for MySQL binary UUID operationsclass MySQLBinaryUuid{ private PDO $pdo; public function __construct(PDO $pdo) { $this->pdo = $pdo; } // Insert user with binary UUID public function createUser(string $name, string $email): string { $uuid = Uuid::v4(); $binaryId = $uuid->bytes; $stmt = $this->pdo->prepare(" INSERT INTO users (id, name, email) VALUES (?, ?, ?) "); $stmt->execute([$binaryId, $name, $email]); return $uuid->string; // Return string format for API } // Retrieve user by UUID string public function getUser(string $uuidString): ?array { $uuid = Uuid::import($uuidString); $binaryId = $uuid->bytes; $stmt = $this->pdo->prepare(" SELECT BIN_TO_UUID(id) as id, name, email, created_at FROM users WHERE id = ? "); $stmt->execute([$binaryId]); return $stmt->fetch(PDO::FETCH_ASSOC) ?: null; } // Get all users with proper UUID formatting public function getAllUsers(): array { $stmt = $this->pdo->query(" SELECT id, name, email, created_at FROM users ORDER BY created_at DESC "); $users = []; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { // Convert binary ID back to string $row['id'] = $this->binaryToUuidString($row['id']); $users[] = $row; } return $users; } private function binaryToUuidString(string $binary): string { $hex = bin2hex($binary); return sprintf( '%s-%s-%s-%s-%s', substr($hex, 0, 8), substr($hex, 8, 4), substr($hex, 12, 4), substr($hex, 16, 4), substr($hex, 20, 12) ); }} // Usage$pdo = new PDO('mysql:host=localhost;dbname=test', $username, $password);$userRepo = new MySQLBinaryUuid($pdo); $user = $userRepo->getUser($userId); echo "Created user: " . $user['name'] . " (ID: " . $user['id'] . ")\n";
PostgreSQL Binary Storage
-- PostgreSQL has native UUID type, but we can still use binary for optimizationCREATE TABLE users ( id BYTEA PRIMARY KEY, -- 16-byte binary storage name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP); -- Create index on binary UUIDCREATE INDEX idx_users_binary_id ON users(id);
// PostgreSQL binary UUID operationsclass PostgreSQLBinaryUuid{ private PDO $pdo; public function __construct(PDO $pdo) { $this->pdo = $pdo; } public function createUser(string $name, string $email): string { $uuid = Uuid::v7(); // Use v7 for better performance $binaryId = $uuid->bytes; $stmt = $this->pdo->prepare(" INSERT INTO users (id, name, email) VALUES (?, ?, ?) "); $stmt->bindParam(1, $binaryId, PDO::PARAM_LOB); $stmt->bindParam(2, $name); $stmt->bindParam(3, $email); $stmt->execute(); return $uuid->string; } public function getUser(string $uuidString): ?array { $uuid = Uuid::import($uuidString); $binaryId = $uuid->bytes; $stmt = $this->pdo->prepare(" SELECT id, name, email, created_at FROM users WHERE id = ? "); $stmt->bindParam(1, $binaryId, PDO::PARAM_LOB); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result) { // Convert binary back to string $result['id'] = $this->binaryToUuidString(stream_get_contents($result['id'])); } return $result ?: null; } private function binaryToUuidString(string $binary): string { $hex = bin2hex($binary); return sprintf( '%s-%s-%s-%s-%s', substr($hex, 0, 8), substr($hex, 8, 4), substr($hex, 12, 4), substr($hex, 16, 4), substr($hex, 20, 12) ); }}
Performance Comparison
Benchmark Results
// Benchmark binary vs string UUID performancefunction benchmarkUuidFormats(int $iterations = 100000): void{ echo "Benchmarking UUID formats with {$iterations} iterations...\n\n"; // Generate test UUIDs $uuids = []; for ($i = 0; $i < $iterations; $i++) { $uuids[] = Uuid::v4(); } // String format benchmark $start = microtime(true); $stringSize = 0; foreach ($uuids as $uuid) { $stringData = $uuid->string; $stringSize += strlen($stringData); } $stringTime = microtime(true) - $start; // Binary format benchmark $start = microtime(true); $binarySize = 0; foreach ($uuids as $uuid) { $binaryData = $uuid->bytes; $binarySize += strlen($binaryData); } $binaryTime = microtime(true) - $start; // Results echo "String Format:\n"; echo " Time: " . number_format($stringTime * 1000, 2) . "ms\n"; echo " Size: " . number_format($stringSize / 1024, 2) . " KB\n"; echo " Avg per UUID: " . ($stringSize / $iterations) . " bytes\n\n"; echo "Binary Format:\n"; echo " Time: " . number_format($binaryTime * 1000, 2) . "ms\n"; echo " Size: " . number_format($binarySize / 1024, 2) . " KB\n"; echo " Avg per UUID: " . ($binarySize / $iterations) . " bytes\n\n"; $spaceSavings = (($stringSize - $binarySize) / $stringSize) * 100; $speedDiff = ($stringTime - $binaryTime) / $stringTime * 100; echo "Savings:\n"; echo " Space: " . number_format($spaceSavings, 1) . "%\n"; echo " Speed: " . number_format($speedDiff, 1) . "% faster\n";} // Run benchmarkbenchmarkUuidFormats(50000);
Live Performance Test
0.05ms
String Format (1000 UUIDs)
35.16 KB total
0.04ms
Binary Format (1000 UUIDs)
15.63 KB total
55.6%
Space Savings
20000 bytes saved
Live benchmark results generated on page load
Advanced Binary Operations
Bulk Binary Processing
class BinaryUuidProcessor{ // Convert array of UUID strings to binary format public static function stringArrayToBinary(array $uuidStrings): array { return array_map(function (string $uuidString): string { $uuid = Uuid::import($uuidString); return $uuid->bytes; }, $uuidStrings); } // Convert array of binary UUIDs to strings public static function binaryArrayToString(array $binaryUuids): array { return array_map(function (string $binary): string { return self::binaryToUuidString($binary); }, $binaryUuids); } // Efficient batch UUID generation in binary format public static function generateBinaryBatch(int $count, int $version = 4): array { $binaries = []; for ($i = 0; $i < $count; $i++) { $uuid = match($version) { 1 => Uuid::generate(1), 4 => Uuid::v4(), 7 => Uuid::v7(), default => Uuid::v4() }; $binaries[] = $uuid->bytes; } return $binaries; } // Pack multiple binary UUIDs into a single string public static function packBinaryUuids(array $binaryUuids): string { return implode('', $binaryUuids); } // Unpack multiple binary UUIDs from a single string public static function unpackBinaryUuids(string $packedData): array { if (strlen($packedData) % 16 !== 0) { throw new InvalidArgumentException('Packed data length must be multiple of 16'); } $uuids = []; $count = strlen($packedData) / 16; for ($i = 0; $i < $count; $i++) { $uuids[] = substr($packedData, $i * 16, 16); } return $uuids; } private static function binaryToUuidString(string $binary): string { $hex = bin2hex($binary); return sprintf( '%s-%s-%s-%s-%s', substr($hex, 0, 8), substr($hex, 8, 4), substr($hex, 12, 4), substr($hex, 16, 4), substr($hex, 20, 12) ); }} // Usage examples$uuidStrings = [ '550e8400-e29b-41d4-a716-446655440000', '6ba7b810-9dad-11d1-80b4-00c04fd430c8', '6ba7b811-9dad-11d1-80b4-00c04fd430c8']; // Convert to binary$binaryUuids = BinaryUuidProcessor::stringArrayToBinary($uuidStrings);echo "Converted " . count($binaryUuids) . " UUIDs to binary\n"; // Pack for storage/transmission$packed = BinaryUuidProcessor::packBinaryUuids($binaryUuids);echo "Packed size: " . strlen($packed) . " bytes\n"; // Unpack and convert back$unpacked = BinaryUuidProcessor::unpackBinaryUuids($packed);$restored = BinaryUuidProcessor::binaryArrayToString($unpacked); echo "Original: " . json_encode($uuidStrings) . "\n";echo "Restored: " . json_encode($restored) . "\n";
Binary UUID Validation
class BinaryUuidValidator{ // Validate binary UUID format public static function isValidBinary(string $binary): bool { // Must be exactly 16 bytes if (strlen($binary) !== 16) { return false; } // Convert to hex and check UUID structure $hex = bin2hex($binary); // Check version and variant bits $version = hexdec(substr($hex, 12, 1)); $variant = hexdec(substr($hex, 16, 1)); // Version should be 1, 3, 4, 5, 6, 7, or 8 if (!in_array($version, [1, 3, 4, 5, 6, 7, 8])) { return false; } // Variant should be 8, 9, A, or B (10xx in binary) if (($variant & 0xC) !== 0x8) { return false; } return true; } // Extract UUID version from binary public static function getVersion(string $binary): int { if (!self::isValidBinary($binary)) { throw new InvalidArgumentException('Invalid binary UUID'); } $hex = bin2hex($binary); return hexdec(substr($hex, 12, 1)); } // Check if binary UUID is nil (all zeros) public static function isNil(string $binary): bool { return $binary === str_repeat("\x00", 16); } // Generate nil UUID in binary format public static function nil(): string { return str_repeat("\x00", 16); }} // Usage examples$uuid = Uuid::v4();$binary = $uuid->bytes; echo "Valid binary UUID: " . (BinaryUuidValidator::isValidBinary($binary) ? "✓" : "✗") . "\n";echo "Version: " . BinaryUuidValidator::getVersion($binary) . "\n";echo "Is nil: " . (BinaryUuidValidator::isNil($binary) ? "✓" : "✗") . "\n"; // Test with nil UUID$nilBinary = BinaryUuidValidator::nil();echo "Nil UUID valid: " . (BinaryUuidValidator::isValidBinary($nilBinary) ? "✓" : "✗") . "\n";echo "Nil UUID is nil: " . (BinaryUuidValidator::isNil($nilBinary) ? "✓" : "✗") . "\n";
Laravel Integration
// Laravel model with binary UUID supportuse Illuminate\Database\Eloquent\Model;use Webpatser\Uuid\Uuid; class BinaryUuidModel extends Model{ protected $keyType = 'string'; public $incrementing = false; // Automatically handle binary UUID conversion protected $casts = [ 'id' => 'string', ]; protected static function boot() { parent::boot(); static::creating(function ($model) { if (!$model->id) { $uuid = Uuid::v7(); // Time-ordered for better performance // Store as binary in database, but keep string in model $model->id = $uuid->string; } }); } // Custom accessor to handle binary storage public function getIdAttribute($value) { if (is_string($value) && strlen($value) === 16) { // Convert binary to string return $this->binaryToUuidString($value); } return $value; } // Custom mutator to store as binary public function setIdAttribute($value) { if (is_string($value) && strlen($value) === 36) { // Convert string to binary for storage $uuid = Uuid::import($value); $this->attributes['id'] = $uuid->bytes; } else { $this->attributes['id'] = $value; } } private function binaryToUuidString(string $binary): string { $hex = bin2hex($binary); return sprintf( '%s-%s-%s-%s-%s', substr($hex, 0, 8), substr($hex, 8, 4), substr($hex, 12, 4), substr($hex, 16, 4), substr($hex, 20, 12) ); }} // Migration for binary UUID column// In your migration file:Schema::create('binary_uuid_models', function (Blueprint $table) { $table->binary('id', 16)->primary(); // 16-byte binary column $table->string('name'); $table->timestamps();});
Best Practices
Troubleshooting
Conclusion
Binary UUID operations provide significant storage and performance benefits, especially for large-scale applications. The 55% space savings and improved index performance make binary UUIDs ideal for high-volume database operations.
Key takeaways:
- Binary UUIDs use 16 bytes vs 36 bytes for string format
- Database indexes are more efficient with binary data
- Proper conversion functions are essential for data integrity
- UUID v7 provides optimal performance for time-ordered data
- Always validate binary UUID format and length