Bagikan melalui


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 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.

Diagram memperlihatkan tiga tabel model. Desain dijelaskan dalam paragraf berikut.

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.

Diagram memperlihatkan bahwa diagram model terdiri dari empat tabel. Hubungan satu ke banyak telah ditambahkan untuk menghubungkan semua tabel.

Untuk membantu menjelaskan cara kerja penyebaran filter hubungan, diagram model telah dimodifikasi untuk mengungkapkan baris tabel.

Diagram memperlihatkan tabel model dan barisnya. Detail baris untuk empat tabel dijelaskan dalam paragraf berikut.

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 dengan CustomerID91
    • AccountID 1 dikaitkan dengan CustomerID92
    • AccountID 2 dikaitkan dengan CustomerID92
  • Tabel Transaction memiliki tiga baris:
    • Date 1 Januari 2019, AccountID1, Amount100
    • Date 2 Februari 2019, AccountID2, Amount200
    • Date 3 Maret 2019, AccountID1, 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 .

Diagram memperlihatkan dua visual tabel yang terletak berdampingan. Visual-visual tersebut dijelaskan dalam paragraf berikut.

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 menunjukkan bahwa model telah diperbarui. Sekarang melakukan pemfilteran di kedua arah.

Diagram memperlihatkan dua visual laporan yang sama berdampingan. Visual pertama belum berubah, sementara visual kedua telah berubah.

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 memperlihatkan model yang berisi dua tabel: Pesanan dan Pemenuhan.

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.)

Diagram memperlihatkan baris tabel model. Detail baris untuk dua tabel dijelaskan dalam paragraf berikut.

Detail baris untuk dua tabel dijelaskan dalam daftar berpoin berikut:

  • Tabel Order memiliki lima baris:
    • OrderDate 1 Januari 2019, OrderID1, OrderLine1, ProductIDProd-A, OrderQuantity5, Sales50
    • OrderDate 1 Januari 2019, OrderID1, OrderLine2, ProductIDProd-B, OrderQuantity10, Sales80
    • OrderDate 2 Februari 2019, OrderID2, OrderLine1, ProductIDProd-B, OrderQuantity5, Sales40
    • OrderDate 2 Februari 2019, OrderID2, OrderLine2, ProductIDProd-C, OrderQuantity1, Sales20
    • OrderDate 3 Maret 2019, OrderID3, OrderLine1, ProductIDProd-C, OrderQuantity5, Sales100
  • Tabel Fulfillment memiliki empat baris:
    • FulfillmentDate 1 Januari 2019, FulfillmentID50, OrderID1, OrderLine1, FulfillmentQuantity2
    • FulfillmentDate 2 Februari 2019, FulfillmentID51, OrderID2, OrderLine1, FulfillmentQuantity5
    • FulfillmentDate 2 Februari 2019, FulfillmentID52, OrderID1, OrderLine1, FulfillmentQuantity3
    • FulfillmentDate 1 Januari 2019, FulfillmentID53, OrderID1, OrderLine2, FulfillmentQuantity10

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 memperlihatkan tabel visual dengan tiga kolom: OrderID, OrderQuantity, dan FulfillmentQuantity.

Visual menyajikan hasil yang akurat. Namun, kegunaan model dibatasi karena Anda hanya dapat memfilter atau mengelompokkan menurut tabel OrderOrderID 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.

Diagram memperlihatkan model yang terdiri dari enam tabel: OrderLine, OrderDate, Order, Fulfillment, Product, dan FulfillmentDate.

Perhatikan perubahan desain berikut:

  • Model sekarang memiliki empat tabel tambahan: OrderLine, OrderDate, Product, dan FulfillmentDate.
  • Empat tabel tambahan semuanya adalah tabel dimensi yang memiliki hubungan satu-ke-banyak dengan tabel fakta.
  • Tabel OrderLine berisi kolom OrderLineID, yang menyimpan nilai OrderID dikalikan dengan 100, ditambah nilai kolom OrderLine—ID untuk setiap baris pesanan.
  • Tabel Order dan Fulfillment sekarang masing-masing berisi kolom OrderLineID, dan tidak lagi berisi kolom OrderID dan OrderLine.
  • Tabel Fulfillment sekarang berisi kolom OrderDate dan ProductID.
  • Tabel FulfillmentDate hanya memiliki hubungan dengan tabel Fulfillment.
  • 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, atau Product 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 memperlihatkan model yang terdiri dari empat tabel: Tanggal, Penjualan, Produk, dan Target.

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.

Diagram memperlihatkan tabel fakta Penjualan dan Target. Tabel Fakta Target memiliki tiga kolom: TahunTarget, Kategori, dan JumlahTarget.

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.)

Diagram memperlihatkan visual matriks yang mengungkapkan kuantitas target tahun 2020 sebagai 270. Ini menghasilkan nilai yang salah berdasarkan tanggal.

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.

Diagram memperlihatkan dua visual matriks. Pertama mengungkapkan target bulan pertama 2020 sebagai 270 sedangkan yang kedua kosong.

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.

Diagram memperlihatkan model tabel Target dan Produk. Relasi banyak-ke-banyak menghubungkan kedua tabel.

Sekarang kita perhatikan baris tabel.

Diagram memperlihatkan model yang berisi dua tabel: Target dan Produk. Hubungan banyak ke banyak berkaitan dengan dua kolom Kategori.

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.

Diagram memperlihatkan dua visual tabel. Grup pertama menurut Kategori dan grup kedua menurut Warna. Visual kedua menghasilkan hasil yang salah.

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.

Diagram memperlihatkan dua visual tabel. Grup pertama menurut Kategori dan grup kedua menurut Warna. Visual kedua menghasilkan hasil kosong yang benar.

Desain model akhir terlihat seperti berikut ini.

Diagram yang memperlihatkan model dengan tabel Tanggal dan Target yang terkait dengan hubungan satu-ke-banyak.

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.

Untuk informasi selengkapnya terkait artikel ini, lihat sumber daya berikut ini: