Many-to-Many Relationship di Power BI: Panduan Lengkap dari Konsep, Bridge Table hingga Best Practice

Many-to-Many Relationship di Power BI: Panduan Lengkap dari Konsep, Bridge Table hingga Best Practice

Relationship merupakan jantung dari semantic model Power BI. Ketika relationship dirancang dengan benar, filter dapat mengalir secara logis dari dimension menuju fact table, DAX menjadi lebih sederhana, visual memberikan hasil yang dapat diprediksi, dan model lebih mudah digunakan oleh report developer maupun pengguna bisnis.

Namun tidak semua hubungan bisnis dapat direpresentasikan dengan pola sederhana one-to-many (1:*).

Dalam banyak kasus nyata, satu entitas dapat berhubungan dengan banyak entitas lain, sementara entitas kedua tersebut juga dapat berhubungan kembali dengan banyak entitas pertama.

Contohnya:

Seorang customer dapat memiliki beberapa rekening bank.

Satu rekening bank juga dapat dimiliki oleh beberapa customer.

Seorang mahasiswa dapat mengikuti beberapa mata kuliah.

Satu mata kuliah dapat diikuti oleh banyak mahasiswa.

Seorang sales representative dapat menangani beberapa wilayah.

Satu wilayah dapat ditangani oleh lebih dari satu sales representative.

Seorang dokter dapat menangani banyak pasien.

Seorang pasien dapat ditangani oleh beberapa dokter.

Inilah contoh hubungan bisnis yang disebut many-to-many.

Di Power BI, many-to-many merupakan salah satu topik data modeling yang paling penting sekaligus paling sering disalahpahami.

Kesalahan paling umum adalah menganggap bahwa setiap hubungan bisnis many-to-many harus langsung dibuat sebagai relationship:

* ↔ *

Padahal tidak selalu demikian.

Microsoft justru merekomendasikan penggunaan bridging table ketika menghubungkan dua dimension table dalam hubungan many-to-many. Dalam pola tersebut, relationship fisik pada semantic model justru berupa relationship one-to-many, bukan direct many-to-many.

Karena itu, memahami many-to-many bukan hanya memahami tombol Cardinality = Many-to-many.

Kita perlu memahami:

business relationship;

grain;

bridge table;

factless fact table;

filter propagation;

bidirectional filtering;

limited relationship;

fact-to-fact relationship;

higher-grain fact;

non-additive values;

dan bagaimana star schema seharusnya dirancang.


Apa Itu Many-to-Many Relationship?

Secara konseptual, many-to-many relationship adalah hubungan ketika satu record atau entitas pada sisi pertama dapat berhubungan dengan banyak record di sisi kedua, dan satu record pada sisi kedua juga dapat berhubungan dengan banyak record di sisi pertama.

Notasinya:

* : *

atau:

Many ↔ Many

Namun kita perlu membedakan dua istilah:

Many-to-many business relationship

dan:

Many-to-many cardinality pada Power BI.

Kedua konsep tersebut berkaitan, tetapi tidak selalu sama.

Hubungan bisnis many-to-many sering kali justru lebih baik dimodelkan menggunakan bridge table dengan beberapa relationship 1:*.


Contoh Sederhana Many-to-Many

Bayangkan sebuah bank memiliki dua customer:

CustomerID Customer
91 Customer-91
92 Customer-92

Kemudian terdapat dua rekening:

AccountID Account
1 Account-01
2 Account-02

Hubungan bisnisnya:

Customer-91 memiliki Account-01.

Customer-92 memiliki Account-01 dan Account-02.

Account-01 dimiliki oleh Customer-91 dan Customer-92.

Account-02 dimiliki oleh Customer-92.

Berarti:

Customer dapat memiliki banyak Account.

Account dapat dimiliki banyak Customer.

Secara bisnis:

Customer * ↔ * Account

Microsoft menggunakan skenario customer dan bank account ini sebagai contoh klasik relationship many-to-many antar dimension.


Mengapa Kita Tidak Langsung Menghubungkan Customer dan Account?

Misalkan Customer mempunyai CustomerID unik.

Account juga memiliki AccountID unik.

Tidak terdapat satu kolom yang secara langsung dapat menyatakan seluruh kombinasi ownership.

Kita membutuhkan tabel yang menjawab pertanyaan:

Customer mana mempunyai Account mana?

Karena itu kita membuat tabel ketiga.

Misalnya:

AccountCustomer

CustomerID AccountID
91 1
92 1
92 2

Tabel tersebut menyimpan satu baris untuk setiap hubungan Customer–Account.

Inilah yang disebut:

Bridge Table

atau:

Bridging Table.


Apa Itu Bridge Table?

Bridge table merupakan tabel perantara yang menyimpan association atau hubungan antara dua entitas yang mempunyai hubungan many-to-many.

Strukturnya biasanya sangat sederhana.

Dalam contoh sebelumnya:

CustomerID AccountID
91 1
92 1
92 2

Bridge table tidak harus mempunyai measure.

Fungsi utamanya adalah menyatakan association.

Microsoft menjelaskan bahwa ketika bridge table hanya berisi identifier atau dimension keys dan tidak mempunyai measure, tabel tersebut disebut factless fact table.


Apa Itu Factless Fact Table?

Fact table biasanya kita bayangkan berisi angka seperti:

Sales Amount;

Quantity;

Cost;

Profit;

Discount;

atau Inventory.

Namun sebuah fact table tidak selalu harus mempunyai numeric measure.

Factless fact table hanya merekam bahwa suatu kejadian atau association terjadi.

Contohnya:

Customer 91 terkait dengan Account 1.

Customer 92 terkait dengan Account 1.

Customer 92 terkait dengan Account 2.

Informasi pentingnya bukan nilai numerik, tetapi keberadaan relationship tersebut.

Karena itu AccountCustomer dapat dipandang sebagai factless fact table.


Model Many-to-Many yang Direkomendasikan

Daripada:

Customer * ↔ * Account

secara langsung, buat:

Customer 1 → * AccountCustomer

dan:

Account 1 → * AccountCustomer

Secara business relationship tetap many-to-many.

Tetapi pada semantic model, masing-masing dimension mempunyai unique key pada sisi “1”, sedangkan bridge menyimpan duplicate keys pada sisi “*”.

Microsoft merekomendasikan pola ini ketika menghubungkan dua dimension yang memiliki relationship many-to-many.


Perbedaan Business Many-to-Many dan Cardinality *:*

Ini adalah konsep yang sangat penting.

Misalkan relationship bisnis:

Customer ↔ Account

adalah many-to-many.

Tetapi physical relationship dalam model dapat menjadi:

Customer:

1 → *

AccountCustomer

dan:

Account:

1 → *

AccountCustomer.

Artinya:

Hubungan bisnis many-to-many tidak selalu membutuhkan cardinality *:* secara langsung.

Ini merupakan salah satu prinsip terpenting dalam Power BI data modeling.


Mengapa Microsoft Tidak Merekomendasikan Direct Many-to-Many antar Dimension?

Microsoft tidak merekomendasikan menghubungkan dua dimension table secara langsung menggunakan many-to-many cardinality.

Alasannya adalah dimension table secara desain seharusnya memiliki identifier unik yang dapat menjadi sisi “one” relationship.

Menggunakan bridge table mempertahankan prinsip tersebut dan menghasilkan model yang lebih eksplisit serta lebih mudah dipahami.

Contoh:

DimCustomer mempunyai CustomerID unik.

DimAccount mempunyai AccountID unik.

BridgeAccountCustomer menyimpan hubungan keduanya.

Ini lebih baik dibanding mencoba membuat column relationship langsung dengan duplicate values pada kedua dimension.


Bagaimana Filter Mengalir pada Bridge Table?

Ini bagian yang sangat penting.

Misalnya model mempunyai:

Customer → AccountCustomer ← Account → Transaction

Transaction menyimpan transaksi rekening.

Kita ingin memilih Customer pada slicer dan melihat transaksi dari account yang dimilikinya.

Filter harus bergerak:

Customer

AccountCustomer

Account

Transaction

Masalahnya, relationship default antara Account dan AccountCustomer biasanya memfilter dari Account menuju bridge.

Untuk memungkinkan filter bergerak dari bridge kembali menuju Account, salah satu relationship perlu mempunyai arah filter Both.

Dalam contoh Microsoft, relationship antara Account dan AccountCustomer diatur menjadi bidirectional sehingga filter dari Customer dapat terus diteruskan hingga Transaction.


Apakah Berarti Semua Relationship Harus Both?

Tidak.

Ini merupakan kesalahan yang berbahaya.

Jangan mengubah seluruh relationship menjadi Both hanya karena sebuah visual tidak bekerja.

Microsoft secara umum menyarankan penggunaan bidirectional filtering secara selektif karena filter dua arah dapat menambah kompleksitas dan membuka kemungkinan munculnya multiple filter paths atau ambiguity.

Untuk model bridge table, biasanya hanya relationship yang memang diperlukan untuk meneruskan filter lintas bridge yang dibuat bidirectional.

Prinsipnya:

Gunakan Both karena kebutuhan filter propagation yang jelas, bukan sebagai solusi universal.


Contoh Filter Propagation Customer ke Transaction

Bayangkan struktur berikut:

Customer

CustomerID 91

CustomerID 92

Bridge AccountCustomer

91 → Account 1

92 → Account 1

92 → Account 2

Transaction

AccountID Amount
1 100
2 200
1 -25

Balance Account 1:

100 – 25 = 75

Balance Account 2:

200

Customer 91 hanya mempunyai Account 1.

Maka:

Customer 91 Balance = 75

Customer 92 mempunyai Account 1 dan Account 2.

Maka:

Customer 92 Balance = 75 + 200 = 275


Mengapa Grand Total Bukan 350?

Ini salah satu konsep paling menarik dalam many-to-many.

Customer 91 = 75.

Customer 92 = 275.

Jika dijumlahkan:

75 + 275 = 350.

Tetapi total seluruh account sebenarnya hanya:

75 + 200 = 275.

Mengapa Power BI menampilkan grand total 275, bukan 350?

Karena Account 1 dimiliki oleh Customer 91 dan Customer 92.

Saldo Account 1 tidak boleh dihitung dua kali ketika menghitung total seluruh account.

Microsoft menjelaskan bahwa customer balances dalam skenario ini bersifat non-additive. Nilai per customer tidak dapat begitu saja dijumlahkan untuk mendapatkan grand total karena shared account dapat muncul dalam lebih dari satu customer context.


Apa Itu Non-Additive Measure?

Additive measure merupakan angka yang dapat dijumlahkan secara aman di seluruh dimension.

Contohnya jumlah unit barang terjual sering kali additive.

Tetapi beberapa ukuran tidak dapat dijumlahkan begitu saja.

Dalam contoh joint account:

Customer 91 mencakup Account 1.

Customer 92 juga mencakup Account 1.

Jika saldo customer dijumlahkan, Account 1 dihitung dua kali.

Karena itu total harus dihitung ulang berdasarkan filter context keseluruhan, bukan sekadar menjumlahkan displayed rows.

Konsep seperti ini penting saat menjelaskan kepada pengguna mengapa:

Grand Total Power BI tidak selalu sama dengan penjumlahan manual seluruh row yang terlihat.


Best Practice Bridge Table Menurut Microsoft

Untuk relationship many-to-many antar dimension, Microsoft memberikan beberapa panduan utama. Setiap entity sebaiknya memiliki dimension table dengan ID unik, bridge table digunakan untuk menyimpan association antar entity, lalu relationship 1:* dibangun menuju bridge. Salah satu relationship dapat dibuat bidirectional jika dibutuhkan agar filter dapat terus bergerak menuju fact table. Bridge table dan technical ID yang tidak diperlukan untuk reporting umumnya disembunyikan dari report author.

Tujuan akhirnya bukan sekadar membuat relationship bekerja, melainkan membuat semantic model tetap intuitif.


Mengapa Bridge Table Sebaiknya Disembunyikan?

Bridge table biasanya merupakan implementation detail.

Report author seharusnya bekerja dengan:

Customer;

Account;

Transaction;

bukan:

CustomerID dari Bridge;

AccountID dari Bridge;

atau technical surrogate keys.

Jika bridge hanya digunakan untuk relationship, menyembunyikannya membuat Data pane jauh lebih bersih.

Microsoft juga merekomendasikan menyembunyikan bridge table jika tabel tersebut tidak mempunyai field atau measure yang memang dibutuhkan untuk reporting.


Sembunyikan Key di Sisi Many

Misalnya:

Customer[CustomerID]

terhubung dengan:

Bridge[CustomerID].

Jika CustomerID memang diperlukan pada report, lebih baik expose key dari sisi dimension atau sisi “one”.

Technical key pada sisi many biasanya sebaiknya disembunyikan.

Microsoft menyebut bahwa filter yang diterapkan pada sisi “one” mempunyai karakteristik filter yang lebih baik dibanding menggunakan key dari sisi many.


Skenario Many-to-Many Kedua: Fact-to-Fact

Selain hubungan antar dimension, many-to-many juga dapat muncul ketika dua fact table ingin dihubungkan.

Microsoft memberikan contoh:

Order

dan:

Fulfillment.

Order menyimpan order line.

Fulfillment menyimpan shipment atau pemenuhan order.

Satu order dapat mempunyai beberapa order line.

Satu order line juga dapat dikirim melalui beberapa fulfillment.

Karena itu OrderID dapat duplicate pada kedua tabel.


Contoh Fact Order

OrderID OrderLine ProductID OrderQty
1001 1 P001 10
1001 2 P002 5
1002 1 P003 8

OrderID 1001 duplicate karena mempunyai dua order line.


Contoh Fact Fulfillment

FulfillmentID OrderID OrderLine ShipQty
F001 1001 1 4
F002 1001 1 6
F003 1001 2 5

OrderID 1001 juga duplicate.

Jika kita menghubungkan:

Order[OrderID]

dengan:

Fulfillment[OrderID]

kedua sisi mempunyai duplicate.

Cardinality-nya:

* : *


Apakah Direct Fact-to-Fact Many-to-Many Direkomendasikan?

Secara teknis bisa.

Microsoft bahkan menyebut direct relationship antara dua fact table dapat berguna untuk eksplorasi data yang cepat dan sederhana.

Namun Microsoft secara umum tidak merekomendasikan desain ini sebagai model akhir.

Mengapa?

Karena kemampuan reporting menjadi terbatas.

Filter dan grouping cenderung bergantung pada field yang terdapat dalam salah satu fact table.

Selain itu, relationship many-to-many dievaluasi sebagai limited relationship sehingga masalah data integrity dapat menghasilkan row yang tidak muncul dalam query result.


Solusi Lebih Baik untuk Fact-to-Fact: Star Schema

Daripada:

FactOrder * ↔ * FactFulfillment

Microsoft merekomendasikan menambahkan dimension bersama.

Contohnya:

DimOrderLine

DimOrderDate

DimProduct

DimFulfillmentDate

Kemudian:

DimOrderLine 1 → * FactOrder

DimOrderLine 1 → * FactFulfillment

DimProduct 1 → * FactOrder

DimProduct 1 → * FactFulfillment

dan seterusnya.

Dengan demikian kedua fact table tidak perlu dihubungkan langsung.


Mengapa Shared Dimension Lebih Baik?

Misalnya DimProduct memfilter:

FactOrder

dan:

FactFulfillment.

Pengguna dapat memilih Product dan kemudian melihat:

Order Quantity;

Fulfilled Quantity;

Outstanding Quantity;

Fulfillment Rate;

dalam satu filter context yang konsisten.

Microsoft menjelaskan bahwa desain star schema seperti ini membuat report dapat melakukan filter atau grouping menggunakan dimension dan melakukan summarization pada fact table yang terkait, sekaligus mempertahankan regular one-to-many relationships.


Gunakan OrderLineID untuk Menyamakan Grain

Salah satu improvement yang dijelaskan Microsoft adalah membangun key pada grain order line.

Misalnya:

OrderID = 1001

OrderLine = 2

Dibuat identifier:

OrderLineID

Yang penting bukan format persisnya, tetapi bahwa OrderLineID mengidentifikasi satu order line secara unik.

Dimension OrderLine kemudian dapat menjadi common dimension bagi FactOrder dan FactFulfillment.


Grain Sekali Lagi Menjadi Kunci

Dalam artikel One-to-One sebelumnya kita membahas grain.

Pada many-to-many, grain bahkan lebih penting.

Tanyakan:

Satu row dalam tabel ini mewakili apa?

FactOrder mungkin:

one row per order line.

FactFulfillment mungkin:

one row per shipment per order line.

Karena grain berbeda, OrderID saja tidak cukup untuk menyatakan association secara presisi.

Memahami grain membantu menemukan dimension atau key yang tepat.


Many-to-Many Cardinality adalah Limited Relationship

Ini salah satu konsep advanced yang wajib dipahami.

Microsoft mengklasifikasikan relationship berdasarkan evaluasinya menjadi:

Regular relationship

dan:

Limited relationship.

Relationship yang menggunakan many-to-many cardinality merupakan limited relationship karena tidak ada guaranteed “one” side.


Apa Konsekuensi Limited Relationship?

Pada limited relationship, Power BI tidak melakukan table expansion dengan cara yang sama seperti regular relationship.

Untuk Import model, join limited relationship diselesaikan ketika query dijalankan.

Microsoft menjelaskan bahwa limited relationship menggunakan semantik yang setara dengan INNER JOIN, sehingga blank virtual row tidak ditambahkan untuk mengompensasi pelanggaran referential integrity.

Implikasinya:

unmatched records dapat tidak muncul seperti yang mungkin Anda harapkan dari regular relationship.

Inilah salah satu alasan mengapa data integrity penting dalam direct many-to-many relationship.


RELATED dan Limited Relationship

Limited relationship juga mempunyai beberapa pembatasan DAX.

Microsoft menjelaskan bahwa fungsi RELATED tidak dapat digunakan melalui limited relationship untuk mengambil nilai dari sisi yang dianggap “one”.

Ini semakin menegaskan bahwa relationship *:* tidak boleh diperlakukan seolah-olah sama dengan relationship 1:* biasa.


Skenario Many-to-Many Ketiga: Higher-Grain Fact

Skenario ketiga sering terjadi dalam dunia bisnis.

Misalnya kita mempunyai:

DimProduct pada level Product.

FactSales pada level transaction/product.

Tetapi FactTarget hanya tersedia pada level Product Category.

Contoh:

Year Category TargetQuantity
2026 Hair Care 500000
2026 Personal Care 400000

Sementara DimProduct:

ProductID Product Category
P001 Shampoo A Hair Care
P002 Shampoo B Hair Care
P003 Soap A Personal Care

Target berada pada:

Category grain.

Product berada pada:

Product grain.

FactTarget berarti mempunyai grain yang lebih tinggi atau lebih aggregated dibandingkan DimProduct.

Microsoft mengidentifikasi skenario ini sebagai salah satu penggunaan many-to-many relationship yang valid.


Mengapa Tidak Bisa Menggunakan 1:*?

DimProduct[Category] berisi:

Hair Care

Hair Care

Personal Care

Category duplicate karena ada banyak produk dalam satu category.

FactTarget[Category] juga berulang dari tahun ke tahun.

Misalnya:

Hair Care 2025

Hair Care 2026

Personal Care 2025

Personal Care 2026

Kedua sisi mempunyai duplicate.

Maka relationship berdasarkan Category menjadi:

* → *

Microsoft menyarankan filter berjalan satu arah dari dimension menuju higher-grain fact dalam skenario ini.


Bahaya Higher-Grain Fact

Masalah muncul ketika pengguna mencoba menganalisis Target pada grain yang lebih rendah daripada grain target sebenarnya.

Misalnya Target ditetapkan berdasarkan Category.

Tetapi report mencoba menampilkan:

Target per Product;

Target per Color;

Target per SKU.

Pertanyaan penting:

Bagaimana target category harus dialokasikan kepada masing-masing product?

Jika business tidak memberikan allocation rule, Power BI tidak bisa secara ajaib menentukan jawabannya.


Contoh Misrepresentation

Misalnya Hair Care target = 100.

Hair Care mempunyai:

Shampoo A

Shampoo B.

Jika report menampilkan Product:

Shampoo A = 100

Shampoo B = 100

pengguna bisa salah menganggap total Hair Care = 200.

Padahal sebenarnya target category hanya 100.

Ini bukan sekadar masalah DAX.

Ini adalah masalah grain mismatch.


Measure Harus Mengontrol Summarization

Microsoft menyarankan agar higher-grain fact tidak dibiarkan diringkas secara sembarangan melalui implicit aggregation.

Gunakan explicit measure untuk memastikan nilai hanya muncul pada level yang mempunyai makna bisnis.

Contoh pendekatan:

Target Quantity Safe =
VAR IsBelowCategory =
    ISINSCOPE(DimProduct[Product])
        || ISINSCOPE(DimProduct[ProductID])
        || ISINSCOPE(DimProduct[Color])
RETURN
    IF(
        IsBelowCategory,
        BLANK(),
        SUM(FactTarget[TargetQuantity])
    )

Dengan pendekatan tersebut:

Target pada Category → tampil.

Target pada level Product → BLANK.

Target pada level Color → BLANK.

Ini lebih baik daripada menampilkan angka yang sebenarnya tidak memiliki makna bisnis.


Mengapa BLANK Justru Bisa Menjadi Jawaban yang Benar?

Dalam dashboard, pengguna sering menganggap BLANK berarti error.

Tidak selalu.

Jika target hanya ditetapkan pada level Category, maka pertanyaan:

Berapa target Product A?

mungkin memang tidak mempunyai jawaban.

Menampilkan BLANK lebih jujur daripada menampilkan target Category seolah-olah itu target Product.

Microsoft secara eksplisit merekomendasikan mengembalikan BLANK ketika lower-level dimension digunakan untuk memfilter atau grouping higher-grain facts.


Higher-Grain Fact dan Date

Kasus time dimension sedikit berbeda.

Misalnya target tersedia per tahun.

DimDate tersedia per hari.

Microsoft menyarankan higher-grain fact date menyimpan tanggal pertama dari periodenya.

Contoh:

Target 2026 → 1 Januari 2026.

Target September 2026 → 1 September 2026.

Kemudian Date dimension tetap dapat mempunyai relationship 1:* menuju FactTarget.


Masalah Drill Down Year ke Month

Namun relationship saja tidak cukup.

Misalnya annual target 1.200 unit disimpan pada:

1 Januari 2026.

Ketika pengguna drill down dari Year ke Month, target mungkin hanya muncul pada Januari sedangkan Februari sampai Desember BLANK.

Secara relationship itu benar.

Secara business reporting, mungkin membingungkan.

Microsoft menyarankan controlling summarization dengan measure atau menggunakan DAX allocation logic apabila memang ada aturan bisnis untuk mendistribusikan annual target ke month.


Jangan Membuat Allocation Rule Tanpa Dasar Bisnis

Misalnya annual target:

12.000 unit.

Membaginya otomatis menjadi:

1.000 per bulan

belum tentu benar.

Mungkin bisnis mempunyai seasonality:

Januari = 8%

Februari = 7%

Ramadan = 15%

dan seterusnya.

Allocation rule harus berasal dari business logic, bukan hanya kebutuhan visualisasi.


Three Many-to-Many Scenarios Menurut Microsoft

Dengan demikian Microsoft membedakan tiga situasi penting. Pertama, relationship many-to-many antar dimension, yang sebaiknya dimodelkan menggunakan bridge table. Kedua, hubungan antar fact table, yang secara teknis dapat dibuat langsung tetapi biasanya lebih baik dirombak menjadi star schema dengan shared dimensions. Ketiga, higher-grain fact, ketika fact table menyimpan data pada grain yang lebih tinggi daripada dimension yang menghubungkannya.


Many-to-Many dan Star Schema

Star schema tetap menjadi fondasi penting.

Dalam star schema:

Dimension digunakan untuk filtering dan grouping.

Fact digunakan untuk summarization.

Sisi “1” pada 1:* umumnya merupakan dimension.

Sisi “*” umumnya merupakan fact.

Microsoft menjelaskan bahwa relationship dan cardinality membantu menentukan peran dimension dan fact dalam semantic model.


Bridge Table Tidak Merusak Star Schema

Beberapa pengguna merasa bridge table membuat star schema menjadi “tidak murni”.

Itu tidak menjadi masalah.

Real-world business model memang kadang membutuhkan factless fact atau bridge.

Yang penting:

grain jelas;

relationship jelas;

filter path jelas;

dan report author memahami model.

Microsoft bahkan menyebut bridge/factless fact sebagai best-practice approach untuk many-to-many antar dimension.


Contoh Many-to-Many pada Sales Organization

Misalnya satu salesman dapat menangani banyak territory.

Satu territory juga dapat ditangani beberapa salesman.

DimSalesperson:

SalespersonID Salesperson
S01 Andi
S02 Budi

DimTerritory:

TerritoryID Territory
T01 Jakarta Selatan
T02 Jakarta Barat

BridgeSalespersonTerritory:

SalespersonID TerritoryID
S01 T01
S01 T02
S02 T02

Secara bisnis:

Salesperson * ↔ * Territory.

Secara semantic model:

DimSalesperson 1 → * Bridge

DimTerritory 1 → * Bridge.


Contoh Many-to-Many pada Pendidikan

Student dapat mengikuti banyak Course.

Course mempunyai banyak Student.

Buat:

DimStudent

DimCourse

BridgeEnrollment.

BridgeEnrollment dapat mempunyai:

StudentID

CourseID

EnrollmentDate

Status.

Jika bridge mempunyai additional business attributes seperti EnrollmentDate, tabel tersebut bahkan menjadi lebih dari sekadar technical bridge.


Contoh Many-to-Many pada Healthcare

Patient dapat memiliki banyak Doctor.

Doctor menangani banyak Patient.

Buat:

DimPatient

DimDoctor

BridgeDoctorPatient.

Jika hubungan mempunyai periode berlaku, bridge dapat juga mempunyai:

StartDate;

EndDate;

Role;

PrimaryDoctorFlag.

Ini menunjukkan bahwa many-to-many modeling tidak hanya persoalan cardinality, tetapi juga representasi business relationship.


Contoh Many-to-Many pada Produk dan Promosi

Satu product dapat masuk beberapa promotion.

Satu promotion dapat berlaku untuk banyak product.

Model:

DimProduct

DimPromotion

BridgeProductPromotion.

Dengan relationship yang dirancang dengan benar, report dapat menjawab:

produk apa yang mengikuti Promotion A;

berapa sales dari product yang termasuk Promotion A;

promotion apa saja yang pernah berlaku pada Product X.


Jangan Gunakan Direct *:* Hanya Karena Power BI Mengizinkannya

Ini serupa dengan pelajaran pada one-to-one relationship.

Power BI menyediakan cardinality:

Many-to-many (*:*)

tetapi keberadaan fitur bukan berarti fitur tersebut harus menjadi pilihan default.

Microsoft menyebut many-to-many cardinality relatif jarang digunakan dan biasanya ditujukan untuk kebutuhan model yang lebih kompleks, termasuk higher-grain fact atau many-to-many fact scenarios.


Kesalahan Umum 1: Langsung Memilih Many-to-Many Saat Duplicate Muncul

Misalnya Anda mencoba membuat:

DimProduct[ProductID]

→ FactSales[ProductID]

tetapi Power BI mengatakan ProductID pada DimProduct duplicate.

Jangan langsung mengubah cardinality menjadi *:*.

Tanyakan:

Mengapa ProductID duplicate di DimProduct?

Mungkin DimProduct sebenarnya mengandung:

historical versions;

multiple warehouses;

multiple price periods;

duplicate source data;

atau grain yang salah.

Many-to-many tidak boleh menjadi plester untuk data quality issue.


Kesalahan Umum 2: Menghilangkan Duplicate Secara Sembarangan

Kebalikan dari kesalahan pertama juga berbahaya.

Developer menggunakan Remove Duplicates hanya agar relationship menjadi 1:*.

Jika duplicate merepresentasikan association yang valid, Anda telah menghapus informasi bisnis.

Contohnya pada bridge:

S01 → T01

S01 → T02.

Salesperson S01 memang harus muncul dua kali karena ia menangani dua territory.


Kesalahan Umum 3: Mengaktifkan Both di Semua Relationship

Ini sering dilakukan karena:

Kalau Both, filter pasti jalan.

Namun semakin banyak bidirectional relationship, semakin besar kemungkinan model mempunyai beberapa jalur filter menuju tabel yang sama.

Power BI mempunyai mekanisme untuk menyelesaikan relationship path ambiguity, tetapi desain yang jelas jauh lebih baik daripada bergantung pada resolusi ambiguity engine. Microsoft mendokumentasikan bahwa bidirectional relationships dapat memperkenalkan multiple filter propagation paths.


Kesalahan Umum 4: Mengabaikan Grand Total

Pada many-to-many, grand total dapat berbeda dari penjumlahan displayed rows karena association overlap.

Jangan langsung menganggap Power BI salah.

Pahami terlebih dahulu:

grain;

filter context;

shared entities;

dan apakah measure bersifat additive atau non-additive.


Kesalahan Umum 5: Menghubungkan Fact Table Secara Langsung

FactSales * ↔ * FactTarget

atau:

FactOrder * ↔ * FactShipment

mungkin bekerja untuk exploratory report.

Tetapi untuk enterprise semantic model, shared dimensions biasanya menghasilkan architecture yang lebih kuat dan fleksibel.

Microsoft secara eksplisit merekomendasikan star schema daripada direct many-to-many fact-to-fact relationships pada skenario Order/Fulfillment.


Kesalahan Umum 6: Mengabaikan Higher-Grain Facts

Target Category tidak sama dengan Target Product.

Budget Region tidak sama dengan Budget Store.

Annual Target tidak sama dengan Monthly Target.

National Forecast tidak sama dengan Outlet Forecast.

Jangan membiarkan report melakukan drill-down ke level yang lebih rendah seolah-olah angka tersebut memang tersedia pada grain tersebut.


Contoh Kasus FMCG: Target Category vs Sales SKU

Misalnya tim Sales mempunyai actual data pada level:

Date × Outlet × SKU.

Namun annual target diberikan oleh management pada level:

Year × Category.

FactSales grain:

one row per transaction/outlet/SKU.

FactTarget grain:

one row per year/category.

Memaksa target ke level SKU tanpa allocation rule akan menghasilkan interpretasi yang salah.

Solusi:

hubungkan target pada grain yang relevan;

gunakan explicit measure;

return BLANK ketika report berada di bawah grain target;

atau implementasikan allocation jika organisasi mempunyai allocation methodology.


Contoh Kasus Budget vs Actual

Actual expense mungkin tersedia per:

Date;

Department;

Account;

Cost Center.

Sementara Budget hanya tersedia per:

Month;

Department.

Jika pengguna melihat Budget berdasarkan individual Cost Center, nilainya mungkin tidak mempunyai business meaning.

Masalah ini sangat mirip dengan higher-grain target.


Many-to-Many dan DAX

Many-to-many relationship bukan berarti seluruh masalah harus diselesaikan dengan DAX.

Prinsip yang tetap berlaku adalah:

Perbaiki model terlebih dahulu, baru tulis DAX.

DAX seharusnya mengimplementasikan business calculation.

DAX tidak seharusnya menjadi alat untuk menyembunyikan relationship architecture yang tidak jelas.


TREATAS sebagai Virtual Relationship

Dalam skenario advanced, DAX menyediakan fungsi seperti TREATAS untuk menerapkan hasil table expression sebagai filter pada kolom dari tabel lain.

Microsoft menyebut TREATAS berguna pada skenario advanced ketika developer ingin menciptakan virtual relationship selama evaluation suatu calculation.

Namun TREATAS bukan pengganti otomatis bridge table atau star schema.

Gunakan ketika ada alasan calculation-specific yang jelas.


Physical Relationship vs Virtual Relationship

Physical relationship dibuat di Model View.

Keuntungannya:

berlaku untuk keseluruhan semantic model;

lebih mudah dilihat;

lebih mudah dipahami report author;

dan filter propagation menjadi bagian eksplisit dari architecture.

Virtual relationship seperti TREATAS hanya berlaku pada calculation tertentu.

Karena itu untuk association bisnis yang fundamental, physical model biasanya tetap lebih mudah dikelola.


Checklist Sebelum Membuat Direct *:* Relationship

Sebelum memilih Many-to-many pada Cardinality, tanyakan beberapa hal berikut.

Pertanyaan Implikasi
Apakah kedua tabel dimension? Pertimbangkan bridge table
Apakah kedua tabel fact? Pertimbangkan shared dimensions/star schema
Apakah salah satu fact mempunyai grain lebih tinggi? *:* mungkin memang diperlukan
Mengapa kedua key duplicate? Validasi grain dan data quality
Apakah duplicate merupakan data valid? Jangan hapus sembarangan
Apakah filter direction jelas? Hindari accidental bidirectional filtering
Apakah model mempunyai multiple filter paths? Periksa ambiguity
Apakah totals additive? Validasi interpretasi
Apakah fact grain konsisten? Pastikan summarization benar
Apakah report drill-down di bawah fact grain? Gunakan measure untuk membatasi hasil

Decision Framework Many-to-Many

Situasi pertama:

Dua dimension mempunyai many-to-many business relationship.

Contoh:

Customer ↔ Account.

Gunakan:

Bridge Table.


Situasi kedua:

Dua fact table mempunyai duplicate common key.

Contoh:

Order ↔ Fulfillment.

Pertimbangkan:

Shared dimensions + star schema.


Situasi ketiga:

Fact mempunyai grain lebih tinggi daripada dimension.

Contoh:

Target Category ↔ Product Dimension.

Direct many-to-many dapat menjadi desain yang valid, tetapi summarization harus dikontrol dengan measure.


Red Flags dalam Many-to-Many Model

Model Anda layak diperiksa kembali jika:

hampir seluruh relationship menggunakan *:*;

Both digunakan di hampir semua relationship;

developer tidak dapat menjelaskan grain;

bridge table tidak jelas;

fact table langsung saling berhubungan dalam jumlah besar;

grand total sulit dijelaskan;

duplicate sengaja dihapus agar model bekerja;

target pada category muncul seolah-olah target SKU;

banyak ambiguous paths;

atau relationship dibuat berdasarkan nama kolom tanpa memahami proses bisnis.


Best Practice: Nama Bridge Table Harus Jelas

Gunakan nama seperti:

BridgeCustomerAccount

BridgeSalespersonTerritory

BridgeProductPromotion

BridgeStudentCourse

atau:

CustomerAccount

SalespersonTerritory.

Nama yang jelas membantu developer memahami bahwa tabel tersebut menyimpan association, bukan dimension biasa.


Best Practice: Dokumentasikan Grain

Contoh dokumentasi:

Table Grain
DimCustomer One row per customer
DimAccount One row per account
BridgeCustomerAccount One row per customer-account association
FactTransaction One row per account transaction

Dengan dokumentasi seperti ini, relationship menjadi jauh lebih mudah dipahami.


Best Practice: Sembunyikan Technical Columns

Surrogate key dan foreign key sering diperlukan oleh engine tetapi tidak berguna bagi report author.

Misalnya:

CustomerKey;

AccountKey;

BridgeCustomerKey;

BridgeAccountKey.

Jika tidak diperlukan untuk reporting, hide.

Expose:

Customer Name;

Account Name;

Category;

Segment;

dan business attributes lainnya.


Best Practice: Jelaskan Non-Additive Metrics kepada User

Jika report mempunyai joint ownership atau overlapping association, report user mungkin mempertanyakan grand total.

Microsoft menyarankan memberikan penjelasan kepada pengguna, misalnya melalui text box atau visual header tooltip, agar hasil many-to-many tidak disalahartikan.

Ini adalah contoh bahwa dashboard design bukan hanya persoalan calculation accuracy, tetapi juga communication.


Many-to-Many Tidak Selalu Buruk

Many-to-many sering mendapat reputasi buruk karena pengguna mendengar:

Hindari many-to-many.

Pernyataan tersebut terlalu sederhana.

Yang lebih tepat:

Hindari direct many-to-many yang tidak diperlukan.

Many-to-many merupakan konsep bisnis yang benar-benar ada.

Power BI menyediakan alat untuk memodelkannya.

Masalah muncul ketika cardinality *:* digunakan sebagai jalan pintas tanpa memahami grain dan filter propagation.


Kapan Direct *:* Relationship Justru Masuk Akal?

Salah satu contoh paling jelas adalah higher-grain fact.

Misalnya:

DimProduct berada pada Product grain.

FactTarget berada pada Category grain.

Category duplicate di DimProduct.

Category juga duplicate di FactTarget.

Dalam kondisi seperti ini direct *:* dapat menjadi desain yang memang diperlukan.

Namun Anda tetap harus mengontrol bagaimana target diringkas ketika report turun ke level Product.


Bridge Table vs Direct Many-to-Many

Aspek Bridge Table Direct *:*
Umum untuk dimension-to-dimension Ya Tidak direkomendasikan
Entity IDs tetap unik Ya Tidak selalu
Model association eksplisit Ya Lebih sedikit
Relationship evaluation Dapat menggunakan regular 1:* Limited
Cocok untuk higher-grain fact Tergantung desain Bisa sangat relevan
Best practice antar dimension Ya Tidak

Many-to-Many vs One-to-Many

Aspek One-to-Many Many-to-Many
Notasi 1:* *:*
Unique side Ada Tidak dijamin
Penggunaan Sangat umum Lebih khusus
Relationship evaluation Umumnya regular Limited
Star schema Pola utama Digunakan pada skenario tertentu
Kompleksitas Lebih mudah dipahami Membutuhkan perhatian lebih

Many-to-Many vs One-to-One

One-to-one:

1 ↔ 1

Key unik pada kedua sisi.

Many-to-many:

* ↔ *

Tidak ada guaranteed unique side.

Keduanya merupakan relationship khusus dibanding 1:*.

Namun masalah desainnya berbeda.

Pada 1:1 kita sering bertanya:

Haruskah dua tabel ini sebenarnya digabung?

Pada many-to-many kita sering bertanya:

Apakah saya membutuhkan bridge, shared dimension, atau memang direct *:*?


Troubleshooting: Hasil Many-to-Many Terlihat Salah

Jika hasil terlihat aneh, jangan langsung mengubah DAX.

Periksa secara berurutan:

grain kedua tabel;

relationship cardinality;

filter direction;

bridge table;

duplicate keys;

missing keys;

shared entities;

limited relationship;

dan additive behavior measure.


Troubleshooting: Semua Customer Menampilkan Total yang Sama

Ini dapat terjadi jika filter dari Customer berhenti di bridge dan tidak diteruskan menuju Account/Transaction.

Periksa relationship direction.

Dalam contoh Microsoft, relationship Account–AccountCustomer harus mengizinkan filter bergerak kembali menuju Account sehingga customer context dapat mencapai Transaction.


Troubleshooting: Grand Total Lebih Kecil dari Penjumlahan Row

Periksa apakah terdapat overlapping associations.

Contoh:

shared bank account;

product yang masuk beberapa promotion;

customer yang mempunyai beberapa membership;

territory yang dibagi dua salesperson.

Grand total dievaluasi dalam grand-total filter context, bukan selalu sebagai SUM dari row values yang terlihat.


Troubleshooting: Target Berulang di Setiap Product

Ini hampir selalu merupakan tanda mismatch grain.

Jika target berada pada Category, jangan menampilkan target mentah pada Product.

Gunakan measure yang memahami level scope.


Troubleshooting: Banyak Relationship Menjadi Ambiguous

Periksa bidirectional relationship.

Filter mungkin mempunyai lebih dari satu jalur untuk bergerak dari satu tabel ke tabel lain.

Kurangi Both jika tidak diperlukan dan sederhanakan topology model.


Prinsip Utama Many-to-Many

Many-to-many adalah masalah business modeling terlebih dahulu, baru masalah cardinality.

Mulai dari memahami business relationship.

Setelah itu tentukan:

grain;

dimension;

fact;

association;

bridge;

filter flow;

dan calculation behavior.

Baru kemudian tentukan cardinality Power BI.


FAQ: Many-to-Many Relationship Power BI

Apa itu Many-to-Many Relationship di Power BI?

Many-to-many merupakan hubungan ketika satu nilai atau entity dapat berhubungan dengan beberapa nilai pada entity lain dan sebaliknya. Dalam Power BI, direct *:* cardinality memungkinkan duplicate values pada kedua relationship columns.

Apakah relationship bisnis many-to-many harus menggunakan cardinality *:*?

Tidak. Untuk dua dimension, Microsoft justru merekomendasikan bridge table yang menghubungkan kedua dimension menggunakan relationship one-to-many.

Apa itu bridge table?

Bridge table adalah tabel penghubung yang menyimpan satu baris untuk setiap association antara dua entity. Contohnya CustomerID–AccountID.

Apa itu factless fact table?

Factless fact table adalah fact table yang tidak mempunyai measure numerik dan terutama menyimpan dimension keys atau event association. Bridge table yang hanya menyimpan keys merupakan salah satu contohnya.

Apakah bridge table harus ditampilkan kepada pengguna?

Biasanya tidak. Microsoft merekomendasikan menyembunyikan bridge jika field di dalamnya tidak dibutuhkan untuk reporting.

Apakah direct fact-to-fact many-to-many direkomendasikan?

Umumnya tidak. Microsoft merekomendasikan penggunaan star schema dengan dimension tables yang terhubung ke masing-masing fact menggunakan one-to-many relationships.

Apa itu higher-grain fact?

Higher-grain fact adalah fact table yang menyimpan data pada level agregasi lebih tinggi dibanding dimension yang terkait. Contohnya target pada level Category sementara Product dimension berada pada level individual Product.

Apakah many-to-many merupakan limited relationship?

Ya. Microsoft menjelaskan bahwa cardinality many-to-many menghasilkan limited relationship karena tidak terdapat guaranteed “one” side.

Apa risiko limited relationship?

Limited relationship memiliki perilaku evaluasi berbeda dari regular relationship, tidak menggunakan table expansion yang sama, dan pelanggaran referential integrity dapat menyebabkan unmatched rows tidak diperlakukan dengan cara yang sama seperti regular relationship.

Apakah saya harus menggunakan Both pada many-to-many?

Tidak selalu. Pada bridge-table design, satu bidirectional relationship mungkin diperlukan agar filter dapat melewati bridge menuju fact, tetapi penggunaan Both sebaiknya dibatasi hanya pada relationship yang memang membutuhkannya.

Mengapa grand total tidak sama dengan penjumlahan row?

Pada many-to-many, satu entity dapat muncul dalam beberapa group. Karena itu row values dapat bersifat non-additive dan grand total dievaluasi ulang berdasarkan filter context keseluruhan.

Apakah many-to-many buruk untuk Power BI?

Tidak. Many-to-many merupakan relationship bisnis yang valid. Yang perlu dihindari adalah penggunaan direct *:* tanpa memahami grain, filtering, dan alternatif desain seperti bridge table atau star schema.


Kesimpulan

Many-to-Many Relationship merupakan salah satu topik terpenting dalam data modeling Power BI karena menggambarkan banyak situasi bisnis nyata yang tidak dapat direpresentasikan hanya dengan relationship one-to-many sederhana.

Namun konsep yang paling penting untuk dipahami adalah bahwa many-to-many business relationship tidak selalu berarti Anda harus membuat direct many-to-many cardinality di Power BI.

Untuk relationship antara dua dimension, Microsoft merekomendasikan menggunakan bridge table atau factless fact table. Kedua dimension mempertahankan unique ID masing-masing, sementara bridge menyimpan setiap association dan dihubungkan menggunakan relationship one-to-many. Pada kondisi yang membutuhkan filter propagation melalui bridge menuju fact table, salah satu relationship dapat menggunakan bidirectional filtering.

Untuk hubungan antara dua fact table, direct many-to-many memang secara teknis memungkinkan, tetapi Microsoft secara umum tidak merekomendasikannya sebagai desain utama. Shared dimensions dan star schema menghasilkan fleksibilitas filtering dan grouping yang lebih baik serta memungkinkan penggunaan regular one-to-many relationships.

Sementara itu, direct many-to-many cardinality mempunyai peran yang valid ketika bekerja dengan higher-grain facts. Target pada level Category, misalnya, dapat berhubungan dengan Product dimension yang berada pada level individual Product. Namun developer harus mengontrol summarization menggunakan explicit measures agar target Category tidak disalahartikan sebagai target Product.

Relationship many-to-many juga merupakan limited relationship. Ini berarti cara evaluasinya berbeda dengan regular one-to-many relationship, sehingga data integrity, filter propagation, dan pemahaman grain menjadi semakin penting.

Karena itu jangan memulai modeling dengan pertanyaan:

Bagaimana cara membuat relationship *:*?

Mulailah dengan:

Apa sebenarnya hubungan bisnis antara kedua entity ini?

Kemudian tanyakan:

Apa grain masing-masing tabel?

Lalu:

Apakah saya membutuhkan bridge table?

Atau:

Apakah kedua fact table seharusnya berbagi dimension?

Atau:

Apakah ini memang kasus higher-grain fact?

Baru setelah itu tentukan physical relationship yang sesuai.

Jika satu prinsip harus diingat dari seluruh pembahasan ini, prinsip tersebut adalah:

Jangan memilih cardinality berdasarkan apa yang membuat Power BI menerima relationship. Pilih cardinality berdasarkan grain dan realitas bisnis yang ingin direpresentasikan.

Semantic model Power BI yang baik bukan model dengan relationship paling sedikit atau paling banyak.

Model yang baik adalah model yang membuat hubungan antar data menjadi:

akurat, eksplisit, mudah dijelaskan, efisien, dapat diprediksi, dan sesuai dengan cara bisnis sebenarnya bekerja.


Referensi Utama

Microsoft Learn — Many-to-many relationship guidance. Halaman ini membahas tiga skenario utama many-to-many: dimension-to-dimension, fact-to-fact, dan higher-grain fact, serta terakhir tercatat diperbarui pada 26 November 2025.

Microsoft Learn — Understand star schema and the importance for Power BI.

Microsoft Learn — Model relationships in Power BI Desktop, termasuk relationship evaluation, limited relationships, dan filter-path ambiguity.

Microsoft Learn — Bi-directional relationship guidance.

Leave a Reply