Kehendak soalan dan masa ia diguna pakai
Ini ialah soalan pemodelan dimensi dan semantik sejarah. Alamat pelanggan tidak boleh dianggap sebagai nilai terkini sahaja apabila laporan kewangan mesti menjawab wilayah mana pelanggan berada pada tarikh yang lalu. Andaikan snapshot penuh harian, tiada log perubahan (change log), dan sasaran yang menyokong keadaan semasa, carian sejarah, serta main semula (replay). Dataquest menyenaraikan SCD Jenis 1, 2, dan 3 antara soalan temu duga kejuruteraan data; AWS menunjukkan Jenis 2 daripada fail penuh tanpa CDC.
Perkara yang diuji oleh penemu duga
- Menentukan sama ada laporan bertanyakan "sekarang" atau "pada masa itu" sebelum memilih jenis.
- Membezakan semantik tulis ganti (overwrite), tambah versi (append-a-version), dan satu nilai sebelumnya.
- Mengekalkan keunikan dengan kunci semula jadi (natural keys), kunci pengganti (surrogate keys), masa berkuat kuasa, dan bendera semasa (current flag).
- Mengendalikan snapshot lewat, fail pendua, pemadaman, main semula, dan penulisan serentak berbanding menulis satu
UPDATEsahaja.
Penjelasan yang perlu ditanya terlebih dahulu
- Adakah laporan mesti membina semula keadaan pada masa peristiwa berlaku, atau adakah profil semasa sudah mencukupi?
- Adakah snapshot membawa versi, masa ekstrak, atau tera air (watermark), dan bolehkah ia tiba tidak mengikut urutan?
- Adakah ketiadaan data bermaksud pemadaman perniagaan, peninggalan sementara, atau kecacatan sumber?
- Bolehkah sejarah yang diterbitkan dan cantuman fakta disemak semula, serta adakah audit, main semula, dan pelaksanaan semula idempoten diperlukan?
Jawapan 30 saat
"Saya menjelaskan semantik masa secara eksplisit: Jenis 1 hanya menyimpan nilai semasa, Jenis 2 menambah versi untuk setiap perubahan perniagaan dengan valid_from dan valid_to, dan Jenis 3 menyimpan satu atau sebilangan kecil nilai sebelumnya. Untuk analisis titik masa (point-in-time), saya memilih Jenis 2, mencari baris semasa mengikut kunci semula jadi, mencantumkan fakta melalui kunci pengganti, dan menggunakan tera air snapshot untuk mengenal pasti data lewat serta pemadaman. Saya mendaratkan dan menyahduplikasi setiap kelompok, kemudian menutup versi lama dan memasukkan versi baharu secara atomik; memainkan semula kelompok yang sama mesti menghasilkan output yang sama."
Penyelesaian langkah demi langkah
Langkah 1: Tentukan soalan sejarah
Jenis 1 sesuai untuk pembetulan atau profil tanpa sejarah dan menulis ganti di tempat asal. Jenis 2 sesuai untuk audit, atribusi hasil, dan pertanyaan titik masa dengan menyimpan setiap versi. Jenis 3 sesuai untuk tetingkap tetap 'semasa berbanding sebelumnya'. Jika keperluan bertanyakan wilayah pelanggan pada suku tahun lepas, Jenis 1 dan 3 kehilangan maklumat, jadi pilih Jenis 2.
Langkah 2: Tetapkan invariant Jenis 2
Simpan kunci pengganti, kunci semula jadi, atribut, valid_from, valid_to, is_current, dan tera air kelompok sumber. Bagi setiap kunci semula jadi, paling banyak satu baris mempunyai is_current = true; selang masa berkuat kuasa tidak boleh bertindih. AWS menggunakan tarikh mula/tamat, bendera semasa, dan pemadaman logik untuk sejarah penuh, manakala konfigurasi Jenis 2 Microsoft memerlukan kunci semula jadi, kunci pengganti, dua tarikh, dan bendera aktif.
Langkah 3: Simpulkan perubahan daripada snapshot penuh
Tulis fail ke jadual pendaratan yang tidak boleh diubah (immutable) dengan cincangan fail (file hash), masa ekstrak, dan jujukan kelompok. Bandingkan cincangan atribut untuk setiap kunci semula jadi dengan dimensi semasa: masukkan kunci baharu, tutup dan tambah kunci yang berubah, serta langkau cincangan yang sama. Kunci yang hilang hanya boleh membayangkan pemadaman apabila kontrak snapshot lengkap adalah benar; fail bertambah (incremental) tidak boleh menyimpulkan pemadaman daripada ketiadaan data.
Langkah 4: Kendalikan data lewat dan tidak mengikut urutan
Kekalkan tera air monotonik bagi setiap sumber. Tolak atau kuarantin fail yang berada di bawah tera air yang telah digunakan. Jika pembetulan sejarah dibenarkan, bahagikan selang masa berkuat kuasa yang terjejas dan kira semula cantuman fakta yang terkesan dalam satu transaksi; jika laporan yang diterbitkan tidak boleh diubah, letakkan kelompok dalam baris gilir pembetulan dan terbitkan kesannya. Menggunakan masa ketibaan sebagai masa sah akan mengubah snapshot lama menjadi keadaan baharu.
Langkah 5: Pemadaman, main semula, dan keserempakan
Kunci yang hilang dalam snapshot lengkap mencipta versi pemadaman logik atau menutup baris semasa, sambil mengekalkan bukti audit. Jadikan cincangan fail atau kelompok sumber sebagai kunci idempotensi yang unik; menjalankan semula kelompok tidak boleh menambah versi lain. Gunakan transaksi atau kunci cantum (merge lock) untuk sekatan kunci semula jadi supaya penutupan dan pemasukan adalah atomik. Gunakan kelompok mengikut urutan tera air; kelompok yang lebih lama tidak boleh membuka semula selang yang telah ditutup.
Rangka SQL yang boleh disahkan
-- current_dim: one current row per customer_id
BEGIN;
UPDATE dim_customer AS old
SET valid_to = :as_of,
is_current = FALSE,
source_batch = :batch_id
FROM stage_customer AS incoming
WHERE old.customer_id = incoming.customer_id
AND old.is_current = TRUE
AND old.row_hash <> incoming.row_hash;
INSERT INTO dim_customer (
customer_key, customer_id, city, valid_from, valid_to,
is_current, source_batch, row_hash
)
SELECT nextval('dim_customer_key_seq'), incoming.customer_id,
incoming.city, :as_of, NULL, TRUE, :batch_id, incoming.row_hash
FROM stage_customer AS incoming
LEFT JOIN dim_customer AS old
ON old.customer_id = incoming.customer_id
AND old.is_current = TRUE
WHERE old.customer_id IS NULL
OR old.row_hash <> incoming.row_hash;
COMMIT;Pengeluaran masih memerlukan kekangan unik pada batch_id dan pemeriksaan pra-pemberian (pre-commit) bahawa setiap kunci semula jadi mempunyai satu baris semasa, selang masa tidak bertindih, dan tera air input adalah sah. Rangka ini mengandaikan stage_customer dinyahduplikasi bagi setiap kelompok; ia bukan pengendali luar urutan yang lengkap.
Contoh jawapan berkualiti tinggi
"Saya terlebih dahulu bertanya sejarah mana yang mesti dipelihara oleh laporan. Gunakan Jenis 1 untuk nilai semasa sahaja, Jenis 2 untuk keadaan pada mana-mana tarikh lalu, dan Jenis 3 untuk tepat satu nilai sebelumnya. Bagi snapshot penuh harian, daratkan fail mentah dan nyahduplikasi mengikut tera air kelompok dan cincangan fail. Bandingkan kunci semula jadi dan cincangan atribut untuk mengelaskan pemasukan, perubahan, dan tiada operasi (no-op). Kemas kini Jenis 2 mesti menutup baris lama dan memasukkan versi baharu secara atomik, dengan satu baris semasa dan selang yang tidak bertindih. Kunci yang hilang bermaksud pemadaman hanya di bawah kontrak snapshot lengkap; kelompok lewat disusun atau dikuarantin mengikut tera air, dan kontrak laporan menentukan sama ada sejarah perlu dibetulkan."
Kesilapan biasa
- Menggunakan Jenis 2 secara lalai untuk setiap dimensi → kos storan dan pertanyaan lebih tinggi → tanya kontrak sejarah terlebih dahulu.
- Menggunakan masa ketibaan sebagai masa berkuat kuasa → snapshot tidak mengikut urutan merosakkan sejarah → gunakan masa berkuat kuasa perniagaan atau baris gilir pembetulan.
- Menganggap kunci yang hilang dalam fail bertambah sebagai pemadaman → penambahan yang sah dipadamkan → simpulkan pemadaman hanya daripada snapshot lengkap.
- Mengemas kini
is_currenttanpa versi kunci pengganti → fakta tidak boleh dicantumkan dengan keadaan titik masa → tutup baris lama dan tambah versi baharu. - Meninggalkan kunci idempotensi kelompok → main semula menambah sejarah pendua → kuat kuasakan keunikan pada cincangan fail atau id kelompok.
Soalan susulan dan respons mantap
Patutkah peristiwa lewat menyemak semula laporan yang diterbitkan?
Sahkan sama ada laporan tersebut boleh disemak semula. Jika ya, bahagikan selang berkuat kuasa mengikut masa perniagaan dan kira semula fakta yang terjejas; jika tidak, kekalkan hasil yang diterbitkan dan keluarkan kelompok pembetulan bersama kesannya. Kedua-dua kontrak mengekalkan kelompok mentah supaya nombor tidak berubah secara senyap.
Bagaimana jika seorang pelanggan muncul dua kali dalam satu snapshot?
Anggap ia sebagai ralat kualiti input. Pilih satu baris hanya apabila versi perniagaan atau jujukan sumber menentukan pemenang; jika tidak, kuarantin dan beri amaran. LIMIT 1 yang sewenang-wenangnya menjadikan sejarah tidak dapat dihasilkan semula.
Bilakah Jenis 3 lebih baik daripada Jenis 2?
Gunakan Jenis 3 apabila satu-satunya perbandingan yang diperlukan ialah semasa berbanding sebelumnya dan versi yang lebih lama tidak akan ditanya sama sekali. Ia menggunakan storan yang lebih sedikit dan pertanyaan yang lebih ringkas. Jika sejarah tarikh sewenang-wenangnya diperlukan kemudian, berhijrah ke Jenis 2 dan nyatakan kos pengisian semula (backfill).
Bagaimanakah anda mengesahkan bahawa selang masa tidak bertindih?
Isih mengikut kunci semula jadi dan pastikan setiap selang tamat tidak lewat daripada selang seterusnya bermula, kemudian sahkan paling banyak satu baris semasa bagi setiap kunci. Jadikan ini sebagai syarat pelepasan kelompok (release gate) dan bukannya pensampelan retrospektif.