# Extender modelo

{% hint style="info" %}

#### Extender el esquema

A medida que maduran las necesidades analíticas de su organización, los usuarios de negocio inevitablemente solicitarán mejoras en su modelo de datos. Esta evolución es natural y esperada: lo que comienza como un cubo de análisis de ventas simple crecerá para acomodar preguntas comerciales más sofisticadas.&#x20;
{% endhint %}

<figure><img src="https://content.gitbook.com/content/VLCJbSi5xQoetAvNtGiu/blobs/Vmty6ucctesQCnu9u6Qb/image.png" alt=""><figcaption><p>Modelos en miniatura - Ampliados</p></figcaption></figure>

{% hint style="info" %}
La evolución del esquema se refiere al perfeccionamiento incremental de las definiciones de cubo de Mondrian para soportar nuevos requisitos analíticos sin interrumpir informes y análisis existentes. El principio clave es **compatibilidad con versiones anteriores -** las nuevas funciones deben mejorar en lugar de romper la funcionalidad existente.
{% endhint %}

***

#### Tabla de referencia rápida

| Tipo de evolución                                         | Usar cuando                          | Impacto en el rendimiento             | Complejidad |
| --------------------------------------------------------- | ------------------------------------ | ------------------------------------- | ----------- |
| [Cambiar título/formato](#change-caption-format)          | Mejorar la usabilidad                | Ninguno                               | Baja        |
| [Agregar jerarquía](#add-hierarchy)                       | Necesidad de navegación alternativa  | Mínimo                                | Media       |
| [Agregar nivel](#add-level)                               | Necesidad de más detalle/aggregación | Baja                                  | Bajo-Medio  |
| [Agregar medida (mismo grano)](#add-measure)              | Necesidad de métricas relacionadas   | Baja                                  | Baja        |
| [Agregar medida (grano distinto)](#add-different-measure) | Necesidad de métricas dimensionales  | Media                                 | Media       |
| [Columna calculada](#calculated-column)                   | Lógica compleja, uso frecuente       | Bajo (calculada una vez)              | Media       |
| [Miembro calculado](#add-cm-to-cube)                      | Ratios, comparaciones, fórmulas      | Medio (cálculo en tiempo de consulta) | Medio-Alto  |
| [Conjunto nombrado](#add-named-set)                       | Grupos reutilizables de miembros     | Mínimo                                | Bajo-Medio  |
| [Múltiples cubos](#multiple-cubes)                        | Casos de uso/seguridad separados     | Positivo (especialización)            | Media       |

{% tabs %}
{% tab title="Cambiar título / formato" %}
{% hint style="info" %}

#### Cambiar el título, la descripción o la cadena de formato de cualquier elemento

**Qué hace:** Modifica cómo aparecen los elementos a los usuarios sin cambiar la estructura de datos subyacente ni la lógica de consultas.

**Por qué importa:** La terminología empresarial evoluciona y su esquema debe reflejar el lenguaje actual. Además, un formato adecuado asegura que los datos se presenten de manera profesional y consistente.
{% endhint %}

**Ejemplo - Estado actual:**

```xml
<Measure name="Sales" 
         aggregator="sum" 
         column="TOTALPRICE"
         formatString="$#,###.00"
         datatype="Numeric"/>
```

**Escenarios de evolución:**

**Escenario A - Actualizar el título para mayor claridad:**

```xml
<Measure name="Sales" 
         caption="Ingresos totales por ventas"
         aggregator="sum" 
         column="TOTALPRICE"
         formatString="$#,###.00"
         datatype="Numeric"/>
```

*Impacto en el negocio:* Los usuarios ahora ven "Ingresos totales por ventas" en Analyzer, lo que aclara que esto representa ingresos brutos, no beneficios.

***

**Escenario B - Cambiar la cadena de formato para moneda internacional:**

```xml
<Measure name="Sales" 
         caption="Ingresos totales por ventas"
         aggregator="sum" 
         column="TOTALPRICE"
         formatString="€#,##0.00;(€#,##0.00)"
         datatype="Numeric"/>
```

*Impacto en el negocio:* Los ingresos ahora se muestran en euros con el formato correcto para números negativos entre paréntesis.

***

**Escenario C - Agregar descripción para documentación:**

```xml
<Measure name="Sales" 
         caption="Ingresos totales por ventas"
         description="Suma de todos los totales de líneas de pedido antes de impuestos y envío. Incluye descuentos aplicados a nivel de pedido."
         aggregator="sum" 
         column="TOTALPRICE"
         formatString="$#,###.00"
         datatype="Numeric"/>
```

*Impacto en el negocio:* Los usuarios que pasan el cursor sobre la medida en Analyzer ven una sugerencia que explica exactamente qué representa esta medida.
{% endtab %}

{% tab title="Agregar jerarquía" %}
{% hint style="info" %}

#### Agregar una jerarquía a una dimensión

**Qué hace:** Proporciona rutas de navegación alternativas a través de la misma dimensión, soportando diferentes perspectivas analíticas.

**Por qué importa:** Diferentes usuarios de negocio necesitan analizar la misma dimensión de formas distintas. Varias jerarquías permiten flexibilidad sin crear dimensiones separadas.

**Ejemplo - Estado actual:** La dimensión Productos tiene una jerarquía: Línea → Proveedor → Nombre del producto
{% endhint %}

**Evolución:** Agregar una segunda jerarquía basada en categorías de producto:

```xml
<Dimension name="PRODUCTS" foreignKey="PRODUCTCODE">
    
    <!-- Jerarquía original -->
    <Hierarchy name="Por proveedor" 
               hasAll="true" 
               allMemberName="Todos los productos"
               primaryKey="PRODUCTCODE">
        <Table name="PRODUCTS" schema="PUBLIC"/>
        <Level name="Línea" column="PRODUCTLINE" type="String"/>
        <Level name="Proveedor" column="PRODUCTVENDOR" type="String"/>
        <Level name="Nombre del producto" column="PRODUCTNAME" type="String"/>
    </Hierarchy>
    
    <!-- Nueva jerarquía -->
    <Hierarchy name="Por categoría" 
               hasAll="true" 
               allMemberName="Todos los productos"
               primaryKey="PRODUCTCODE">
        <Table name="PRODUCTS" schema="PUBLIC"/>
        <Level name="Categoría" column="PRODUCTCATEGORY" type="String"/>
        <Level name="Subcategoría" column="PRODUCTSUBCATEGORY" type="String"/>
        <Level name="Nombre del producto" column="PRODUCTNAME" type="String"/>
    </Hierarchy>
    
</Dimension>
```

{% hint style="info" %}
**Caso de uso empresarial:**

* El departamento de marketing analiza por Categoría → Subcategoría (clasificación orientada al mercado)
* El departamento de operaciones analiza por Línea → Proveedor (clasificación de la cadena de suministro)
* Ambos equipos usan el mismo cubo con diferentes rutas de navegación
* Los usuarios seleccionan su jerarquía preferida en Analyzer sin necesidad de fuentes de datos separadas
  {% endhint %}
  {% endtab %}

{% tab title="Agregar nivel" %}
{% hint style="info" %}

#### Agregar un nivel a una jerarquía

**Qué hace:** Aumenta la granularidad o añade puntos intermedios de agregación en una jerarquía existente.

**Por qué importa:** A medida que maduran los requisitos de informes, los usuarios necesitan capacidades de desglose más detalladas o niveles intermedios de resumen.

**Ejemplo - Estado actual:** La dimensión Clientes tiene: Nombre del cliente (nivel único)
{% endhint %}

**Escenario de evolución A - Agregar niveles geográficos:**

```xml
<Hierarchy name="Customers" 
           hasAll="true" 
           allMemberName="Todos los clientes"
           primaryKey="CUSTOMERNUMBER">
    <Table name="CUSTOMERS" schema="PUBLIC"/>
    
    <!-- Nuevos niveles -->
    <Level name="País" 
           column="COUNTRY" 
           type="String" 
           uniqueMembers="true"/>
    
    <Level name="Estado/Provincia" 
           column="STATE" 
           type="String" 
           uniqueMembers="false"/>
    
    <Level name="Ciudad" 
           column="CITY" 
           type="String" 
           uniqueMembers="false"/>
    
    <Level name="Nombre del cliente" 
           column="CUSTOMERNAME" 
           type="String" 
           uniqueMembers="false"/>
</Hierarchy>
```

**Caso de uso empresarial:**

* **Antes:** Los usuarios solo podían ver ventas por cliente individual (demasiado detallado para ejecutivos)
* **Después:** Los ejecutivos pueden ver ventas por País, los gerentes regionales por Estado/Provincia y los representantes de ventas por Ciudad, con la capacidad de profundizar hasta clientes específicos
* Soporta análisis de mercado geográfico sin crear dimensiones separadas

***

**Escenario de evolución B - Agregar segmentación de clientes:**

```xml
<Level name="Segmento de cliente" 
       column="CUSTOMERSEGMENT" 
       type="String" 
       uniqueMembers="true"
       levelType="Regular">
    <!-- Agregar antes del nivel Nombre del cliente -->
</Level>
```

**Caso de uso empresarial:**

* Segmenta a los clientes como "Empresa", "Mediana empresa", "Pequeña empresa"
* Permite el análisis: "¿Cuál es nuestro tamaño de acuerdo promedio por segmento de cliente?"
* La dirección de ventas puede comparar el rendimiento entre diferentes segmentos de mercado
  {% endtab %}

{% tab title="Agregar medida" %}
{% hint style="info" %}

#### Agregar una medida que tenga la misma granularidad o dimensionalidad que las medidas existentes

**Qué hace:** Añade nuevas métricas que pueden analizarse al mismo nivel dimensional que las medidas existentes.

**Por qué importa:** Las necesidades del negocio se expanden para incluir nuevos KPI sin requerir cambios en la estructura dimensional.

**Ejemplo - Estado actual:** Medida única: Ventas (suma de TOTALPRICE)
{% endhint %}

**Evolución - Agregar métricas de ventas complementarias:**

```xml
<!-- Medida existente -->
<Measure name="Sales" 
         aggregator="sum" 
         column="TOTALPRICE"
         formatString="$#,###.00"/>

<!-- Nuevas medidas con la misma granularidad -->
<Measure name="Quantity Sold" 
         caption="Unidades vendidas"
         aggregator="sum" 
         column="QUANTITYORDERED"
         formatString="#,###"
         datatype="Integer"/>

<Measure name="Order Count" 
         caption="Número de pedidos"
         aggregator="count" 
         column="ORDERNUMBER"
         formatString="#,###"
         datatype="Integer"/>

<Measure name="Discount Amount" 
         caption="Total descuentos"
         aggregator="sum" 
         column="DISCOUNT"
         formatString="$#,###.00"
         datatype="Numeric"/>

<Measure name="Cost of Goods Sold" 
         caption="COGS"
         aggregator="sum" 
         column="BUYPRICE"
         formatString="$#,###.00"
         datatype="Numeric"/>
```

**Caso de uso empresarial:** Todas estas medidas comparten la misma dimensionalidad: todas pueden analizarse por:

* Línea de producto
* Territorio
* Cliente
* Periodo de tiempo

**Ejemplo de análisis:** "Muéstrame Ventas, Unidades Vendidas y Precio Medio por Unidad por Línea de Producto y Territorio"

* Ventas por Territorio y Línea: $X
* Unidades vendidas por Territorio y Línea: Y
* Precio medio por unidad: $X / Y
* Las tres métricas se alinean perfectamente en los mismos ejes dimensionales
  {% endtab %}

{% tab title="Agregar medida diferente" %}
{% hint style="info" %}

#### Agregar una medida de granularidad o dimensionalidad diferente a las medidas existentes

**Qué hace:** Introduce métricas que existen en niveles dimensionales distintos a su tabla de hechos, requiriendo un manejo especial para la agregación.

**Por qué importa:** Algunas métricas de negocio no existen a nivel transaccional. Niveles de inventario, recuentos de empleados y límites de crédito de clientes son atributos dimensionales, no hechos de transacción.

**Ejemplo - Estado actual:** Todas las medidas están en el grano ORDER\_DETAILS (una fila por producto por pedido)
{% endhint %}

**Evolución - Agregar medidas en diferentes granularidades:**

**Escenario A - Medida a nivel de cliente:**

```xml
<Measure name="Customer Credit Limit" 
         caption="Límite de crédito"
         aggregator="max" 
         column="CREDITLIMIT"
         formatString="$#,###.00"
         datatype="Numeric"/>
```

**¿Por qué el agregador "max"?**

* El límite de crédito se almacena una vez por cliente en la tabla de dimensión CUSTOMERS
* Al agregar sobre varios clientes, queremos el límite de crédito máximo en ese grupo
* Esto evita el doble conteo cuando un cliente tiene múltiples pedidos

**Caso de uso empresarial:** "Muéstrame ventas totales frente a crédito disponible por segmento de cliente"

* Las ventas se agregan de forma natural (suma de todos los pedidos)
* Los límites de crédito usan "max" para mostrar el límite más alto en cada segmento sin doble conteo

***

**Escenario B - Medida a nivel de producto:**

```xml
<Measure name="Product Unit Cost" 
         caption="Costo estándar del producto"
         aggregator="avg" 
         column="BUYPRICE"
         formatString="$#,###.00"
         datatype="Numeric"/>
```

**Caso de uso empresarial:** "¿Cuál es el costo promedio del producto por proveedor?"

* Cada producto tiene un costo estándar
* El agregador "avg" proporciona el costo promedio entre productos para cada proveedor
* Diferente del COGS total, que suma los costos reales de las transacciones
  {% endtab %}

{% tab title="Columna calculada" %}
{% hint style="info" %}

#### Crear una columna calculada y usarla en un atributo o medida

**Qué hace:** Define columnas derivadas a nivel de base de datos o ETL, luego las expone en su esquema como dimensiones o medidas.

**Por qué importa:** No toda la lógica de negocio debería estar en cálculos MDX. Algunas transformaciones es mejor realizarlas una vez durante el ETL en lugar de repetidamente en tiempo de consulta.
{% endhint %}

**Columna calculada en la base de datos (creada en su ETL o vista de base de datos):**

```sql
CREATE VIEW ORDER_DETAILS_ENHANCED AS
SELECT 
    *,
    TOTALPRICE - (QUANTITYORDERED * BUYPRICE) AS PROFIT,
    CASE 
        WHEN TOTALPRICE - (QUANTITYORDERED * BUYPRICE) < 0 THEN 'Pérdida'
        WHEN TOTALPRICE - (QUANTITYORDERED * BUYPRICE) < 100 THEN 'Margen bajo'
        WHEN TOTALPRICE - (QUANTITYORDERED * BUYPRICE) < 500 THEN 'Margen medio'
        ELSE 'Margen alto'
    END AS PROFITABILITY_TIER
FROM ORDER_DETAILS;
```

**Usar la columna calculada en una medida:**

```xml
<Measure name="Profit" 
         caption="Beneficio bruto"
         aggregator="sum" 
         column="PROFIT"
         formatString="$#,###.00"
         datatype="Numeric"/>
```

**Usar la columna calculada en una dimensión:**

```xml
<Dimension name="PROFITABILITY" foreignKey="ORDERDETAILID">
    <Hierarchy name="Rentabilidad" 
               hasAll="true" 
               allMemberName="Todas las transacciones"
               primaryKey="ORDERDETAILID">
        <Table name="ORDER_DETAILS_ENHANCED" schema="PUBLIC"/>
        <Level name="Nivel de rentabilidad" 
               column="PROFITABILITY_TIER" 
               type="String"/>
    </Hierarchy>
</Dimension>
```

**Caso de uso empresarial:** "Muéstrame ventas y margen de beneficio por nivel de rentabilidad y línea de producto"

* El cálculo del beneficio ocurre una vez en la base de datos
* Mucho más rápido que calcular (Ventas - Coste) en MDX para cada consulta
* El nivel de rentabilidad permite a los usuarios filtrar y agrupar por rendimiento de beneficios
* Reduce la complejidad de las consultas y mejora el rendimiento

**Beneficio en el rendimiento:**

* Antes: MDX calcula el beneficio para cada celda en cada consulta
* Después: la base de datos calcula una vez; Mondrian solo agrega los valores pre-calculados
  {% endtab %}

{% tab title="Agregar MC al cubo" %}
{% hint style="info" %}

#### Agregar un miembro calculado a un cubo

**Qué hace:** Define fórmulas que combinan medidas existentes para crear nuevas métricas, calculadas en tiempo de consulta.

**Por qué importa:** Muchas métricas comerciales son ratios, porcentajes o fórmulas complejas que no se pueden simplemente sumar o promediar. Los miembros calculados gestionan esta lógica de negocio en MDX.
{% endhint %}

```xml
<CalculatedMember name="Profit Margin %" 
                  dimension="Measures"
                  formula="([Measures].[Profit] / [Measures].[Sales]) * 100"
                  formatString="#,##0.00'%'">
    <CalculatedMemberProperty name="FORMAT_STRING" value="#,##0.00'%'"/>
</CalculatedMember>

<CalculatedMember name="Average Order Value" 
                  dimension="Measures"
                  formula="[Measures].[Sales] / [Measures].[Order Count]"
                  formatString="$#,###.00">
</CalculatedMember>

<CalculatedMember name="Units Per Order" 
                  dimension="Measures"
                  formula="[Measures].[Quantity Sold] / [Measures].[Order Count]"
                  formatString="#,##0.0">
</CalculatedMember>

<CalculatedMember name="Sales Growth vs Prior Year" 
                  dimension="Measures">
    <Formula>
        <![CDATA[
        ([Measures].[Sales] - ([Measures].[Sales], ParallelPeriod([Time].[Year], 1))) /
        ([Measures].[Sales], ParallelPeriod([Time].[Year], 1)) * 100
        ]]>
    </Formula>
    <CalculatedMemberProperty name="FORMAT_STRING" value="#,##0.0'%'"/>
</CalculatedMember>
```

**Casos de uso empresarial:**

**Margen de beneficio %**

* "¿Qué líneas de producto tienen los márgenes de beneficio más altos?"
* "¿Cómo varía el margen de beneficio por segmento de cliente?"
* No se puede calcular como un promedio: debe ser (Beneficio total / Ventas totales) en cada nivel de agregación

**Valor medio del pedido**

* "¿Cuál es el valor medio del pedido por territorio?"
* "¿Está aumentando nuestro tamaño medio de pedido con el tiempo?"
* Diferente de sumar los valores de los pedidos: requiere dividir las ventas totales por el número de pedidos

**Crecimiento de ventas respecto al año anterior**

* "¿Qué territorios están creciendo más rápido año tras año?"
* "¿Cuál es nuestra tasa de crecimiento compuesta?"
* Utiliza la inteligencia temporal MDX para comparar el periodo actual con el mismo periodo del año anterior

**Diferencia clave respecto a las medidas regulares:**

* Las medidas regulares se agregan mediante SUM, COUNT, AVG, etc.
* Los miembros calculados usan fórmulas que operan sobre valores agregados
* Ejemplo: el margen de beneficio debe calcularse DESPUÉS de agregar beneficio y ventas, no antes
  {% endtab %}

{% tab title="Agregar conjunto nombrado" %}
{% hint style="info" %}

#### Agregar un conjunto nombrado a un cubo

**Qué hace:** Define colecciones predefinidas y reutilizables de miembros de dimensión que los usuarios pueden aplicar de forma consistente en los análisis.

**Por qué importa:** Los usuarios de negocio analizan repetidamente los mismos grupos significativos. Los conjuntos nombrados proporcionan consistencia, mejoran la usabilidad y encapsulan lógica MDX compleja.
{% endhint %}

**Ejemplo:**

```xml
<!-- Top 10 Products by Sales -->
<NamedSet name="Top 10 Products">
    <Formula>
        <![CDATA[
        TopCount([PRODUCTS].[By Vendor].[Product Name].Members, 10, [Measures].[Sales])
        ]]>
    </Formula>
</NamedSet>

<!-- Territorios clave (mercados de altos ingresos) -->
<NamedSet name="Strategic Territories">
    <Formula>
        <![CDATA[
        {
            [TERRITORY].[Geographic].[Territory].[EMEA North],
            [TERRITORY].[Geographic].[Territory].[NA East],
            [TERRITORY].[Geographic].[Territory].[NA West],
            [TERRITORY].[Geographic].[Territory].[APAC Central]
        }
        ]]>
    </Formula>
</NamedSet>

<!-- Año actual y anterior para tendencias -->
<NamedSet name="Current and Prior Year">
    <Formula>
        <![CDATA[
        {
            [Time].[Calendar].[Year].CurrentMember,
            [Time].[Calendar].[Year].CurrentMember.Lag(1)
        }
        ]]>
    </Formula>
</NamedSet>

<!-- Clientes de alto valor (>$100K gasto anual) -->
<NamedSet name="High Value Customers" dynamic="true">
    <Formula>
        <![CDATA[
        Filter(
            [CUSTOMERS].[Geographic].[Customer Name].Members,
            [Measures].[Sales] > 100000
        )
        ]]>
    </Formula>
</NamedSet>
```

**Casos de uso empresarial:**

**Top 10 Products**

* Los usuarios pueden analizar de forma consistente los mismos productos de mejor rendimiento
* La definición está centralizada: si el negocio decide que "Top 10" significa Top 15, cámbielo una vez
* Aparece como una opción de filtro preconfigurada en Analyzer

**Territorios estratégicos**

* La dirección de ventas quiere centrar los informes en mercados clave
* En lugar de seleccionar manualmente los territorios cada vez, use el conjunto nombrado
* Garantiza consistencia entre informes y paneles

**Año actual y anterior**

* Cada informe de tendencias necesita esta comparación
* El conjunto nombrado encapsula la lógica MDX para acceder a periodos actuales y anteriores
* Los usuarios no necesitan entender MDX para crear comparaciones año tras año

**Clientes de alto valor (dinámico)**

* El filtro se actualiza automáticamente en función de los datos actuales
* "dynamic=true" significa que el conjunto se recalcula en cada consulta
* Diferentes clientes pueden calificar cada trimestre a medida que cambian los patrones de gasto

**Conjuntos nombrados vs miembros calculados:**

* Los miembros calculados crean nuevas medidas
* Los conjuntos nombrados crean grupos predefinidos de miembros de dimensión
* Ambos mejoran la usabilidad al encapsular la complejidad
  {% endtab %}

{% tab title=" Múltiples cubos" %}
{% hint style="info" %}

#### Múltiples cubos en un esquema

A medida que madura su entorno analítico, descubrirá que diferentes grupos de negocio necesitan perspectivas distintas de sus datos:

* **Cubo de análisis de ventas:** Optmizado para informes diarios de ventas (grano a nivel de pedido)
* **Cubo de analítica de clientes:** Enfocado en el comportamiento del cliente (grano a nivel de cliente con métricas de vida útil)
* **Cubo de gestión de inventarios:** Niveles y movimientos de stock (grano producto/almacén/día)
* **Cubo de informes financieros:** Métricas financieras mensuales (grano a nivel de mes con cuentas del libro mayor)
  {% endhint %}

{% hint style="info" %}

#### **Beneficios clave:**

1. **Optimización del rendimiento**
   * Cada cubo optimizado para patrones de consulta específicos
   * Agregaciones apropiadas para cada caso de uso
   * Cubos más pequeños y enfocados consultan más rápido que un cubo masivo
2. **Seguridad y gobernanza**
   * Conceder al equipo de ventas acceso solo al cubo de análisis de ventas
   * El equipo de finanzas accede al cubo de informes financieros
   * Prevenir la contaminación cruzada de datos sensibles
3. **Diferente granularidad**
   * Cubos de transacciones: detalle de línea de pedido
   * Cubos resumen: instantáneas diarias o mensuales
   * Cubos especializados: rentabilidad por producto, valor de vida del cliente
4. **Experiencia de usuario simplificada**
   * Los usuarios ven solo dimensiones y medidas relevantes
   * Menos abrumador que un cubo con 50 dimensiones
   * Adaptado a flujos de trabajo analíticos específicos
     {% endhint %}

**Ejemplo - Múltiples cubos en el esquema MiniatureModels:**

```xml
<Schema name="MiniatureModels">
    
    <!-- Cubo de transacciones de ventas original -->
    <Cube name="Sales" visible="true">
        <Table name="ORDER_DETAILS" schema="PUBLIC"/>
        <!-- Dimensiones: Territorio, Productos, Clientes, Tiempo -->
        <!-- Medidas: Ventas, Cantidad, Número de pedidos -->
    </Cube>
    
    <!-- Nuevo cubo de analítica de clientes -->
    <Cube name="Customer Analytics" visible="true">
        <Table name="CUSTOMER_SUMMARY" schema="PUBLIC"/>
        <Dimension name="CUSTOMERS" foreignKey="CUSTOMERNUMBER">
            <!-- Jerarquía de clientes con segmentos -->
        </Dimension>
        <Measure name="Lifetime Value" aggregator="sum" column="TOTAL_LTV"/>
        <Measure name="Customer Tenure Days" aggregator="avg" column="TENURE_DAYS"/>
        <Measure name="Number of Customers" aggregator="count" column="CUSTOMERNUMBER"/>
    </Cube>
    
    <!-- Nuevo cubo de rendimiento de producto -->
    <Cube name="Product Performance" visible="true">
        <Table name="PRODUCT_METRICS" schema="PUBLIC"/>
        <Dimension name="PRODUCTS" foreignKey="PRODUCTCODE">
            <!-- Jerarquía de producto -->
        </Dimension>
        <Measure name="Inventory Turns" aggregator="avg" column="INVENTORY_TURNOVER"/>
        <Measure name="Days in Stock" aggregator="avg" column="DAYS_INVENTORY"/>
        <Measure name="Sell-Through Rate" aggregator="avg" column="SELLTHROUGH_PCT"/>
    </Cube>
    
</Schema>
```

**Asignación de usuarios:**

* Representantes de ventas → Cubo de ventas
* Equipo de éxito del cliente → Cubo de analítica de clientes
* Gerentes de producto → Cubo de rendimiento de producto
* Ejecutivos → Todos los cubos (para paneles comprensivos)
  {% endtab %}
  {% endtabs %}
