Tipe data uuid
yang sempurna cocok untuk tugas. Ini hanya menempati 16 byte sebagai lawan dari 37 byte di RAM untuk representasi varchar
atau text
. (Atau 33 byte pada disk, tetapi angka ganjil akan membutuhkan padding dalam banyak kasus untuk membuatnya 40 byte secara efektif.) Dan uuid
tipe ini memiliki beberapa kelebihan.
Contoh:
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash
Detail dan penjelasan lebih lanjut:
Anda mungkin mempertimbangkan fungsi hashing lainnya (lebih murah) jika Anda tidak memerlukan komponen kriptografi dari md5, tapi saya akan menggunakan md5 untuk use case Anda (kebanyakan hanya baca-saja).
Sebuah kata peringatan : Untuk kasus Anda ( immutable once written
) a fungsional tergantung (pseudo-alam) PK baik-baik saja. Tetapi hal yang sama akan menyusahkan jika pembaruan text
dimungkinkan. Pikirkan untuk memperbaiki kesalahan ketik: PK dan semua indeks tergantung, kolom FK di dozens of other tables
dan referensi lainnya harus berubah juga. Tabel dan indeks mengasapi, masalah penguncian, pembaruan lambat, referensi hilang, ...
Jika text
dapat berubah dalam operasi normal, PK pengganti akan menjadi pilihan yang lebih baik. Saya menyarankan sebuah bigserial
kolom (kisaran -9223372036854775808 to +9223372036854775807
- itu sembilan trilyun dua ratus dua puluh tiga kuadriliun tiga ratus tujuh puluh dua triliun tiga puluh enam sesuatu miliar ) nilai yang berbeda untuk billions of rows
. Mungkin ide yang baik dalam setiap kasus: 8 bukan 16 ! Byte untuk puluhan kolom FK dan indeks). Atau UUID acak untuk kardinalitas yang jauh lebih besar atau sistem terdistribusi. Anda selalu dapat menyimpan kata md5 (as uuid
) tambahan untuk menemukan baris di tabel utama dari teks asli dengan cepat. Terkait:
Adapun permintaan Anda :
Untuk mengatasi komentar @ Daniel : Jika Anda lebih suka representasi tanpa tanda hubung, hapus tanda hubung untuk ditampilkan:
SELECT replace('90b7525e-84f6-4850-c2ef-b407fae3f271', '-', '')
Tapi aku tidak mau repot. Representasi default baik-baik saja. Dan masalahnya bukan representasi di sini.
Jika pihak lain harus memiliki pendekatan yang berbeda dan melempar string tanpa tanda hubung ke dalam campuran, itu tidak masalah juga. Postgres menerima beberapa representasi teks yang masuk akal sebagai input untuk a uuid
. Dokumentasi :
PostgreSQL juga menerima formulir alternatif berikut untuk input: penggunaan digit huruf besar, format standar yang dikelilingi oleh kawat gigi, menghilangkan beberapa atau semua tanda hubung, menambahkan tanda hubung setelah grup yang terdiri dari empat digit. Contohnya adalah:
A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
a0eebc999c0b4ef8bb6d6bb9bd380a11
a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
Apa lagi, md5()
kembali fungsi text
, Anda akan menggunakan decode()
untuk mengkonversi ke bytea
dan representasi default yang adalah:
SELECT decode(md5('Store hash for long string, maybe for index?'), 'hex')
\220\267R^\204\366HP\302\357\264\007\372\343\362q
Anda harus encode()
kembali untuk mendapatkan representasi teks asli:
SELECT encode(my_md5_as_bytea, 'hex');
Sebagai tambahan, nilai yang disimpan bytea
akan menempati 20 byte dalam RAM (dan 17 byte pada disk, 24 dengan padding ) karena overhead internalvarlena
, yang sangat tidak menguntungkan untuk ukuran dan kinerja indeks sederhana.
Semuanya berfungsi mendukung di uuid
sini.