Pokyny k relaci M:NMany-to-many relationship guidance

Tento článek je určený pro modelátory dat, kteří pracují s Power BI Desktopem.This article targets you as a data modeler working with Power BI Desktop. Popisuje tři různé scénáře modelování relací M:N.It describes three different many-to-many modeling scenarios. Nabízí také pokyny k jejich úspěšnému návrhu ve vašich modelech.It also provides you with guidance on how to successfully design for them in your models.

Poznámka

Článek neobsahuje úvod do relací v modelu.An introduction to model relationships is not covered in this article. Pokud se ještě nevyznáte v relacích, jejich vlastnostech a způsobu jejich konfigurace, doporučujeme si napřed přečíst článek Relace modelů v Power BI Desktopu.If you're not completely familiar with relationships, their properties or how to configure them, we recommend that you first read the Model relationships in Power BI Desktop article.

Je také důležité, abyste uměli navrhnout hvězdicové schéma.It's also important that you have an understanding of star schema design. Další informace najdete v článku Vysvětlení hvězdicového schématu a jeho důležitosti pro Power BI.For more information, see Understand star schema and the importance for Power BI.

Ve skutečnosti existují tři scénáře M:N.There are, in fact, three many-to-many scenarios. Můžou nastat, pokud musíte:They can occur when you're required to:

Relace dimenzí M:NRelate many-to-many dimensions

Pojďme se podívat na první typ scénáře M:N včetně příkladu.Let's consider the first many-to-many scenario type with an example. Klasickým scénářem je relace dvou entit: bankovních zákazníků a jejich účtů.The classic scenario relates two entities: bank customers and bank accounts. Je potřeba vzít v úvahu, že zákazníci můžou mít více účtů a účty můžou patřit více zákazníkům.Consider that customers can have multiple accounts, and accounts can have multiple customers. Pokud jeden účet patří více zákazníkům, běžně se tito zákazníci označují jako společní vlastníci účtu.When an account has multiple customers, they're commonly called joint account holders.

Modelování těchto entit je jednoduché.Modeling these entities is straight forward. V jedné tabulce typu dimenze jsou uložené účty a ve druhé tabulce typu dimenze jsou uložení zákazníci.One dimension-type table stores accounts, and another dimension-type table stores customers. Pro tabulky typu dimenze je charakteristické, že každá tabulka má sloupec ID.As is characteristic of dimension-type tables, there's an ID column in each table. K modelování vztahu mezi oběma tabulkami potřebujeme třetí tabulku.To model the relationship between the two tables, a third table is required. Tato tabulka bývá často označovaná jako spojovací tabulka.This table is commonly referred to as a bridging table. V tomto příkladu je v ní uložený jeden řádek pro každé spojení zákazníka a účtu.In this example, it's purpose is to store one row for each customer-account association. Pokud tato tabulka obsahuje jenom sloupce ID, říká se jí tabulka faktů bez faktů.Interestingly, when this table only contains ID columns, it's called a factless fact table.

Tady je diagram jednoduchého modelu složeného z těchto tří tabulek.Here's a simplistic model diagram of the three tables.

Diagram znázorňující model, který obsahuje tři tabulky

První tabulka se jmenuje Account (Účet) a obsahuje dva sloupce: AccountID (IDúčtu) a Account (Účet).The first table is named Account, and it contains two columns: AccountID and Account. Druhá tabulka se jmenuje AccountCustomer (ZákazníkÚčtu) a obsahuje dva sloupce: AccountID (IDúčtu) a CustomerID (IDzákazníka).The second table is named AccountCustomer, and it contains two columns: AccountID and CustomerID. Třetí tabulka se jmenuje Customer (Zákazník) a obsahuje dva sloupce: CustomerID (IDzákazníka) a Customer (Zákazník).The third table is named Customer, and it contains two columns: CustomerID and Customer. Mezi tabulkami neexistují žádné relace.Relationships don't exist between any of the tables.

Přidáme dvě relace 1:N, kterými spojíme tabulky.Two one-to-many relationships are added to relate the tables. Tady je diagram aktualizovaného modelu se spojenými tabulkami.Here's an updated model diagram of the related tables. Přidáme tabulku typu fakta, kterou pojmenujeme Transaction (Transakce).A fact-type table named Transaction has been added. Jsou v ní zaznamenané transakce na účtu.It records account transactions. Spojovací tabulka a všechny sloupce ID jsou skryté.The bridging table and all ID columns have been hidden.

Diagram znázorňující, že model teď obsahuje čtyři tabulky

Abychom si mohli popsat, jak funguje šíření relačního filtru, upravíme diagram modelu, aby zobrazoval řádky tabulek.To help describe how the relationship filter propagation works, the model diagram has been modified to reveal the table rows.

Poznámka

V diagramu modelu v Power BI Desktopu nejdou řádky tabulek zobrazit.It's not possible to display table rows in the Power BI Desktop model diagram. Uděláme to v tomto článku, abychom výklad doplnili jasnými příklady.It's done in this article to support the discussion with clear examples.

Diagram znázorňující, že model teď ukazuje řádky tabulky

Podrobnosti řádků všech čtyř tabulek jsou popsané v následujícím seznamu s odrážkami:The row details for the four tables are described in the following bulleted list:

  • Tabulka Account (Účet) má dva řádky:The Account table has two rows:
    • AccountID 1 je pro účet Account-01.AccountID 1 is for Account-01
    • AccountID 2 je pro účet Account-02.AccountID 2 is for Account-02
  • Tabulka Customer (Zákazník) má dva řádky:The Customer table has two rows:
    • CustomerID 91 je pro zákazníka Customer-91.CustomerID 91 is for Customer-91
    • CustomerID 92 je pro zákazníka Customer-92.CustomerID 92 is for Customer-92
  • Tabulka AccountCustomer (ZákazníkÚčtu) má tři řádky:The AccountCustomer table has three rows:
    • Identifikátor AccountID 1 je přidružený k zákazníkovi CustomerID 91.AccountID 1 is associated with CustomerID 91
    • Identifikátor AccountID 1 je přidružený k zákazníkovi CustomerID 92.AccountID 1 is associated with CustomerID 92
    • Identifikátor AccountID 2 je přidružený k zákazníkovi CustomerID 92.AccountID 2 is associated with CustomerID 92
  • Tabulka Transaction (Transakce) má tři řádky:The Transaction table has three rows:
    • Date January 1 2019, AccountID 1, Amount 100Date January 1 2019, AccountID 1, Amount 100
    • Date February 2 2019, AccountID 2, Amount 200Date February 2 2019, AccountID 2, Amount 200
    • Date March 3 2019, AccountID 1, Amount -25Date March 3 2019, AccountID 1, Amount -25

Pojďme se podívat, co se stane při dotazu do modelu.Let's see what happens when the model is queried.

Dole jsou dva vizuály, které shrnují sloupec Amount (Částka) tabulky Transaction (Transakce).Below are two visuals that summarize the Amount column from the Transaction table. První vizuál seskupuje údaje podle účtu. Součet sloupce Amount (Částka) představuje zůstatek účtu.The first visual groups by account, and so the sum of the Amount columns represents the account balance. Druhý vizuál seskupuje údaje podle zákazníka. Součet sloupce Amount (Částka) představuje zůstatek zákazníka.The second visual groups by customer, and so the sum of the Amount columns represents the customer balance.

Diagram znázorňující dva vizuály sestav vedle sebe

První vizuál má název Account Balance (Zůstatek účtu) a má dva sloupce: Account (Účet) a Amount (Částka).The first visual is titled Account Balance, and it has two columns: Account and Amount. Zobrazuje následující výsledek:It displays the following result:

  • Zůstatek pro Account-01 je 75.Account-01 balance amount is 75
  • Zůstatek pro Account-02 je 200.Account-02 balance amount is 200
  • Celkový součet je 275.The total is 275

Druhý vizuál má název Customer Balance (Zůstatek zákazníka) a má dva sloupce: Customer (Zákazník) a Amount (Částka).The second visual is titled Customer Balance, and it has two columns: Customer and Amount. Zobrazuje následující výsledek:It displays the following result:

  • Zůstatek zákazníka Customer-91 je 275.Customer-91 balance amount is 275
  • Zůstatek zákazníka Customer-92 je 275.Customer-92 balance amount is 275
  • Celkový součet je 275.The total is 275

Při rychlém pohledu na řádky tabulky a na vizuál Account Balance (Zůstatek účtu) zjistíme, že je správný výsledek každého účtu i celková částka.A quick glance at the table rows and the Account Balance visual reveals that the result is correct, for each account and the total amount. Je to proto, že seskupením účtů dojde k rozšíření filtru daného účtu do tabulky Transaction (Transakce).It's because each account grouping results in a filter propagation to the Transaction table for that account.

Ale zdá se, že ve vizuálu Customer Balance (Zůstatek zákazníka) přece jen není něco v pořádku.However, something doesn't appear correct with the Customer Balance visual. Zůstatek každého zákazníka ve vizuálu Customer Balance (Zůstatek zákazníka) je stejný jako celkový zůstatek.Each customer in the Customer Balance visual has the same balance as the total balance. Tento výsledek by byl správný jen v případě, že by všichni zákazníci byli společnými vlastníky všech účtů.This result could only be correct if every customer was a joint account holder of every account. V tomto příkladu tomu ale tak není.That's not the case in this example. Problém souvisí s šířením filtru.The issue is related to filter propagation. Filtr nedosahuje až do tabulky Transaction (Transakce).It's not flowing all the way to the Transaction table.

Prohlédněte si směr relačního filtru z tabulky Customer (Zákazník) do tabulky Transaction (Transakce).Follow the relationship filter directions from the Customer table to the Transaction table. Je patrné, že relace mezi tabulkami Account (Účet) a AccountCustomer (ZákazníkÚčtu) se šíří nesprávným směrem.It should be apparent that the relationship between the Account and AccountCustomer table is propagating in the wrong direction. Směr filtru u této relace musí být nastaven na Both (Oba).The filter direction for this relationship must be set to Both.

Diagram znázorňující, že model je aktualizovaný

Diagram znázorňující dva stejné vizuály sestav vedle sebe.

Podle očekávání se nezměnil vizuál Account Balance (Zůstatek účtu).As expected, there has been no change to the Account Balance visual.

Ale ve vizuálu Customer Balance (Zůstatek zákazníka) teď vidíme následující výsledek:The Customer Balance visuals, however, now displays the following result:

  • Zůstatek zákazníka Customer-91 je 75.Customer-91 balance amount is 75
  • Zůstatek zákazníka Customer-92 je 275.Customer-92 balance amount is 275
  • Celkový součet je 275.The total is 275

Ve vizuálu Customer Balance se teď zobrazuje správný výsledek.The Customer Balance visual now displays a correct result. Prohlédněte si směr filtrování a podívejte se na výpočet zůstatků zákazníků.Follow the filter directions for yourself, and see how the customer balances were calculated. Dále si všimněte, že celkový součet za vizuál znamená součet za všechny zákazníky.Also, understand that the visual total means all customers.

Pokud by někdo neznal relace modelu, mohl by dojít k závěru, že výsledek není správně.Someone unfamiliar with the model relationships could conclude that the result is incorrect. Mohl by se ptát: Proč celkový zůstatek obou zákazníků Customer-91 a Customer-92 není 350 (75 + 275)?They might ask: Why isn't the total balance for Customer-91 and Customer-92 equal to 350 (75 + 275)?

Odpověď na tuto otázku se skrývá v pochopení relace M:N.The answer to their question lies in understanding the many-to-many relationship. Zůstatek každého zákazníka představuje součet zůstatků více účtů, takže zůstatky zákazníků se nedají sčítat.Each customer balance can represent the addition of multiple account balances, and so the customer balances are non-additive.

Pokyny k relacím dimenzí M:NRelate many-to-many dimensions guidance

Pokud máte mezi tabulkami typu dimenze relace M:N, máme tu pro vás následující pokyny:When you have a many-to-many relationship between dimension-type tables, we provide the following guidance:

  • Každou entitu propojenou relací M:N přidejte jako tabulku modelu. Ověřte, že má sloupec s jedinečným identifikátorem (ID).Add each many-to-many related entity as a model table, ensuring it has a unique identifier (ID) column
  • Přidejte spojovací tabulku, ve které budou uloženy spojené entity.Add a bridging table to store associated entities
  • Mezi těmito třemi tabulkami vytvořte relace 1:N.Create one-to-many relationships between the three tables
  • Nakonfigurujte jednu obousměrnou relaci, abyste umožnili rozšířit filtr až do tabulek typu fakta.Configure one bi-directional relationship to allow filter propagation to continue to the fact-type tables
  • Pokud není vhodné, aby chyběly hodnoty ID, nastavte ve sloupcích ID vlastnost Is Nullable na hodnotu FALSE. Pokud by chyběly hodnoty, nepodaří se aktualizace dat.When it isn't appropriate to have missing ID values, set the Is Nullable property of ID columns to FALSE—data refresh will then fail if missing values are sourced
  • Skryjte spojovací tabulku (pokud neobsahuje další sloupce nebo míry potřebné v sestavách).Hide the bridging table (unless it contains additional columns or measures required for reporting)
  • Skryjte sloupce s ID, které se nehodí k vytváření sestav (například pokud ID představují náhradní klíče).Hide any ID columns that aren't suitable for reporting (for example, when IDs are surrogate keys)
  • Pokud je smysluplné nechat sloupec ID viditelný, zajistěte, aby to bylo na té straně relace, která je označená číslem 1, a vždy ho skryjte na té straně relace, která je označená písmenem N.If it makes sense to leave an ID column visible, ensure that it's on the "one" slide of the relationship—always hide the "many" side column. Tak bude mít filtr nejlepší výkon.It results in the best filter performance.
  • Abyste se vyhnuli nejasnostem nebo nesprávné interpretaci, vysvětlete model uživatelům sestavy. Popisy můžete přidat do textových polí nebo do záhlaví vizuálu.To avoid confusion or misinterpretation, communicate explanations to your report users—you can add descriptions with text boxes or visual header tooltips

Nedoporučujeme připojovat tabulky typu dimenze přímo relací M:N.We don't recommend you relate many-to-many dimension-type tables directly. Takový přístup k návrhu by vyžadoval, abyste nakonfigurovali relaci s kardinalitou M:N.This design approach requires configuring a relationship with a many-to-many cardinality. V zásadě to možné je, ale znamená to, že spojované sloupce budou obsahovat duplicitní hodnoty.Conceptually it can be achieved, yet it implies that the related columns will contain duplicate values. Uznávaný postup při návrhu je ale takový, že tabulky typu dimenze mají sloupec ID.It's a well-accepted design practice, however, that dimension-type tables have an ID column. Tabulky typu dimenze by měly sloupec ID vždy používat jako stranu „jedna“ relace.Dimension-type tables should always use the ID column as the "one" side of a relationship.

Relace fakt M:NRelate many-to-many facts

Druhý typ scénáře M:N představuje relaci dvou tabulek typu fakta.The second many-to-many scenario type involves relating two fact-type tables. Dvě tabulky typu fakta můžete spojit přímo.Two fact-type tables can be related directly. Tato technika návrhu je užitečná, když potřebujete rychle a jednoduše prozkoumat data.This design technique can be useful for quick and simple data exploration. My ale tento způsob návrhu obecně nedoporučujeme.However, and to be clear, we generally don't recommend this design approach. Důvod si vysvětlíme dále v této části.We'll explain why later in this section.

Představte si například dvě tabulky typu fakta: Order (Objednávka) a Fulfillment (Plnění).Let's consider an example that involves two fact-type tables: Order and Fulfillment. Tabulka Order (Objednávka) obsahuje ke každému řádku objednávky jeden řádek a tabulka Fulfillment (Plnění) obsahuje k řádku objednávky nula a více řádků.The Order table contains one row per order line, and the Fulfillment table can contains zero or more rows per order line. Řádky v tabulce Order (Objednávka) představují prodejní objednávky.Rows in the Order table represent sales orders. Řádky v tabulce Fulfillment (Plnění) představují položky objednávky, které byly odeslány.Rows in the Fulfillment table represent order items that have been shipped. Oba sloupce OrderID jsou spojené relací M:N. Filtr se šíří jenom z tabulky Order (Objednávka) (tabulka Order filtruje tabulku Fulfillment).A many-to-many relationship relates the two OrderID columns, with filter propagation only from the Order table (Order filters Fulfillment).

Diagram znázorňující model, který obsahuje dvě tabulky: Order (Objednávka) a Fulfillment (Plnění).

Kardinalita relace je nastavená na M:N, abychom mohli do obou tabulek ukládat duplicitní hodnoty OrderID.The relationship cardinality is set to many-to-many to support storing duplicate OrderID values in both tables. V tabulce Order (Objednávka) můžou existovat duplicitní hodnoty OrderID (IDobjednávky), protože objednávka může mít více řádků.In the Order table, duplicate OrderID values can exist because an order can have multiple lines. V tabulce Fulfillment (Plnění) můžou existovat duplicitní hodnoty OrderID (IDobjednávky), protože objednávky můžou mít více řádků a řádky objednávky můžou být plněny několika zásilkami.In the Fulfillment table, duplicate OrderID values can exist because orders may have multiple lines, and order lines can be fulfilled by many shipments.

Pojďme se podívat na řádky tabulky.Let's now take a look at the table rows. V tabulce Fulfillment (Plnění) si všimněte, že plnění řádků objednávky může probíhat ve více zásilkách.In the Fulfillment table, notice that order lines can be fulfilled by multiple shipments. (Pokud řádek objednávky chybí, znamená to, že objednávka čeká na splnění.)(The absence of an order line means the order is yet to be fulfilled.)

Diagram znázorňující, že model teď ukazuje řádky tabulky

Podrobnosti o řádcích obou tabulek jsou popsané v následujícím seznamu s odrážkami:The row details for the two tables are described in the following bulleted list:

  • Tabulka Order (Objednávka) má pět řádků:The Order table has five rows:
    • OrderDate January 1 2019, OrderID 1, OrderLine 1, ProductID Prod-A, OrderQuantity 5, Sales 50OrderDate January 1 2019, OrderID 1, OrderLine 1, ProductID Prod-A, OrderQuantity 5, Sales 50
    • OrderDate January 1 2019, OrderID 1, OrderLine 2, ProductID Prod-B, OrderQuantity 10, Sales 80OrderDate January 1 2019, OrderID 1, OrderLine 2, ProductID Prod-B, OrderQuantity 10, Sales 80
    • OrderDate February 2 2019, OrderID 2, OrderLine 1, ProductID Prod-B, OrderQuantity 5, Sales 40OrderDate February 2 2019, OrderID 2, OrderLine 1, ProductID Prod-B, OrderQuantity 5, Sales 40
    • OrderDate February 2 2019, OrderID 2, OrderLine 2, ProductID Prod-C, OrderQuantity 1, Sales 20OrderDate February 2 2019, OrderID 2, OrderLine 2, ProductID Prod-C, OrderQuantity 1, Sales 20
    • OrderDate March 3 2019, OrderID 3, OrderLine 1, ProductID Prod-C, OrderQuantity 5, Sales 100OrderDate March 3 2019, OrderID 3, OrderLine 1, ProductID Prod-C, OrderQuantity 5, Sales 100
  • Tabulka Fulfillment (Plnění) má čtyři řádky:The Fulfillment table has four rows:
    • FulfillmentDate January 1 2019, FulfillmentID 50, OrderID 1, OrderLine 1, FulfillmentQuantity 2FulfillmentDate January 1 2019, FulfillmentID 50, OrderID 1, OrderLine 1, FulfillmentQuantity 2
    • FulfillmentDate February 2 2019, FulfillmentID 51, OrderID 2, OrderLine 1, FulfillmentQuantity 5FulfillmentDate February 2 2019, FulfillmentID 51, OrderID 2, OrderLine 1, FulfillmentQuantity 5
    • FulfillmentDate February 2 2019, FulfillmentID 52, OrderID 1, OrderLine 1, FulfillmentQuantity 3FulfillmentDate February 2 2019, FulfillmentID 52, OrderID 1, OrderLine 1, FulfillmentQuantity 3
    • FulfillmentDate January 1 2019, FulfillmentID 53, OrderID 1, OrderLine 2, FulfillmentQuantity 10FulfillmentDate January 1 2019, FulfillmentID 53, OrderID 1, OrderLine 2, FulfillmentQuantity 10

Pojďme se podívat, co se stane při dotazu do modelu.Let's see what happens when the model is queried. Tady je vizuál tabulky, který srovnává objednané a splněné množství podle sloupce OrderID (IDobjednávky) tabulky Order (Objednávka).Here's a table visual comparing order and fulfillment quantities by the Order table OrderID column.

Diagram znázorňující vizuál tabulky se třemi sloupci: OrderID (IDobjednávky), OrderQuantity (ObjednanéMnožství) a FulfillmentQuantity (SplněnéMnožství).

Vizuál představuje přesný výsledek.The visual presents an accurate result. Model je ale užitečný jen z části, protože položky můžete filtrovat nebo seskupovat jenom podle sloupce OrderID tabulky Order.However, the usefulness of the model is limited—you can only filter or group by the Order table OrderID column.

Pokyny k faktům M:NRelate many-to-many facts guidance

Obecně nedoporučujeme spojovat dvě tabulky typu fakta přímo kardinalitou M:N.Generally, we don't recommend relating two fact-type tables directly using many-to-many cardinality. Hlavním důvodem je, že takový model nedovolí ve vizuálu flexibilně filtrovat ani seskupovat položky sestavy.The main reason is because the model won't provide flexibility in the ways you report visuals filter or group. V našem příkladu můžeme vizuály filtrovat nebo seskupovat jenom podle sloupce OrderID (IDobjednávky) tabulky Order (Objednávka).In the example, it's only possible for visuals to filter or group by the Order table OrderID column. Další důvod souvisí s kvalitou dat.An additional reason relates to the quality of your data. V případě potíží s integritou dat je možné některé řádky z dotazování vynechat, což je dáno povahou omezené relace.If your data has integrity issues, it's possible some rows may be omitted during querying due to the nature of the limited relationship. Další informace najdete v tématu Relace modelu v Power BI Desktopu (vyhodnocení relace).For more information, see Model relationships in Power BI Desktop (Relationship evaluation).

Místo přímého spojení tabulek typu fakta doporučujeme osvojit si principy návrhu označované jako hvězdicové schéma.Instead of relating fact-type tables directly, we recommend you adopt Star Schema design principles. Uděláte to tak, že přidáte tabulky typu dimenze.You do it by adding dimension-type tables. Tabulky typu dimenze pak spojíte s tabulkami typu fakta relací 1:N.The dimension-type tables then relate to the fact-type tables by using one-to-many relationships. Takový způsob návrhu sestav je odolný a současně flexibilní.This design approach is robust as it delivers flexible reporting options. Umožňuje filtrovat nebo seskupovat podle libovolného sloupce typu dimenze a sumarizovat položky v související tabulce typu fakta.It lets you filter or group using any of the dimension-type columns, and summarize any related fact-type table.

Pojďme si prohlédnout lepší řešení.Let's consider a better solution.

Diagram znázorňující model, který obsahuje šest tabulek: OrderLine (ŘádekObjednávky), OrderDate (DatumObjednávky), Order (Objednávka), Fulfillment (Plnění), Product (Produkt) a FulfillmentDate (DatumPlnění).

Všimněte si následujících změn návrhu:Notice the following design changes:

  • Do modelu přibyly čtyři další tabulky: OrderLine (ŘádekObjednávky), OrderDate (DatumObjednávky), Product (Produkt) a FulfillmentDate (DatumPlnění).The model now has four additional tables: OrderLine, OrderDate, Product, and FulfillmentDate
  • Všechny čtyři přidané tabulky jsou typu dimenze. K jejich spojení s tabulkami typu fakta použijeme relaci 1:N.The four additional tables are all dimension-type tables, and one-to-many relationships relate these tables to the fact-type tables
  • Tabulka OrderLine (ŘádekObjednávky) obsahuje sloupec OrderLineID (IDřádkuObjednávky), který představuje hodnotu OrderID krát 100 plus hodnota OrderLine – dostaneme jedinečný identifikátor každého řádku objednávky.The OrderLine table contains an OrderLineID column, which represents the OrderID value multiplied by 100, plus the OrderLine value—a unique identifier for each order line
  • Tabulky Order (Objednávka) a Fulfillment (Plnění) teď obsahují sloupec OrderLineID (IDřádkuObjednávky), ale už neobsahují sloupce OrderID (IDobjednávky) ani OrderLine (ŘádekObjednávky).The Order and Fulfillment tables now contain an OrderLineID column, and they no longer contain the OrderID and OrderLine columns
  • Tabulka Fulfillment (Plnění) teď obsahuje sloupce OrderDate (DatumObjednávky) a ProductID (IDproduktu).The Fulfillment table now contains OrderDate and ProductID columns
  • Tabulka FulfillmentDate (DatumPlnění) je spojená jenom s tabulkou Fulfillment (Plnění).The FulfillmentDate table relates only to the Fulfillment table
  • Všechny sloupce s jedinečným identifikátorem jsou skryté.All unique identifier columns are hidden

Pokud věnujeme čas použití principů hvězdicového schématu, přinese nám to následující výhody:Taking the time to apply star schema design principles delivers the following benefits:

  • Vizuály sestav můžete filtrovat nebo seskupovat podle libovolného viditelného sloupce, který je v tabulkách typu dimenze.Your report visuals can filter or group by any visible column from the dimension-type tables
  • Ve vizuálech v sestavách můžete sumarizovat libovolný viditelný sloupec z tabulek typu fakta.Your report visuals can summarize any visible column from the fact-type tables
  • Filtry použité v tabulkách OrderLine (ŘádekObjednávky), OrderDate (DatumObjednávky) nebo Product (Produkt) se šíří do obou tabulek typu fakta.Filters applied to the OrderLine, OrderDate, or Product tables will propagate to both fact-type tables
  • Všechny relace jsou 1:N a každá představuje normální relaci.All relationships are one-to-many, and each relationship is a regular relationship. Problémy s integritou dat nejsou zamaskované.Data integrity issues won't be masked. Další informace najdete v tématu Relace modelu v Power BI Desktopu (vyhodnocení relace).For more information, see Model relationships in Power BI Desktop (Relationship evaluation).

Spojování faktů vyšší úrovněRelate higher grain facts

Tento scénář M:N se zcela liší od předchozích dvou scénářů, které jsme popsali v tomto článku.This many-to-many scenario is very different from the other two already described in this article.

Představte si příklad se čtyřmi tabulkami: Date (Datum), Sales (Prodej), Product (Produkt) a Target (Cíl).Let's consider an example involving four tables: Date, Sales, Product, and Target. Tabulky Date a Product jsou typu dimenze. Každá z nich je relací 1:N připojená k tabulce Sales, která je typu fakta.The Date and Product are dimension-type tables, and one-to-many relationships relate each to the Sales fact-type table. Zatím máme dobrý návrh hvězdicového schématu.So far, it represents a good star schema design. S ostatními tabulkami ale ještě není spojená tabulka Target.The Target table, however, is yet to be related to the other tables.

Diagram znázorňující model, který obsahuje čtyři tabulky: Date (Datum), Sales (Prodej), Product (Produkt) a Target (Cíl).

Tabulka Target (Cíl) obsahuje tři sloupce: Category (Kategorie), TargetQuantity (CílovéMnožství) a TargetYear (CílovýRok).The Target table contains three columns: Category, TargetQuantity, and TargetYear. Řádky tabulky ukrývají dělení ročních období a kategorií produktů.The table rows reveal a granularity of year and product category. Jinými slovy: Cíle, které se používají k měření dosažených prodejů, jsou nastavené v každém roce pro každou kategorii produktu.In other words, targets—used to measure sales performance—are set each year for each product category.

Diagram znázorňující, že tabulka Target má tři sloupce: TargetYear (CílovýRok), Category (Kategorie) a TargetQuantity (CílovéMnožství).

V tabulce Target (Cíl) jsou uložená data na vyšší úrovni než v tabulkách typu dimenze, a proto nemůžeme vytvořit relaci 1:N.Because the Target table stores data at a higher level than the dimension-type tables, a one-to-many relationship cannot be created. Platí to vlastně jenom o jedné relaci.Well, it's true for just one of the relationships. Pojďme se podívat, jak můžeme tabulku Target (Cíl) spojit s tabulkami typu dimenze.Let's explore how the Target table can be related to the dimension-type tables.

Spojování časových období vyšší úrovněRelate higher grain time periods

Mezi tabulkami Date a Target by měla být relace 1:N.A relationship between the Date and Target tables should be a one-to-many relationship. Je to proto, že hodnoty sloupce TargetYear (CílovýRok) představují kalendářní data.It's because the TargetYear column values are dates. V tomto příkladě představuje každá hodnota ve sloupci TargetYear první den cílového roku.In this example, each TargetYear column value is the first date of the target year.

Tip

Při ukládání faktických údajů, které jsou podrobnější než každodenní údaje, nastavte typ dat sloupce na Date (Datum) (nebo na Whole number (Celé číslo), pokud pro kalendářní data používáte klíče).When storing facts at a higher time granularity than day, set the column data type to Date (or Whole number if you're using date keys). Do sloupce uložte hodnotu, která představuje první den časového období.In the column, store a value representing the first day of the time period. Například roční období je zaznamenané jako 1. leden daného roku a měsíční období je zaznamenané jako první den daného měsíce.For example, a year period is recorded as January 1 of the year, and a month period is recorded as the first day of that month.

Je potřeba postupovat opatrně, abyste měli jistotu, že filtry měsíce nebo data poskytnou smysluplný výsledek.Care must be taken, however, to ensure that month or date level filters produce a meaningful result. Bez zvláštní logiky výpočtu se může stát, že se ve vizuálech sestav jako cílová data zobrazí jenom první den každého roku.Without any special calculation logic, report visuals may report that target dates are literally the first day of each year. U všech ostatních dnů – a také u všech měsíců s výjimkou ledna – se cílové množství sečte jako BLANK.All other days—and all months except January—will summarize the target quantity as BLANK.

V následujícím maticovém vizuálu je vidět, co se stane, když uživatel sestavy přejde z roku na měsíce.The following matrix visual shows what happens when the report user drills from a year into its months. Vizuál sčítá sloupec TargetQuantity (CílovéMnožství).The visual is summarizing the TargetQuantity column. (U řádků matice byla povolena možnost Zobrazit položky, které neobsahují data.)(The Show items with no data option has been enabled for the matrix rows.)

Diagram znázorňující maticový vizuál, na kterém je vidět, že cílové množství pro rok 2020 je 270.

Abyste se takovému chování vyhnuli, doporučujeme k řízení sumarizace faktických dat používat míry.To avoid this behavior, we recommend you control the summarization of your fact data by using measures. Jedním ze způsobů, jak řídit sumarizaci, je vrátit při dotazu na časová období nižší úrovně hodnotu BLANK.One way to control the summarization is to return BLANK when lower-level time periods are queried. Další způsob, který se definuje některými složitějšími funkcemi DAX, spočívá v přidělení poměrné části hodnot jednotlivým časovým obdobím nižší úrovně.Another way—defined with some sophisticated DAX—is to apportion values across lower-level time periods.

Představte si následující definici míry, která používá funkci DAX ISFILTERED.Consider the following measure definition that uses the ISFILTERED DAX function. Vrátí hodnotu jen tehdy, když nejsou sloupce Date a Month filtrované.It only returns a value when the Date or Month columns aren't filtered.

Target Quantity =
IF(
    NOT ISFILTERED('Date'[Date])
        && NOT ISFILTERED('Date'[Month]),
    SUM(Target[TargetQuantity])
)

V následujícím maticovém vizuálu se používá míra Target Quantity (Cílové množství).The following matrix visual now uses the Target Quantity measure. Všechna měsíční cílová množství jsou BLANK.It shows that all monthly target quantities are BLANK.

Diagram znázorňující maticový vizuál, na kterém je vidět, že cílové množství pro rok 2020 je 270 a měsíční hodnoty jsou prázdné

Spojování vyšší úrovně (jiné než datum)Relate higher grain (non-date)

K návrhu připojení sloupce, který nepředstavuje datum a je z tabulky typu dimenze, k tabulce typu fakta, která je vyšší úrovně než tabulka typu dimenze, je potřeba přistupovat jinak.A different design approach is required when relating a non-date column from a dimension-type table to a fact-type table (and it's at a higher grain than the dimension-type table).

Sloupce Category (v obou tabulkách Product a Target) obsahují duplicitní hodnoty.The Category columns (from both the Product and Target tables) contains duplicate values. Takže v relaci 1:N chybí strana označená číslem jedna.So, there's no "one" for a one-to-many relationship. V takovém případě bude potřeba vytvořit relaci M:N.In this case, you'll need to create a many-to-many relationship. Tuto relaci musí šířit filtry jedním směrem, totiž z tabulky typu dimenze do tabulky typu fakta.The relationship should propagate filters in a single direction, from the dimension-type table to the fact-type table.

Diagram znázorňující model tabulek Target a Product

Pojďme se podívat na řádky tabulky.Let's now take a look at the table rows.

Diagram znázorňující model, který obsahuje dvě tabulky: Target (Cíl) a Product (Produkt).

V tabulce Target jsou čtyři řádky: dva pro každý cílový rok (2019 a 2020) a dvě kategorie: Clothing (Oděvy) a Accessories (Doplňky).In the Target table, there are four rows: two rows for each target year (2019 and 2020), and two categories (Clothing and Accessories). V tabulce Product jsou tři produkty.In the Product table, there are three products. Dva patří do kategorie oděvů a jeden patří do kategorie doplňků.Two belong to the clothing category, and one belongs to the accessories category. Barva jednoho oděvu je zelená a zbývající dva jsou modré.One of the clothing colors is green, and the remaining two are blue.

Vizuál tabulky seskupený podle sloupce Category (Kategorie) tabulky Product (Produkt) vygeneruje následující výsledek.A table visual grouping by the Category column from the Product table produces the following result.

Diagram znázorňující vizuál tabulky se dvěma sloupci: Category (Kategorie) a TargetQuantity (CílovéMnožství).

Tento vizuál generuje správný výsledek.This visual produces the correct result. Pojďme se podívat, co se stane, když k seskupení cílového množství použijeme sloupec Color (Barva) tabulky Product (Produkt).Let's now consider what happens when the Color column from the Product table is used to group target quantity.

Diagram znázorňující vizuál tabulky se dvěma sloupci: Color (Barva) a TargetQuantity (CílovéMnožství).

Vizuál neinterpretuje data správně.The visual produces a misrepresentation of the data. Co se stalo?What is happening here?

Filtr sloupce Color (Barva) získá z tabulky Product (Produkt) dva řádky.A filter on the Color column from the Product table results in two rows. Jeden pro kategorii Clothing (Oděvy) a druhý pro kategorii Accessories (Doplňky).One of the rows is for the Clothing category, and the other is for the Accessories category. Obě hodnoty kategorií se rozšíří jako filtry do tabulky Target (Cíl).These two category values are propagated as filters to the Target table. Jinak řečeno: Modrá barva je použitá u produktů dvou kategorií, a proto se tyto kategorie použijí k filtrování cílů.In other words, because the color blue is used by products from two categories, those categories are used to filter the targets.

Abychom se tomuto chování vyhnuli (viz předchozí popis), doporučujeme k řízení sumarizace faktických dat používat míry.To avoid this behavior, as described earlier, we recommend you control the summarization of your fact data by using measures.

Představte si následující definicí míry.Consider the following measure definition. Všimněte si, že filtry testují všechny sloupce tabulky Product (Produkt) pod danou úrovní kategorie.Notice that all Product table columns that are beneath the category level are tested for filters.

Target Quantity =
IF(
    NOT ISFILTERED('Product'[ProductID])
        && NOT ISFILTERED('Product'[Product])
        && NOT ISFILTERED('Product'[Color]),
    SUM(Target[TargetQuantity])
)

V následujícím vizuálu tabulky teď použijeme míru Target Quantity (Cílové množství).The following table visual now uses the Target Quantity measure. U všech barev se zobrazí cílové množství BLANK.It shows that all color target quantities are BLANK.

Diagram znázorňující vizuál tabulky se dvěma sloupci: Color (Barva) a TargetQuantity (CílovéMnožství).

Konečný návrh modelu vypadá takto.The final model design looks like the following.

Diagram znázorňující model s tabulkami Date (Datum) a Target (Cíl) spojené relací 1:N

Pokyny ke spojování faktů vyšší úrovněRelate higher grain facts guidance

Pokud potřebujete tabulku typu dimenze připojit k tabulce typu fakta a v tabulce typu fakta jsou uložené řádky vyšší úrovně, než jsou řádky tabulky typu dimenze, přečtěte si následující pokyny:When you need to relate a dimension-type table to a fact-type table, and the fact-type table stores rows at a higher grain than the dimension-type table rows, we provide the following guidance:

  • Faktická data vyšší úrovně:For higher grain fact dates:
    • Do tabulky typu fakta uložte první datum časového období.In the fact-type table, store the first date of the time period
    • Mezi tabulkou kalendářních dat a tabulkou typu fakta vytvořte relaci 1:N.Create a one-to-many relationship between the date table and the fact-type table
  • Další faktická data vyšší úrovně:For other higher grain facts:
    • Mezi tabulkou typu dimenze a tabulkou typu fakta vytvořte relaci M:N.Create a many-to-many relationship between the dimension-type table and the fact-type table
  • Oba typy:For both types:
    • K řízení sumarizací použijte logiku měr. Pokud se k filtrování nebo seskupení používají sloupce typu dimenze, které jsou nižší úrovně, vrátí se hodnota BLANK.Control summarization with measure logic—return BLANK when lower-level dimension-type columns are used to filter or group
    • Skryjte souhrnné sloupce tabulky typu fakta, aby k sumarizaci této tabulky šly použít jenom míry.Hide summarizable fact-type table columns—this way, only measures can be used to summarize the fact-type table

Další krokyNext steps

Další informace související s tímto článkem najdete v následujících tématech:For more information related to this article, check out the following resources: