Panduan hubungan banyak ke banyak
Artikel ini menargetkan Anda sebagai pemodel data yang bekerja dengan Power BI Desktop. Panduan ini menjelaskan tiga skenario pemodelan banyak ke banyak yang berbeda. Juga memberi Anda panduan tentang cara merancangnya dengan benar pada model Anda.
Catatan
Pengantar relasi model tidak tercakup dalam artikel ini. Jika Anda tidak sepenuhnya terbiasa dengan hubungan, propertinya, atau cara mengonfigurasinya, kami sarankan Anda terlebih dahulu membaca artikel Relasi model di Power BI Desktop.
Penting juga jika Anda memiliki pemahaman tentang desain skema bintang. Untuk informasi selengkapnya, lihat Memahami skema bintang dan pentingnya Power BI.
Pada kenyataannya, ada tiga skenario banyak-ke-banyak. Skenario ini dapat terjadi ketika Anda diharuskan untuk:
- Menghubungkan dua tabel berjenis dimensi
- Menghubungkan dua tabel berjenis fakta
- Menghubungkan tabel jenis fakta butir yang lebih tinggi, saat tabel jenis fakta menyimpan baris pada butir yang lebih tinggi daripada baris tabel jenis dimensi
Catatan
Power BI sekarang secara asli mendukung relasi banyak ke banyak. Untuk informasi selengkapnya, lihat Menerapkan relasi banyak ke banyak di Power BI Desktop.
Menghubungkan dimensi banyak ke banyak
Mari kita pelajari contoh jenis skenario banyak ke banyak yang pertama. Tipikal skenario yang berkaitan dengan dua entitas: nasabah bank dan rekening bank. Ketahui bahwa pelanggan dapat memiliki beberapa rekening, dan rekening dapat dipegang beberapa pelanggan. Ketika akun memiliki beberapa pelanggan, mereka biasanya disebut pemegang rekening bersama.
Pemodelan entitas ini sederhana. Satu tabel jenis dimensi menyimpan rekening, dan tabel jenis dimensi lainnya menyimpan pelanggan. Seperti karakteristik tabel jenis dimensi, terdapat kolom ID pada setiap tabelnya. Untuk memodelkan relasi antara dua tabel, maka diperlukan tabel ketiga. Tabel ini biasanya disebut sebagai tabel bridging. Dalam contoh ini, tujuannya adalah untuk menyimpan satu baris untuk setiap asosiasi rekening pelanggan. Menariknya, ketika tabel ini hanya berisi kolom ID, tabel ini disebut tabel fakta tanpa fakta.
Berikut adalah diagram model sederhana dari tiga tabel tersebut.
Tabel pertama diberi nama Akun, berisikan dua kolom: AccountID dan Akun. Tabel kedua diberi nama AccountCustomer, berisikan dua kolom: AccountID dan CustomerID. Tabel ketiga diberi nama Pelanggan, berisikan dua kolom: CustomerID dan Pelanggan. Tidak ada relasi di antara tabel yang tersedia.
Dua relasi satu ke banyak ditambahkan untuk menghubungkan tabel. Berikut adalah diagram model yang diperbarui dari tabel terkait. Tabel jenis fakta bernama Transaksi telah ditambahkan. Tabel ini akan mencatat transaksi rekening. Tabel bridging dan semua kolom ID telah disembunyikan.
Diagram model telah dimodifikasi untuk mengungkapkan baris tabel.guna membantu menjelaskan cara kerja penyebaran filter relasi.
Catatan
Tidak dimungkinkan untuk menampilkan baris tabel dalam diagram model Power BI Desktop. Telah dijelaskan dalam artikel ini untuk mendukung diskusi dengan contoh yang jelas.
Detail baris untuk empat tabel tersebut dijelaskan dalam daftar berikut ini:
- Tabel Akun memiliki dua baris:
- AccountID 1 adalah untuk Akun-01
- AccountID 2 adalah untuk Akun-02
- Tabel Pelanggan memiliki dua baris:
- CustomerID 91 adalah untuk Pelanggan-91
- CustomerID 92 adalah untuk Pelanggan-92
- Tabel AccountCustomer memiliki tiga baris:
- AccountID 1 dikaitkan dengan CustomerID 91
- AccountID 1 dikaitkan dengan CustomerID 92
- AccountID 2 dikaitkan dengan CustomerID 92
- Tabel Transaksi memiliki tiga baris:
- Tanggal 1 Januari 2019, AccountID 1, Jumlah 100
- Tanggal 2 Februari 2019, AccountID 2, Jumlah 200
- Tanggal 3 Maret 2019, AccountID 1, Jumlah -25
Mari kita lihat apa yang terjadi ketika model dikueri.
Di bawah ini adalah dua visual yang meringkas kolom Jumlah dari tabel Transaksi. Visual pertama dikelompokkan menurut rekening, sehingga jumlah kolom Jumlah mewakili saldo rekening. Visual kedua dikelompokkan menurut pelanggan, sehingga jumlah kolom Jumlah mewakili saldo pelanggan.
Visual pertama berjudul Saldo Akun, dan memiliki dua kolom: Akun dan Jumlah. Yang menampilkan hasil berikut:
- Jumlah saldo Akun-01 adalah 75
- Jumlah saldo Akun-02 adalah 200
- Totalnya adalah 275
Visual kedua berjudul Saldo Pelanggan, dan memiliki dua kolom: Pelanggan dan Jumlah. Yang menampilkan hasil berikut:
- Jumlah saldo Pelanggan-91 adalah 275
- Jumlah saldo Pelanggan-92 adalah 275
- Totalnya adalah 275
Sekilas baris tabel dan visual dari Saldo Akun memperlihatkan bahwa hasilnya benar untuk setiap rekening dan jumlah totalnya. Ini karena setiap pengelompokan rekening menghasilkan penyebaran filter ke tabel Transaksi untuk rekening tersebut.
Namun, ada yang tidak beres dengan visual Saldo Pelanggan. Setiap pelanggan dalam visual Saldo Pelanggan memiliki saldo yang sama dengan total saldo. Hasil ini hanya bisa benar jika setiap pelanggan adalah pemegang rekening bersama dari setiap rekening. Namun bukan itu masalah yang ada dalam contoh ini. Masalah ini terkait dengan penyebaran filter. Penyebaran filternya tidak menyebar sampai ke tabel Transaksi.
Ikuti petunjuk filter relasi dari tabel Pelanggan ke tabel Transaksi. Seharusnya terlihat bahwa relasi antara tabel Akun dan AccountCustomer menyebar ke arah yang salah. Arah filter untuk relasi ini harus diatur ke Keduanya.
Seperti yang diperkirakan, belum ada perubahan pada visual Saldo Akun.
Namun, visual Saldo Pelanggan sekarang menampilkan hasil berikut:
- Jumlah saldo Pelanggan-91 adalah 75
- Jumlah saldo Pelanggan-92 adalah 275
- Totalnya adalah 275
Visual Saldo Pelanggan sekarang menampilkan hasil yang benar. Ikuti petunjuk filter, dan lihat bagaimana saldo pelanggan dihitung. Selain itu, pahami bahwa total visual berarti semua pelanggan.
Pengguna yang tidak terbiasa dengan relasi model mungkin menyimpulkan bahwa hasilnya salah. Mereka mungkin akan menanyakan: Mengapa total saldo untuk Pelanggan-91 dan Pelanggan-92 tidak sama dengan 350 (75 + 275)?
Jawaban atas pertanyaan mereka adalah pemahaman relasi banyak-ke-banyak. Setiap saldo pelanggan dapat mewakili penambahan beberapa saldo rekening, sehingga saldo pelanggan non-aditif.
Menghubungkan dimensi banyak ke banyak
Saat Anda menggunakan relasi banyak ke banyak di antara tabel jenis dimensi, kami akan berikan panduan berikut:
- Tambahkan setiap entitas terkait banyak ke banyak sebagai tabel model, memastikannya memiliki kolom pengidentifikasi (ID) unik
- Tambahkan tabel bridging untuk menyimpan entitas terkait
- Buat relasi satu-ke-banyak di antara tiga tabel tersebut
- Konfigurasi satu relasi dua arah untuk memungkinkan penyebaran filter berlanjut ke tabel jenis fakta
- Jika nilai ID yang hilang tidak sesuai, atur properti Dapat Diubah ke Null dari kolom ID ke FALSE—melakukan refresh data akan gagal jika nilai yang hilang bersumber
- Sembunyikan tabel bridging (kecuali berisi kolom atau ukuran tambahan yang diperlukan untuk pelaporan)
- Sembunyikan semua kolom ID yang tidak cocok untuk pelaporan (misalnya, saat ID adalah kunci pengganti)
- Jika ingin agar kolom ID terlihat, pastikan kolom tersebut berada di "satu" slide relasi—selalu sembunyikan kolom samping yang "banyak". Dengan begitu akan menghasilkan performa filter terbaik.
- Untuk menghindari kebingungan atau salah tafsir, sampaikan penjelasan kepada pengguna laporan—Anda dapat menambahkan deskripsi dengan kotak teks atau tipsalat header visual
Kami tidak menyarankan Anda menghubungkan tabel jenis dimensi banyak ke banyak secara langsung. Pendekatan desain ini memerlukan konfigurasi relasi dengan kardinalitas banyak-ke-banyak. Secara konseptual dapat dicapai, namun ini menyiratkan bahwa kolom terkait akan berisikan nilai duplikat. Pendekatan ini merupakan praktik desain yang diterima dengan baik, namun, tabel jenis dimensi tersebut memiliki kolom ID. Tabel jenis dimensi harus selalu menggunakan kolom ID sebagai sisi "satu" dari relasi.
Hubungkan fakta banyak ke banyak
Jenis skenario banyak-ke-banyak yang kedua melibatkan dua tabel jenis fakta berkaitan. Dua tabel jenis fakta dapat terkait secara langsung. Teknik desain ini dapat berguna untuk eksplorasi data yang cepat dan sederhana. Namun, agar jelas, kami umumnya tidak menyarankan pendekatan desain ini. Akan kami jelaskan alasannya nanti di bagian ini.
Mari kita pelajari contoh yang melibatkan dua tabel jenis fakta: Pesanan dan Pemenuhan. Tabel Pesanan berisikan satu baris per baris pesanan, dan tabel Pemenuhan dapat berisi nol atau beberapa baris per baris pesanan. Baris dalam tabel Pesanan mewakili pesanan penjualan. Baris dalam tabel Pemenuhan mewakili item pesanan yang telah dikirim. Relasi banyak ke banyak berkaitan dengan dua kolom OrderID, dengan penyebaran filter hanya dari tabel Pemenuhan (Pemenuhan memfilter Pesanan).
Kardinalitas relasi diatur ke banyak-ke-banyak untuk mendukung penyimpanan nilai OrderID duplikat di kedua tabel. Dalam tabel Pesanan, nilai OrderID yang terduplikat bisa muncul karena pesanan bisa memiliki beberapa baris. Dalam tabel Pemenuhan, nilai OrderID yang terduplikat dapat muncul karena pesanan mungkin memiliki beberapa baris, dan baris pesanan dapat dipenuhi oleh banyak pengiriman.
Sekarang mari kita lihat baris tabel. Dalam tabel Pemenuhan, perhatikan bahwa baris pesanan dapat dipenuhi oleh beberapa pengiriman. (Tidak adanya baris pesanan berarti pesanan belum terpenuhi.)
Detail baris untuk dua tabel tersebut dijelaskan dalam daftar berikut ini:
- Tabel Pesanan memiliki lima baris:
- OrderDate 1 Januari 2019, OrderID 1, OrderLine 1, ProductID Prod-A, OrderQuantity 5, Penjualan 50
- OrderDate 1 Januari 2019, OrderID 1, OrderLine 2, ProductID Prod-B, OrderQuantity 10, Penjualan 80
- OrderDate 2 Februari 2019, OrderID 2, OrderLine 1, ProductID Prod-B, OrderQuantity 5, Penjualan 40
- OrderDate 2 Februari 2019, OrderID 2, OrderLine 2, ProductID Prod-C, OrderQuantity 1, Penjualan 20
- OrderDate 3 Maret 2019, OrderID 3, OrderLine 1, ProductID Prod-C, OrderQuantity 5, Penjualan 100
- Tabel Pemenuhan memiliki empat baris:
- FulfillmentDate 1 Januari 2019, FulfillmentID 50, OrderID 1, OrderLine 1, FulfillmentQuantity 2
- FulfillmentDate 2 Februari 2019, FulfillmentID 51, OrderID 1, OrderLine 1, FulfillmentQuantity 5
- FulfillmentDate 2 Februari 2019, FulfillmentID 52, OrderID 1, OrderLine 1, FulfillmentQuantity 3
- FulfillmentDate 1 Januari 2019, FulfillmentID 53, OrderID 1, OrderLine 2, FulfillmentQuantity 10
Mari kita lihat apa yang terjadi ketika model dikueri. Berikut adalah visual tabel yang membandingkan jumlah pesanan dan pemenuhan menurut tabel Pesanan kolom OrderID.
Visual ini menyajikan hasil yang akurat. Namun, kegunaan model terbatas—Anda hanya dapat memfilter atau mengelompokkan menurut tabel Pesanan kolom OrderID.
Panduan menghubungkan fakta banyak ke banyak
Umumnya, kami tidak menyarankan untuk menghubungkan dua tabel jenis fakta secara langsung menggunakan kardinalitas banyak ke banyak. Alasan utamanya adalah karena model tidak akan memberikan fleksibilitas dalam cara Anda melaporkan filter visual atau grup. Dalam contoh tersebut, visual hanya dimungkinkan untuk memfilter atau mengelompokkan menurut tabel Pesanan kolom OrderID. Alasan lainnya berkaitan dengan kualitas data Anda. Jika data Anda memiliki masalah integritas, ada kemungkinan beberapa baris dapat dihilangkan selama kueri karena sifat relasi yang terbatas. Untuk informasi selengkapnya, lihat Relasi model di Power BI Desktop (Evaluasi relasi).
Alih-alih menghubungkan tabel jenis fakta secara langsung, kami sarankan Anda memakai prinsip desain Skema Bintang. Dilakukan dengan menambahkan tabel jenis dimensi. Tabel jenis dimensi kemudian berhubungan dengan tabel jenis fakta dengan menggunakan relasi satu-ke-banyak. Pendekatan desain ini kuat karena memberikan opsi pelaporan yang fleksibel. Pendekatan ini memungkinkan Anda memfilter atau mengelompokkan menggunakan salah satu kolom jenis dimensi, dan meringkas tabel jenis fakta terkait.
Mari kita pertimbangkan solusi yang lebih baik.
Perhatikan perubahan desain berikut:
- Sekarang model ini memiliki empat tabel tambahan: OrderLine, OrderDate, Produk, dan FulfillmentDate
- Empat tabel tambahan ini adalah semua tabel jenis dimensi, dan relasi satu-ke-banyak menghubungkan tabel ini dengan tabel jenis fakta
- Tabel OrderLine berisi kolom OrderLineID, yang mewakili nilai OrderID dikalikan dengan 100, ditambah nilai OrderLine—pengidentifikasi unik untuk setiap baris pesanan
- Tabel Pesanan dan Pemenuhan sekarang berisi kolom OrderLineID, dan tidak lagi berisi kolom OrderID dan OrderLine
- Tabel Pemenuhan sekarang berisi kolom OrderDate dan ProductID
- Tabel FulfillmentDate hanya berkaitan dengan tabel Pemenuhan
- Semua kolom pengidentifikasi unik disembunyikan
Meluangkan waktu untuk menerapkan prinsip desain skema bintang memberikan keuntungan berikut:
- Visual laporan Anda dapat memfilter atau mengelompokkan menurut kolom apa saja yang terlihat dari tabel jenis dimensi
- Visual laporan Anda dapat meringkas menurut kolom apa saja yang terlihat dari tabel jenis fakta
- Filter yang diterapkan ke tabel OrderLine, OrderDate, atau Produk akan disebarluaskan ke kedua tabel jenis fakta
- Semua relasi bersifat satu-ke-banyak, dan setiap relasi adalah relasi reguler. Masalah integritas data tidak akan ditutupi. Untuk informasi selengkapnya, lihat Relasi model di Power BI Desktop (Evaluasi relasi).
Menghubungkan fakta butir yang lebih tinggi
Skenario banyak-ke-banyak ini sangat berbeda dari dua lainnya yang sudah dijelaskan dalam artikel ini.
Mari kita pelajari contoh yang melibatkan empat tabel: Tanggal, Penjualan, Produk, dan Target. Tanggal dan Produk adalah tabel jenis dimensi, dan relasi satu-ke-banyak masing-masing berhubungan dengan tabel jenis fakta Penjualan. Sejauh ini, proses ini mewakili desain skema bintang yang baik. Namun, tabel Target belum berkaitan dengan tabel lain.
Tabel Target berisi tiga kolom: Kategori, TargetQuantity, dan TargetYear. Baris tabel mengungkapkan perincian tahun dan kategori produk. Dengan kata lain, target—digunakan untuk mengukur performa penjualan—ditetapkan setiap tahun untuk setiap kategori produk.
Karena tabel Target menyimpan data pada tingkat yang lebih tinggi dari tabel jenis dimensi, relasi satu-ke-banyak tidak dapat dibuat. Itu benar hanya untuk salah satu relasi. Mari kita selidiki bagaimana tabel Target dapat terkait dengan tabel jenis dimensi.
Menghubungkan periode waktu butir yang lebih tinggi
Relasi antara tabel Tanggal dan Target harus merupakan relasi satu-ke-banyak. Ini karena nilai kolom TargetYear berupa tanggal. Dalam contoh ini, setiap nilai kolom TargetYear adalah tanggal pertama tahun target.
Tip
Saat menyimpan fakta pada perincian waktu yang lebih tinggi dari hari, atur jenis data kolom ke Tanggal (atau Bilangan bulat jika Anda menggunakan kunci tanggal). Di kolom, simpan nilai yang mewakili hari pertama dari periode waktu. Misalnya, periode tahun dicatat sebagai 1 Januari tahun itu, dan periode bulan dicatat sebagai hari pertama bulan itu.
Namun, perawatan harus dilakukan untuk memastikan bahwa filter tingkat bulan atau tanggal menghasilkan hasil yang berarti. Tanpa logika perhitungan tertentu, visual laporan dapat melaporkan bahwa tanggal target secara harfiah adalah hari pertama pada setiap tahun. Hari-hari lainnya—dan semua bulan kecuali Januari—akan meringkas kuantitas target sebagai BLANK.
Visual matriks berikut menunjukkan apa yang terjadi ketika pengguna laporan menelusuri dari tahun ke bulan. Visual ini meringkas kolom TargetQuantity. (Opsi Perlihatkan item tanpa data telah diaktifkan untuk baris matriks.)
Untuk menghindari tindakan ini, kami sarankan Anda mengontrol ringkasan data fakta Anda dengan menggunakan pengukuran. Salah satu cara untuk mengontrol ringkasan adalah dengan mengembalikan BLANK ketika periode waktu tingkat yang lebih rendah dikueri. Cara lain—yang didefinisikan dengan beberapa DAX canggih—adalah dengan membagi nilai di seluruh periode waktu tingkat yang lebih rendah.
Pertimbangkan definisi pengukuran berikut yang menggunakan fungsi DAX ISFILTERED. Pengukuran ini hanya mengembalikan nilai saat kolom Tanggal atau Bulan tidak difilter.
Target Quantity =
IF(
NOT ISFILTERED('Date'[Date])
&& NOT ISFILTERED('Date'[Month]),
SUM(Target[TargetQuantity])
)
Visual matriks berikut kini menggunakan ukuran Jumlah Target. Yang menunjukkan bahwa semua jumlah target bulanan adalah BLANK.
Menghubungkan butir yang lebih tinggi (non-tanggal)
Pendekatan desain yang berbeda diperlukan saat menghubungkan kolom non-tanggal dari tabel jenis dimensi ke tabel jenis fakta (dan berada pada butir yang lebih tinggi daripada tabel jenis dimensi).
Kolom Kategori (dari tabel Produk dan Target) berisi nilai duplikat. Jadi, tidak ada "satu" pada relasi satu-ke-banyak. Dalam hal ini, Anda harus membuat relasi banyak ke banyak. Relasi harus menyebarkan filter dalam satu arah, dari tabel jenis dimensi ke tabel jenis fakta.
Sekarang mari kita lihat baris tabel.
Terdapat empat baris dalam tabel Target: dua baris untuk setiap tahun target (tahun 2019 dan 2020), dan dua kategori (Pakaian dan Aksesori). Dalam tabel Produk, terdapat tiga produk. Dua di antaranya termasuk dalam kategori pakaian, dan satu dalam kategori aksesori. Salah satu warna pakaian berwarna hijau, dan dua lainnya berwarna biru.
Pengelompokan visual tabel menurut kolom Kategori dari tabel Produk menghasilkan hasil berikut.
Visual ini menghasilkan hasil yang benar. Sekarang mari kita pertimbangkan apa yang terjadi ketika kolom Warna dari tabel Produk digunakan untuk mengelompokkan kuantitas target.
Visual ini menghasilkan pernyataan yang salah tentang data. Apa yang terjadi di sini?
Filter pada kolom Warna dari tabel Produk menghasilkan dua baris. Salah satu baris untuk kategori Pakaian, dan yang lainnya untuk kategori Aksesori. Kedua nilai kategori ini disebarluaskan sebagai filter ke tabel Target. Dengan kata lain, karena warna biru digunakan oleh produk dari dua kategori, kategori tersebut digunakan untuk memfilter target.
Untuk menghindari tindakan ini, seperti yang telah dijelaskan sebelumnya, kami sarankan Anda mengontrol ringkasan data fakta Anda dengan menggunakan pengukuran.
Pertimbangkan definisi alur kerja berikut. Perhatikan bahwa semua kolom tabel Produk yang berada di bawah tingkat kategori diuji filternya.
Target Quantity =
IF(
NOT ISFILTERED('Product'[ProductID])
&& NOT ISFILTERED('Product'[Product])
&& NOT ISFILTERED('Product'[Color]),
SUM(Target[TargetQuantity])
)
Visual matriks berikut kini menggunakan ukuran Jumlah Target. Yang menunjukkan bahwa semua jumlah target warna adalah BLANK.
Desain model akhir terlihat seperti berikut ini.
Menghubungkan fakta butir yang lebih tinggi
Saat Anda perlu menghubungkan tabel jenis dimensi dengan tabel jenis fakta, dan tabel jenis fakta menyimpan baris pada butir yang lebih tinggi daripada baris tabel jenis dimensi, maka kami berikan panduan berikut:
- Untuk tanggal fakta grain yang lebih tinggi:
- Dalam tabel jenis fakta, simpan tanggal pertama dari periode waktu
- Buat relasi satu-ke-banyak di antara tabel tanggal dan tabel jenis fakta
- Untuk fakta biji-bijian lain yang lebih tinggi:
- Buat relasi banyak-ke-banyak di antara tabel jenis dimensi dan tabel jenis fakta
- Untuk kedua jenis:
- Ringkas kontrol dengan logika pengukuran—mengembalikan BLANK saat kolom jenis dimensi tingkat bawah digunakan untuk memfilter atau mengelompokkan
- Sembunyikan kolom tabel jenis fakta yang dapat diringkas—dengan cara ini, hanya pengukuran yang dapat digunakan untuk meringkas tabel jenis fakta
Konten terkait
Untuk informasi selengkapnya tentang dokumen resmi ini, lihat sumber daya berikut:
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk