Panduan hubungan banyak-ke-banyak
Artikel ini menargetkan Anda sebagai pemodel data yang bekerja dengan Power BI Desktop. Ini menjelaskan tiga skenario pemodelan banyak-ke-banyak yang berbeda. Ini juga memberi Anda panduan tentang cara mendesainnya dengan sukses dalam model Anda.
Nota
Pengantar hubungan model tidak tercakup dalam artikel ini. Jika Anda tidak sepenuhnya terbiasa dengan hubungan, propertinya, atau cara mengonfigurasinya, kami sarankan Anda terlebih dahulu membaca hubungan Model di Power BI Desktop artikel.
Penting juga bahwa Anda memiliki pemahaman tentang desain skema bintang. Untuk informasi selengkapnya, lihat Memahami skema bintang dan pentingnya bagi Power BI.
Ada tiga skenario relasi banyak-ke-banyak yang berbeda. Ini dapat terjadi ketika Anda diharuskan untuk:
- Menghubungkan dua tabel dimensi
- Menghubungkan dua tabel fakta
- Mengaitkan tabel fakta dengan granularitas lebih tinggi, ketika tabel fakta menyimpan baris pada tingkat granularitas yang lebih tinggi daripada baris tabel dimensi.
Menghubungkan dimensi banyak-ke-banyak
Skenario klasik banyak ke banyak berkaitan dengan dua entitas, misalnya nasabah bank dan rekening bank. Pertimbangkan bahwa pelanggan dapat memiliki beberapa akun, dan akun dapat memiliki beberapa pelanggan. Ketika sebuah rekening memiliki beberapa pelanggan, mereka biasanya disebut pemegang rekening bersama.
Pemodelan entitas ini sederhana. Satu tabel dimensi menyimpan akun, dan tabel dimensi lain menyimpan pelanggan. Seperti karakteristik tabel dimensi, ada kolom pengidentifikasi unik (ID) di setiap tabel. Untuk memodelkan hubungan antara dua tabel, tabel ketiga diperlukan. Tabel ini biasanya disebut tabel penghubung . Dalam contoh ini, tujuannya adalah untuk menyimpan satu baris untuk setiap asosiasi akun pelanggan. Menariknya, ketika tabel ini hanya berisi kolom pengidentifikasi, tabel ini disebut tabel fakta tanpa fakta .
Berikut adalah diagram sederhana dari tiga tabel model.
Tabel pertama diberi nama Account
, dan berisi dua kolom: AccountID
dan Account
. Tabel kedua diberi nama AccountCustomer
, dan berisi dua kolom: AccountID
dan CustomerID
. Tabel ketiga diberi nama Customer
, dan berisi dua kolom: CustomerID
dan Customer
. Hubungan tidak ada di antara tabel-tabel.
Dua relasi satu-ke-banyak ditambahkan untuk mengaitkan tabel. Berikut adalah diagram model yang diperbarui dari tabel terkait. Tabel fakta bernama Transaction
telah ditambahkan. Ini mencatat transaksi akun. Tabel penghubung dan semua kolom pengidentifikasi telah disembunyikan.
Untuk membantu menjelaskan cara kerja penyebaran filter hubungan, diagram model telah dimodifikasi untuk mengungkapkan baris tabel.
Detail baris untuk empat tabel disajikan dalam daftar berpoin berikut:
- Tabel
Account
memiliki dua baris:-
AccountID
1 adalah untuk Account-01 -
AccountID
2 adalah untuk Akun-02
-
- Tabel
Customer
memiliki dua baris:-
CustomerID
91 adalah untuk Customer-91 -
CustomerID
92 untuk Customer-92
-
- Tabel
AccountCustomer
memiliki tiga baris:-
AccountID
1 dikaitkan denganCustomerID
91 -
AccountID
1 dikaitkan denganCustomerID
92 -
AccountID
2 dikaitkan denganCustomerID
92
-
- Tabel
Transaction
memiliki tiga baris:-
Date
1 Januari 2019,AccountID
1,Amount
100 -
Date
2 Februari 2019,AccountID
2,Amount
200 -
Date
3 Maret 2019,AccountID
1,Amount
-25
-
Mari kita lihat apa yang akan terjadi ketika model diminta informasi.
Dalam gambar berikut, terdapat dua visual tabel yang merangkum kolom Amount
dari tabel Transaction
. Grup visual pertama menurut akun, sehingga jumlah kolom Amount
mewakili saldo akun . Grup visual kedua disusun berdasarkan pelanggan, dan karenanya total kolom Amount
menunjukkan saldo pelanggan .
Visual tabel pertama (Saldo Akun) memiliki dua kolom: Account
dan Amount
. Ini menampilkan hasil berikut:
- jumlah saldo Akun-01 75.
- Akun-02 jumlah saldo adalah 200.
- Totalnya adalah 275.
Visual tabel kedua (Saldo Pelanggan) memiliki dua kolom: Customer
dan Amount
. Ini menampilkan hasil berikut:
- Saldo Pelanggan-91 adalah 275.
- Saldo Pelanggan-92 adalah 275.
- Totalnya adalah 275.
Sekilas baris tabel dan visual Saldo Akun mengungkapkan bahwa hasilnya benar, untuk setiap akun dan jumlah total. Itu karena setiap pengelompokan akun menghasilkan penyebaran filter ke tabel Transaction
untuk akun tersebut.
Namun, ada sesuatu yang tidak terlihat benar dengan visual Saldo Pelanggan. Setiap pelanggan dalam visual ini memiliki saldo yang sama dengan total saldo. Hasil ini hanya bisa benar jika setiap pelanggan adalah pemegang akun bersama dari setiap akun. Itu tidak terjadi dalam contoh ini. Ada masalah, dan terkait dengan penyebaran filter. Filter tidak mengalir sepenuhnya ke tabel Transaction
.
Jika Anda mengikuti petunjuk filter hubungan dari tabel Customer
ke tabel Transaction
, Anda dapat menentukan bahwa hubungan antara tabel Account
dan AccountCustomer
menyebar ke arah yang salah. Arah filter untuk hubungan ini harus diatur ke Both
.
diagram
Seperti yang diharapkan, belum ada perubahan pada visual Saldo Akun.
Namun, visual Saldo Pelanggan menampilkan hasil berikut:
- jumlah saldo Pelanggan-91 75.
- jumlah saldo Pelanggan-92 adalah 275.
- Totalnya adalah 275.
Visual Saldo Pelanggan sekarang menampilkan hasil yang benar. Ikuti petunjuk filter untuk diri Anda sendiri, dan lihat bagaimana saldo pelanggan dihitung. Selain itu, pahami bahwa keseluruhan visual berarti semua pelanggan.
Seseorang yang tidak terbiasa dengan hubungan model dapat menyimpulkan bahwa hasilnya salah. Mereka mungkin bertanya: Mengapa saldo total untuk Customer-91
dan Customer-92
tidak sama dengan 350 (75 + 275)?
Jawaban atas pertanyaan mereka terletak pada pemahaman hubungan banyak-ke-banyak. Setiap saldo pelanggan dapat mewakili penambahan beberapa saldo akun, sehingga saldo pelanggan non-aditif.
Menghubungkan panduan dimensi banyak ke banyak
Saat Anda memiliki hubungan banyak ke banyak antara tabel dimensi, ikuti panduan ini:
- Tambahkan setiap entitas terkait banyak-ke-banyak sebagai tabel model, memastikannya memiliki kolom ID.
- Tambahkan tabel bridging untuk menyimpan entitas terkait.
- Buat hubungan satu-ke-banyak di antara ketiga tabel.
- Atur satu relasi dua arah agar filter dapat menyebar ke tabel fakta.
- Jika tidak sesuai untuk memiliki nilai ID yang hilang, nonaktifkan properti
Is Nullable
—refresh data akan gagal saat nilai yang hilang bersumber. - Sembunyikan tabel bridging (kecuali jika memuat kolom atau metrik lain yang diperlukan untuk pelaporan).
- Sembunyikan kolom ID apa pun yang tidak cocok untuk pelaporan (misalnya, saat kolom menyimpan nilai kunci pengganti).
- Jika masuk akal untuk membiarkan kolom ID terlihat, pastikan kolom tersebut berada di sisi "satu" dari hubungan—selalu sembunyikan kolom sisi "banyak". Itu karena filter yang diterapkan ke slide "satu" menghasilkan performa filter yang lebih baik.
- Untuk menghindari kebingungan atau salah tafsir, berikan penjelasan kepada pengguna laporan Anda—Anda dapat menambahkan deskripsi dengan kotak teks, atau tooltip header visual.
Kami tidak menyarankan Anda mengaitkan tabel dimensi yang bersifat banyak ke banyak secara langsung. Pendekatan desain ini membutuhkan pengaturan hubungan dengan kardinalitas banyak-ke-banyak. Secara konseptual dapat dicapai, namun menyiratkan bahwa kolom terkait mungkin berisi nilai duplikat. Namun, ini adalah praktik desain yang diterima dengan baik, tabel dimensi tersebut memiliki kolom ID. Tabel dimensi harus selalu menggunakan kolom ID sebagai sisi "satu" hubungan.
Menghubungkan banyak-ke-banyak fakta
Sebuah jenis skenario banyak-ke-banyak yang berbeda melibatkan hubungan antara dua tabel fakta. Dua tabel fakta dapat terkait secara langsung. Teknik desain ini dapat berguna untuk eksplorasi data yang cepat dan sederhana. Namun, dan agar jelas, kami umumnya tidak merekomendasikan pendekatan desain ini. Kami akan menjelaskan mengapa nanti di bagian ini.
Mari kita pertimbangkan contoh yang melibatkan dua tabel fakta: Order
dan Fulfillment
. Tabel Order
berisi satu baris per baris pesanan, dan tabel Fulfillment
dapat berisi nol atau lebih baris per baris pesanan. Baris dalam tabel Order
mewakili pesanan penjualan. Baris dalam tabel Fulfillment
mewakili item pesanan yang telah dikirim. Hubungan banyak-ke-banyak berkaitan dengan kolom OrderID
di setiap tabel, dengan propagasi filter hanya dari tabel Order
(yang berarti tabel Order
memfilter tabel Fulfillment
).
diagram
Kardinalitas hubungan diatur ke Many-to-many
untuk mendukung penyimpanan nilai kolom duplikat OrderID
di kedua tabel. Dalam tabel Order
, nilai ID duplikat bisa ada karena pesanan bisa memiliki beberapa baris. Dalam tabel Fulfillment
, nilai ID duplikat dapat ada karena pesanan dapat memiliki beberapa baris, dan baris pesanan dapat dipenuhi oleh banyak pengiriman.
Sekarang mari kita lihat baris-baris tabel. Dalam tabel Fulfillment
, perhatikan bahwa baris pesanan dapat dipenuhi oleh beberapa pengiriman. (Tidak adanya baris pesanan berarti pesanan belum terpenuhi.)
Detail baris untuk dua tabel dijelaskan dalam daftar berpoin berikut:
- Tabel
Order
memiliki lima baris:-
OrderDate
1 Januari 2019,OrderID
1,OrderLine
1,ProductID
Prod-A,OrderQuantity
5,Sales
50 -
OrderDate
1 Januari 2019,OrderID
1,OrderLine
2,ProductID
Prod-B,OrderQuantity
10,Sales
80 -
OrderDate
2 Februari 2019,OrderID
2,OrderLine
1,ProductID
Prod-B,OrderQuantity
5,Sales
40 -
OrderDate
2 Februari 2019,OrderID
2,OrderLine
2,ProductID
Prod-C,OrderQuantity
1,Sales
20 -
OrderDate
3 Maret 2019,OrderID
3,OrderLine
1,ProductID
Prod-C,OrderQuantity
5,Sales
100
-
- Tabel
Fulfillment
memiliki empat baris:-
FulfillmentDate
1 Januari 2019,FulfillmentID
50,OrderID
1,OrderLine
1,FulfillmentQuantity
2 -
FulfillmentDate
2 Februari 2019,FulfillmentID
51,OrderID
2,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 tabel visual yang membandingkan jumlah pesanan dan pemenuhan berdasarkan kolom OrderID
pada tabel Order
.
Diagram
Visual menyajikan hasil yang akurat. Namun, kegunaan model dibatasi karena Anda hanya dapat memfilter atau mengelompokkan menurut tabel Order
OrderID
kolom.
Menghubungkan panduan fakta banyak ke banyak
Umumnya, kami tidak menyarankan Anda menghubungkan dua tabel fakta secara langsung dengan menggunakan kardinalitas banyak ke banyak. Alasan utamanya adalah karena model tidak akan memberikan fleksibilitas dalam cara visual laporan Anda memfilter atau mengelompokkan. Dalam contoh ini, visual hanya bisa memfilter atau mengelompokkan menurut kolom OrderID
dari tabel Order
. Alasan lain berkaitan dengan kualitas data Anda. Jika data Anda memiliki masalah integritas, ada kemungkinan beberapa baris mungkin dihilangkan selama kueri karena sifat kardinalitas banyak ke manusia dan hubungan terbatas.
Alih-alih menghubungkan tabel fakta secara langsung, kami sarankan Anda menerapkan desain skema bintang . Itu berarti Anda menambahkan tabel dimensi. Tabel dimensi ini kemudian berhubungan dengan tabel fakta dengan menggunakan hubungan satu-ke-banyak. Pendekatan desain ini kuat karena secara efisien memberikan opsi pelaporan yang fleksibel. Ini memungkinkan Anda memfilter atau mengelompokkan dengan menggunakan salah satu kolom tabel dimensi, dan meringkas kolom tabel fakta terkait.
Mari kita pertimbangkan solusi yang lebih baik.
Perhatikan perubahan desain berikut:
- Model sekarang memiliki empat tabel tambahan:
OrderLine
,OrderDate
,Product
, danFulfillmentDate
. - Empat tabel tambahan semuanya adalah tabel dimensi yang memiliki hubungan satu-ke-banyak dengan tabel fakta.
- Tabel
OrderLine
berisi kolomOrderLineID
, yang menyimpan nilaiOrderID
dikalikan dengan 100, ditambah nilai kolomOrderLine
—ID untuk setiap baris pesanan. - Tabel
Order
danFulfillment
sekarang masing-masing berisi kolomOrderLineID
, dan tidak lagi berisi kolomOrderID
danOrderLine
. - Tabel
Fulfillment
sekarang berisi kolomOrderDate
danProductID
. - Tabel
FulfillmentDate
hanya memiliki hubungan dengan tabelFulfillment
. - Semua kolom ID disembunyikan.
Meluangkan waktu untuk mengadopsi desain skema bintang memberikan manfaat berikut:
- Visual laporan Anda dapat memfilter atau mengelompokkan dengan kolom apa pun yang terlihat dari tabel dimensi.
- Visual laporan Anda dapat meringkas kolom apa pun yang terlihat dari tabel fakta.
- Filter yang diterapkan ke tabel
OrderLine
,OrderDate
, atauProduct
disebarluaskan ke kedua tabel fakta. - Semua hubungan bersifat satu-ke-banyak, dan setiap hubungan adalah hubungan reguler . Masalah integritas data tidak akan ditutupi. Untuk informasi selengkapnya tentang evaluasi hubungan, lihat hubungan Model di Power BI Desktop.
Menyajikan fakta berkualitas tinggi tentang biji-bijian
Skenario banyak-ke-banyak ini sangat berbeda dari dua lainnya yang sudah dijelaskan dalam artikel ini.
Mari kita pertimbangkan contoh yang melibatkan empat tabel: Date
, Sales
, Product
, dan Target
. Tabel Date
dan Product
adalah tabel dimensi, dan hubungan satu ke banyak terkait masing-masing dengan tabel fakta Sales
. Sejauh ini, itu mewakili desain skema bintang yang baik. Tabel Target
, namun, belum terkait dengan tabel lain.
diagram
Tabel Target
berisi tiga kolom: Category
, TargetQuantity
, dan TargetYear
. Baris tabel mengungkapkan granularitas kategori tahun dan 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 dimensi, hubungan satu ke banyak tidak dapat dibuat. Yah, itu benar hanya untuk salah satu hubungan. Mari kita jelajahi bagaimana tabel Target
dapat terkait dengan tabel dimensi.
Menghubungkan periode waktu butir yang lebih tinggi
Hubungan antara tabel Date
dan Target
harus merupakan hubungan satu ke banyak. Itu karena nilai kolom TargetYear
adalah tanggal. Dalam contoh ini, setiap kolom TargetYear
menyimpan tanggal pertama tahun target.
Tips
Saat menyimpan fakta pada granularitas waktu yang lebih tinggi dari hari, atur jenis data kolom ke Tanggal (atau Seluruh angka jika Anda menggunakan kunci tanggal). Di kolom, simpan nilai yang mewakili hari pertama periode waktu. Misalnya, periode tahun dicatat sebagai 1 Januari dalam setahun, dan periode bulan dicatat sebagai hari pertama bulan itu.
Namun, hati-hati harus dilakukan untuk memastikan bahwa filter pada tingkat bulan atau tanggal menghasilkan hasil yang berarti. Tanpa logika perhitungan khusus, visual laporan mungkin melaporkan bahwa tanggal target secara harfiah merupakan hari pertama setiap tahun. Semua hari lainnya—dan semua bulan kecuali Januari—akan meringkas kuantitas target sebagai BLANK.
Visual matriks berikut menunjukkan apa yang terjadi saat pengguna laporan mengeksplorasi secara rinci dari tahun ke bulan-bulan. Visual tersebut merangkum kolom TargetQuantity
. (Opsi Tampilkan item tanpa data telah diaktifkan untuk baris matriks.)
Untuk menghindari perilaku ini, kami sarankan Anda mengontrol ringkasan data fakta Anda dengan menggunakan langkah-langkah. 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 yang canggih—adalah membagikan nilai di seluruh periode waktu tingkat yang lebih rendah.
Pertimbangkan definisi pengukuran berikut yang menggunakan fungsi ISFILTERED DAX. Ini hanya mengembalikan nilai saat kolom Date
dan Month
tidak difilter.
Target Quantity =
IF(
NOT ISFILTERED('Date'[Date])
&& NOT ISFILTERED('Date'[Month]),
SUM(Target[TargetQuantity])
)
Visual matriks berikut menggunakan ukuran Target Quantity
. Ini 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 dimensi ke tabel fakta (dan berada pada butir yang lebih tinggi dari tabel dimensi).
Kolom Category
(dari tabel Product
dan Target
) berisi nilai duplikat. Jadi, tidak ada "sisi yang satu" dalam hubungan satu-ke-banyak. Dalam hal ini, Anda perlu membuat hubungan banyak ke banyak. Hubungan harus menyebarluaskan filter dalam satu arah, dari tabel dimensi ke tabel fakta.
Sekarang kita perhatikan baris tabel.
Dalam tabel Target
, ada empat baris: dua baris untuk setiap tahun target (2019 dan 2020), dan dua kategori (Pakaian dan Aksesori). Dalam tabel Product
, ada tiga produk. Dua termasuk dalam kategori pakaian, dan satu termasuk dalam kategori aksesori. Salah satu warna pakaian berwarna hijau, dan dua lainnya berwarna biru.
Pengelompokan visual tabel menurut kolom Category
dari tabel Product
menghasilkan hasil berikut. Namun, visual ini menghasilkan hasil yang benar. Sekarang mari kita pertimbangkan apa yang terjadi ketika kolom Color
dari tabel Product
digunakan untuk mengelompokkan kuantitas target.
Visual menghasilkan misrepresentasi data. Apa yang terjadi di sini?
Filter pada kolom Color
dari tabel Product
menghasilkan dua baris. Salah satu barisnya adalah untuk kategori Pakaian, dan yang lainnya adalah 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, kedua kategori tersebut digunakan untuk memfilter target.
Untuk menghindari perilaku ini, seperti yang dijelaskan sebelumnya, kami sarankan Anda mengontrol ringkasan data fakta Anda dengan menggunakan langkah-langkah.
Pertimbangkan definisi pengukuran berikut. Perhatikan bahwa semua kolom tabel Product
yang berada di bawah tingkat kategori diuji untuk filter.
Target Quantity =
IF(
NOT ISFILTERED('Product'[ProductID])
&& NOT ISFILTERED('Product'[Product])
&& NOT ISFILTERED('Product'[Color]),
SUM(Target[TargetQuantity])
)
Visual tabel berikut menggunakan ukuran Target Quantity
. Ini menunjukkan bahwa semua jumlah target warna adalah kosong.
Desain model akhir terlihat seperti berikut ini.
Menghubungkan panduan fakta biji-bijian yang lebih lengkap
Saat Anda perlu menghubungkan tabel dimensi ke tabel fakta, dan tabel fakta menyimpan baris pada butir yang lebih tinggi daripada baris tabel dimensi, ikuti panduan ini:
-
Untuk tanggal fakta biji-bijian yang lebih tinggi
- Dalam tabel fakta, simpan tanggal pertama periode waktu.
- Buat hubungan satu-ke-banyak antara tabel tanggal dan tabel fakta.
-
Untuk fakta biji-bijian yang lebih mendalam
- Buat hubungan banyak ke banyak antara tabel dimensi dan tabel fakta.
-
Untuk kedua jenis
- Kontrol ringkasan dengan logika pengukuran—kembalikan BLANK ketika kolom dimensi tingkat bawah digunakan untuk memfilter atau mengelompokkan.
- Sembunyikan kolom tabel fakta yang dapat diringkas—yang memastikan hanya pengukuran yang dapat digunakan untuk meringkas tabel fakta.
Konten terkait
Untuk informasi selengkapnya terkait artikel ini, lihat sumber daya berikut ini:
- Hubungan model di Power BI Desktop
- Memahami skema bintang dan pentingnya power BI
- panduan pemecahan masalah hubungan
- Pertanyaan? Coba tanyakan Komunitas Fabric
- Saran? Menyumbangkan ide untuk meningkatkan Fabric