Forum Discussion
DimUserAccess Optimal Design
Hi Experts, I have designed the DimUserAccess dimension which consists of 26 columns, it could be fair to assume that it is wide table. Now, I have design quandry such as leave it as a single table or is it better to split it into two tables (DimUserAccess + UserAccessScope bridge table) and normalize. Please help me what approach would be in this scenerio. what are the pros and cons of each approach. Any other key considerations I should be mindful of. Thank a lot in advance.
The solution is about keeping the single wide table because your cardinality (1k–10k rows), DAX RLS pattern, SOX atomicity requirement, and Direct Lake fallback risk all point in the same direction. The bridge adds complexity with zero benefit at your current scale. Revisit only if scope types multiply significantly.
4 Replies
- oussamahaimoudMemorable Member
Can you share:
- What are the 26 columns? (or at least categorize them like : user identity attributes, permission flags, scope/hierarchy columns, date columns, etc.)
- What is this dimension used for? RLS enforcement? Reporting on access rights? Both?
- What is the cardinality? How many rows roughly, hundreds, thousands, millions?
- Is there a many-to-many relationship involved? For example, can one user have multiple scopes/roles, or is it strictly one row per user?
- What is your semantic model type? Import, DirectQuery, or Direct Lake?
- SamyAbdulFrequent Visitor
Thank you ,happy to share the details:
- Column categories (26 total)
- Identity (8): UserAccessKey, AccessGrantType, AccessSubjectType, UserPrincipalName, GroupObjectId, EmployeeId, DisplayName, PersonaRole
- Scope (6): AccessScopeType, PermittedSegmentCode, PermittedBranchRegionCode, PermittedSiteCode, PermittedBusinessUnitCode, SecurityTier
- Lifecycle flags (4): IsSOXUser, EffectiveFromDate, EffectiveToDate, IsActive
- Audit / Pipeline (8): ApprovalReference, SourceSystem, CreatedDateTime, CreatedBy, LastModifiedDateTime, LastModifiedBy, RecordHash, BatchId
- Purpose
Dual - RLS + CLS enforcement at the semantic model layer, plus SOX audit trail. DAX resolves the authenticated user via USERPRINCIPALNAME(), looks up active entitlements at query time, filters rows by scope (RLS) and columns by SecurityTier (CLS via OLS). Not a reporting dimension - lives in a restricted security workspace, never exposed to consumers.
- Cardinality
Low thousands - driven by active users × avg scope rows per user (typically 1–3). Estimated steady state 1k–10k rows. Well within CALCULATETABLE + IN safe range; TREATAS/INTERSECT documented as the upgrade path if that threshold is crossed.
- Many-to-many - yes, intentional
One user can have multiple rows - one per AccessScopeType they hold (e.g. SEGMENT + BRANCH_REGION simultaneously). Each DAX pattern independently filters its scope type from _activeEntitlements and the union governs total visibility. A normalised bridge table approach (DimUserAccess + UserAccessScope) is flagged as the Phase 1 option if scope combinations grow complex.
- Semantic model mode
Not locked in yet - DAX patterns are mode-agnostic. F32 dedicated capacity so Direct Lake is the target. Main thing to validate: Direct Lake → DirectQuery fallback behaviour under RLS, which needs explicit testing before go-live.
I appreciate your help alot.
- SamyAbdulFrequent Visitor
Thank you . Please find the details :
Column categories 26
Identity 8,scope 6 life cycle flags 4 and Audit and Pipeline 8
Purpose : Dual -RSL and CLS enforcement at semantic model layer plus SOX audit trail, DAX resolves the authenticated user by USERPRINCIPALNAME
Cardinality :Low thousands , estimated steady state 1k to 10k rows
Many to Many intentional one user can have multiple rows, one for AccessScopeType they hold
Semantic Model Mode : Not locked in yet. Thank again and I appreciate your help.
- oussamahaimoudMemorable Member
The solution is about keeping the single wide table because your cardinality (1k–10k rows), DAX RLS pattern, SOX atomicity requirement, and Direct Lake fallback risk all point in the same direction. The bridge adds complexity with zero benefit at your current scale. Revisit only if scope types multiply significantly.