Я хочу построить простую многомерную модель данных, используя схему звезд в реляционной базе данных (ROLAP). Для этого я создаю таблицу фактов и две таблицы измерений. Во-первых, я копирую данные из операционного источника и обрабатываю эти данные (некоторый упрощенный процесс ETL).Что может быть неправильным в этой многомерной модели?
В моей модели только два измерения: date
и status
. Мера: количество определенных статусов (на время).
время таблица измерения:
CREATE TABLE [dbo].[tbl_date_dim] (
[ID][int] IDENTITY(1,1) NOT NULL,
[date_key][int] NOT NULL primary key,
[Year][int] NOT NULL,
[Month][int] NOT NULL,
[Day][int] NOT NULL
);
Существует таблица - tbl_application
-, в которой хранится весь диапазон времени (поле VersionDate
). Таким образом, таблица измерения времени я заполняю этот путь:
INSERT INTO [dbo].[tbl_date_dim]
([date_key],
[Year],
[Month],
[Day])
(
SELECT DISTINCT
CAST(YEAR(VersionDate) as VARCHAR(4)) +
RIGHT('00' + CAST(MONTH(VersionDate) as VARCHAR(2)) ,2) +
RIGHT('00' + CAST(DAY(VersionDate) as VARCHAR(2)), 2) as 'date_key',
YEAR(inner_data.VersionDate) as 'Year',
MONTH(inner_data.VersionDate) as 'Month',
DAY(inner_data.VersionDate) as 'Day'
FROM (
SELECT
VersionDate
FROM [dbo].[tbl_application]
) AS inner_data
);
размерность таблицы состояния: Я использую всю существующую таблицу tbl_applicationstatus
.
Далее я создаю таблицу фактов. Он содержит внешние ключи к таблицам измерений и мерам.
CREATE TABLE [dbo].[tbl_olap_fact] (
[ID][int] IDENTITY(1,1) NOT NULL,
[status_id][int] NOT NULL, // FK
[date_dim][int] NOT NULL, // FK
[staus_name] varchar(100) NOT NULL, // Non additive measure
[transaction_id][int] NOT NULL, // Additive measure
CONSTRAINT [PK_tbl_olap_fact] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];
transaction_id
- это поле, которое я агрегировать (число состояний).
Далее я добавляю связь между таблицей фактов и размерами таблицами:
ALTER TABLE [dbo].[tbl_olap_fact] ADD CONSTRAINT [FK_tbl_olap_fact_tbl_date_dim] FOREIGN KEY([date_dim])
REFERENCES [dbo].[tbl_date_dim] ([date_key]);
ALTER TABLE [dbo].[tbl_olap_fact] ADD CONSTRAINT [FK_tbl_olap_fact_tbl_applicationstatus] FOREIGN KEY([status_id])
REFERENCES [dbo].[tbl_applicationstatus] ([ID]);
Затем я заполнить таблицу фактов:
INSERT INTO [dbo].[tbl_olap_fact]
([transaction_id],
[status_id],
[staus_name],
[date_dim])
(
SELECT DISTINCT
core.id as 'transaction_id',
core_status.ID as 'status_id',
core_status.name as 'status_name',
CAST(YEAR(core.VersionDate) as VARCHAR(4)) +
RIGHT('00' + CAST(MONTH(core.VersionDate) as VARCHAR(2)) ,2) +
RIGHT('00' + CAST(DAY(core.VersionDate) as VARCHAR(2)), 2) as 'date_dim'
FROM
[dbo].[tbl_application] as core
inner join tbl_applicationstatus as core_status
on core.ApplicationStatusID = core_status.ID
WHERE IsRaw = 0
);
В качестве сервера OLAP я использую Мондриан. Mondrian схема, которая определяет логическую модель многомерной базы данных:
<Schema name="olap_schema">
<Dimension type="TimeDimension" visible="true" highCardinality="false" name="Date first dim">
<Hierarchy name="date_hierarchy" visible="true" hasAll="true" primaryKey="date_key" description="">
<Table name="tbl_date_dim" schema="dbo">
</Table>
<Level name=""
visible="true"
table="tbl_date_dim"
column="Year"
nameColumn="Year"
type="Numeric"
uniqueMembers="true"
levelType="TimeYears"
hideMemberIf="Never"
description="">
</Level>
<Level name=""
visible="true"
table="tbl_date_dim"
column="Month"
nameColumn="Month"
ordinalColumn="Month"
type="Numeric"
uniqueMembers="false"
levelType="TimeMonths"
hideMemberIf="Never"
description="">
</Level>
<Level name=""
visible="true"
table="tbl_date_dim"
column="Day"
nameColumn="Day"
ordinalColumn="Day"
type="Numeric"
uniqueMembers="false"
levelType="TimeDays"
hideMemberIf="Never"
description="">
</Level>
</Hierarchy>
</Dimension>
<Dimension type="TimeDimension" visible="true" highCardinality="false" name="Date second dim">
<Hierarchy name="date_hierarchy" visible="true" hasAll="true" primaryKey="date_key" description="">
<Table name="tbl_date_dim" schema="dbo">
</Table>
<Level name=""
visible="true"
table="tbl_date_dim"
column="Year"
nameColumn="Year"
type="Numeric"
uniqueMembers="true"
levelType="TimeYears"
hideMemberIf="Never"
description="">
</Level>
<Level name=""
visible="true"
table="tbl_date_dim"
column="Month"
nameColumn="Month"
ordinalColumn="Month"
type="Numeric"
uniqueMembers="false"
levelType="TimeMonths"
hideMemberIf="Never"
description="">
</Level>
<Level name=""
visible="true"
table="tbl_date_dim"
column="Day"
nameColumn="Day"
ordinalColumn="Day"
type="Numeric"
uniqueMembers="false"
levelType="TimeDays"
hideMemberIf="Never"
description="">
</Level>
</Hierarchy>
</Dimension>
<Dimension type="StandardDimension" visible="true" highCardinality="false" name="Status dimension">
<Hierarchy name="status_hierarchy" visible="true" hasAll="true" primaryKey="ID" description="">
<Table name="tbl_applicationstatus" schema="dbo">
</Table>
<Level name=""
visible="true"
table="tbl_applicationstatus"
column="Name"
nameColumn="Name"
type="String"
uniqueMembers="true"
levelType="Regular"
hideMemberIf="Never"
description="">
</Level>
</Hierarchy>
</Dimension>
<Cube name="enrollment_cube" caption="" visible="true" description="" cache="true" enabled="true">
<Table name="tbl_olap_fact" schema="dbo">
</Table>
<DimensionUsage source="Date first dim" name="X axis" caption="" visible="true" foreignKey="date_dim" highCardinality="false">
</DimensionUsage>
<DimensionUsage source="Date second dim" name="Y axis" caption="" visible="true" foreignKey="date_dim" highCardinality="false">
</DimensionUsage>
<DimensionUsage source="Status dimension" name="Z axis" caption="" visible="true" foreignKey="status_id" highCardinality="false">
</DimensionUsage>
<Measure name="TotalCount" column="transaction_id" aggregator="count" caption="Total" visible="true">
</Measure>
</Cube>
</Schema>
В качестве клиента OLAP я использую Saiku Analytics.
В принципе, я получаю правильные данные - но не совсем уверен в этом. Например, правильно ли это используется для заполнения таблицы фактов? Я строю процесс ETL правильно? Это тестовый режим, и я делаю некоторые эксперименты в создании хранилищ данных и многомерных моделей.
Я был бы очень признателен за информацию. Спасибо всем.
Я дар речи! .. Большое спасибо за такой подробный ответ! Я буду внимательно изучать ... Спасибо, что поделились своим опытом! Это очень важно для меня. –