Data analysis and data mining: OLAP, star schema, association rules
OLTP vs OLAP, the data warehouse and star schema, cube operations and ROLLUP/CUBE, then data mining: support/confidence/lift, Apriori, information gain in decision trees and k-means. Concept and small calculation questions in the final come from here.
The last topic of the semester is seeing the database not as a “system that keeps records” but as a “system that helps make decisions”. It has two parts. The first is the data warehouse and OLAP: summarizing large data along different dimensions. The second is data mining: finding patterns in data that a human eye could not find. In the final exam this topic usually brings concept questions and small calculations: compute support and confidence, how many rows ROLLUP produces, what the entropy is, one iteration of k-means. What you need to know:
- OLTP does the daily work, OLAP does the analysis. That is why their designs differ.
- Star schema: a fact table in the middle, dimension tables around it.
- ROLLUP produces and CUBE produces grouping sets.
- Confidence is not symmetric. Lift tells how much better the rule is than independence.
- Classification has labels, clustering does not.
OLTP, OLAP and the data warehouse
The university database we have built so far was an OLTP (online transaction processing) system. A student registers for a course, a grade is entered, credits are updated. Each transaction touches a few rows, hundreds happen per second, and normalized tables (weeks 9-11) prevent update anomalies.
The question of the rector’s office is different: “How has each department’s average performance changed each semester over the last five years?” This is an OLAP (online analytical processing) query. It reads millions of rows, groups and sums them. It updates nothing.
| OLTP | OLAP | |
|---|---|---|
| Purpose | daily operation | analysis, decision support |
| Query | short, a few rows, very many | long, millions of rows, few |
| Operations | INSERT, UPDATE, DELETE | mostly SELECT and aggregation |
| Data | current | historical (past years) |
| Design | normalized (3NF/BCNF) | denormalized, star schema |
A data warehouse is a store where data from different sources is collected in a single schema, over a long period, in a form suitable for analysis. Data is moved from the sources to the warehouse with ETL: extract, transform (bring units, codes and names to a single form, clean dirty data), load. The warehouse is usually updated in nightly batches.
Star schema
As an example, let us analyze the sales of campus cafeterias. The measures of a sale event are quantity and amount. The context that describes this event is the dimensions: which item, which cafeteria, which month.
dim_item(item_id, item_name, category)
|
dim_date(date_id, month) -- fact_sales(date_id, store_id, item_id, qty, amount) -- dim_store(store_id, campus)
(The lines in the middle are foreign key links.) Dimension tables: dim_item = {1 Tost Food, 2 Simit Food, 3 Cay Drink, 4 Kahve Drink}, dim_store = {K1 Galata, K2 Rumeli}, dim_date = {1 Sep, 2 Oct}. The fact table:
| date_id | store_id | item_id | qty | amount |
|---|---|---|---|---|
| 1 | K1 | 1 | 10 | 600 |
| 1 | K1 | 3 | 40 | 400 |
| 1 | K2 | 2 | 30 | 450 |
| 1 | K2 | 4 | 10 | 500 |
| 2 | K1 | 1 | 20 | 1200 |
| 2 | K1 | 4 | 20 | 1000 |
| 2 | K2 | 3 | 50 | 500 |
| 2 | K2 | 2 | 10 | 150 |
In a star schema, each dimension is a single table and is not normalized: the category name repeats inside dim_item. In a snowflake schema, dimensions are normalized too; for example, the category moves into a separate dim_category table. A snowflake saves space, but adds extra joins to queries.
PITFALL · the fact table is not small. Students often write “dimension tables are large, the fact table is small”. The opposite is true. Every sale is a fact row, and they reach millions. The number of products or stores, on the other hand, is limited.
Data cube and OLAP operations
If you think of three dimensions (item category, campus, month) as axes, the sales settle in the cells of a cube. This is called a data cube. Each cell is the total for one combination. When you add an “all” (ALL) value to each dimension, three dimensions with two values each give cells.
| Operation | What it does | Cafeteria example | Result |
|---|---|---|---|
| Slice | fixes one dimension to a single value | only October, by campus | Galata 2200, Rumeli 650 |
| Dice | selects a sub-cube on several dimensions | Galata and Food, by month | Sep 600, Oct 1200 |
| Roll-up | summarizes to a coarser level | item → category → all | Drink 2400, Food 2400 |
| Drill-down | goes down to a finer level | from the Drink category to items | Cay 900, Kahve 1500 |
| Pivot | rotates the axes | campus in rows, month in columns | the table below |
Pivot result (amount):
| campus | Sep | Oct |
|---|---|---|
| Galata | 1000 | 2200 |
| Rumeli | 950 | 650 |
A pivot is written in SQL with CASE: SUM(CASE WHEN month = 'Sep' THEN amount END) AS Sep.
ROLLUP, CUBE and GROUPING SETS
In standard SQL (after SQL:1999) there are GROUP BY extensions to get several grouping levels in one query:
SELECT campus, category, SUM(amount) AS total
FROM fact_sales f JOIN dim_item i USING (item_id) JOIN dim_store s USING (store_id)
GROUP BY ROLLUP (campus, category);
ROLLUP(campus, category) is the union of these three grouping sets: (campus, category), (campus), (). The aggregated column appears as NULL in the result:
| campus | category | total |
|---|---|---|
| Galata | Drink | 1400 |
| Galata | Food | 1800 |
| Rumeli | Drink | 1000 |
| Rumeli | Food | 600 |
| Galata | NULL | 3200 |
| Rumeli | NULL | 1600 |
| NULL | NULL | 4800 |
CUBE(campus, category) is all four sets: (category) is added to those of ROLLUP, and two more rows come: (NULL, Drink, 2400) and (NULL, Food, 2400). A total of 9 rows. General rule: for attributes, ROLLUP produces and CUBE produces sets. With a form like GROUPING SETS ((campus), (category)) you can also choose the sets you want by hand.
SQLite does not support these extensions. If you write GROUP BY ROLLUP(campus), you get the error “no such function: ROLLUP”. We produce the same result with UNION ALL:
SELECT campus, category, SUM(amount) FROM ... GROUP BY campus, category
UNION ALL
SELECT campus, NULL, SUM(amount) FROM ... GROUP BY campus
UNION ALL
SELECT NULL, NULL, SUM(amount) FROM ...;
PITFALL · NULL can mean two things. The NULL in a ROLLUP row means “aggregated over this column”. But if there is a real NULL category in the data, the two get mixed. Standard SQL provides the
GROUPING(category)function for this: it returns 1 in a total row and 0 in a normal row.
Data mining: association rules
Data mining is the automatic discovery of useful and unexpected patterns in large data. The main tasks are association rules, classification, clustering, regression and outlier detection.
An association rule has the form “whoever buys X also buys Y”: . 8 receipts from the cafeteria:
| Transaction | Items |
|---|---|
| T1 | cay, simit |
| T2 | cay, simit, tost |
| T3 | kahve, tost |
| T4 | cay, simit |
| T5 | kahve, su |
| T6 | cay, tost |
| T7 | cay, simit, su |
| T8 | kahve, tost |
Three measures:
| Rule | supp(X ∪ Y) | conf | lift |
|---|---|---|---|
| cay ⇒ simit | 4/8 = 0.5 | 4/5 = 0.8 | 0.8 / 0.5 = 1.6 |
| simit ⇒ cay | 0.5 | 4/4 = 1.0 | 1.0 / 0.625 = 1.6 |
| kahve ⇒ tost | 2/8 = 0.25 | 2/3 = 0.667 | 0.667 / 0.5 = 1.333 |
| tost ⇒ cay | 2/8 = 0.25 | 2/4 = 0.5 | 0.5 / 0.625 = 0.8 |
| {cay, simit} ⇒ tost | 1/8 | 1/4 = 0.25 | 0.25 / 0.5 = 0.5 |
Support is symmetric, confidence is not. Lift is symmetric again: . If lift > 1, X increases the probability of Y. If lift < 1, it decreases it: a customer who buys tost buys less cay than average.
Apriori
Counting all item combinations is exponentially expensive. Apriori is based on this principle: every subset of a frequent set is also frequent. Conversely: a candidate with an infrequent subset is dropped without needing to be counted. With a minimum support count of 2:
C1 counts : cay 5, kahve 3, simit 4, su 2, tost 4 → L1 = all
C2 counts : cay+kahve 0, cay+simit 4, cay+su 1, cay+tost 2, kahve+simit 0,
kahve+su 1, kahve+tost 2, simit+su 1, simit+tost 1, su+tost 0
L2 : {cay,simit}:4, {cay,tost}:2, {kahve,tost}:2
C3 candidate: {cay,simit,tost} → {simit,tost} infrequent, PRUNED
{cay,kahve,tost} → {cay,kahve} infrequent, PRUNED
C3 empty → stop
Rules are generated from frequent sets and filtered with a minimum confidence threshold. For example, with a threshold of 0.75, from the set {cay, simit} both cay ⇒ simit (0.8) and simit ⇒ cay (1.0) pass.
Classification and decision trees
Classification is learning a model from training data with known labels (supervised learning) and predicting the class of a new record: “Will this student pass the course?” A decision tree splits the data at each node on an attribute. Which attribute to choose is decided with entropy:
In a training set of 10 students, 5 passed and 5 failed: (the most mixed case). Of the 5 with attendance ‘yes’, 4 passed, and of the 5 with ‘no’, 1 passed. The entropy of each branch is , and the gain is . In this data the study time (high/low) gives the same 4-to-1 and 1-to-4 distribution, so its gain is also 0.278. In a tie, either can be chosen. For another comparison: the entropy of a node with 3 passed and 1 failed is 0.811, and that of 2 to 2 is 1. A pure (single-class) node has entropy 0, and the tree makes a leaf there.
Clustering and k-means
Clustering groups similar records without labels (unsupervised). The best-known algorithm is k-means:
- Choose k centroids.
- Assign each point to the nearest centroid.
- Move each centroid to the mean of its own cluster.
- Repeat 2 and 3 until the assignments stop changing.
Points A(1,2), B(2,1), C(2,3), D(8,8), E(9,7), F(7,9), k = 2, initial centroids c1 = (1,2), c2 = (2,3):
iter 1: A→c1 (d²: 0 / 2) B→c1 (2 / 4) C→c2 (2 / 0) D,E,F→c2
c1 = (1.5, 1.5) c2 = ((2+8+9+7)/4, (3+8+7+9)/4) = (6.5, 6.75)
iter 2: d² for C: 2.5 to c1, 34.3125 to c2 → C moves to c1
c1 = (1.67, 2) c2 = (8, 8)
iter 3: no assignment changed → stop. SSE = 2.667 + 4 = 6.667
The k-means result depends on the initial centroids. A bad start can take longer or get stuck in a bad local minimum. In practice the algorithm is run several times with different starts, and the result with the smallest SSE is chosen.
Common mistakes
| Wrong idea | The truth |
|---|---|
| A data warehouse is also designed in 3NF | A denormalized star schema is preferred for analysis |
| The fact table is small, the dimensions are large | The fact table is the largest table |
| ROLLUP and CUBE give the same rows | ROLLUP is sets, CUBE is . CUBE also gives the extra (category) totals |
| conf(X ⇒ Y) = conf(Y ⇒ X) | Not so: cay ⇒ simit is 0.8, simit ⇒ cay is 1.0 |
| High confidence = a good rule | If Y is already very common, lift can be near or below 1 |
| Apriori counts every candidate in the data | A candidate with an infrequent subset is pruned without counting |
| Clustering needs labeled data | Labels are needed in classification, clustering is unsupervised |
| k-means always gives the same result | It depends on the initial centroids |
GROUP BY ROLLUP works in SQLite | It does not, imitate it with UNION ALL |
Test yourself
Exam-style questions. Solve them on paper first, then reveal the answer.
Which kind of workload is characterized by many short transactions that insert and update a few rows each, such as course registration?
- OLAP
- OLTP
- Data mining
- ETL
Show answer
OLTP (online transaction processing) is the daily operational work: short, frequent INSERTs/UPDATEs that touch a few rows. OLAP (online analytical processing) is a small number of very large, mostly read-only summary queries, such as 'average grade per department over the last three years'.
In a star schema, which table stores the numeric measures (such as amount and qty), and what do its other columns reference?
Show answer
At the center of the star is the fact table: each row is an event (one sale), and the measures are numeric. Its other columns are foreign keys that go to the dimension tables: which product, which cafeteria, which date. Dimension tables are small and descriptive, and the fact table is large.
On the cafeteria data, how many rows does SELECT campus, category, SUM(amount) FROM ... GROUP BY ROLLUP(campus, category) return?
Show answer
ROLLUP(campus, category) produces three grouping sets: (campus, category), (campus), (). In the data there are 2 campuses and 2 categories, all filled: (campus, category) is 4 rows, (campus) is 2 rows (Galata 3200, Rumeli 1600), () is 1 row (4800). Total 4 + 2 + 1 = 7. Since SQLite has no ROLLUP, three GROUP BYs were combined with UNION ALL, and 7 rows came out.
Same query with GROUP BY CUBE(campus, category). How many rows, and which extra rows appear compared with ROLLUP?
Show answer
CUBE takes all subsets: (campus, category), (campus), (category), (). The only set not in ROLLUP is (category): the total for each category regardless of campus. Drink 1400 + 1000 = 2400, Food 1800 + 600 = 2400. 7 + 2 = 9 rows.
For grouping attributes, how many grouping sets do CUBE and ROLLUP generate? Give the numbers for .
Show answer
CUBE chooses each attribute as 'present or absent': subsets, 8 for . ROLLUP is hierarchical and drops one from the right at a time: (a,b,c), (a,b), (a), (). Total .
Slice the cafeteria cube on month = 'Oct' and give total sales (amount) per campus.
Show answer
Slice fixes one dimension to a single value. The October rows: Galata Tost 1200 + Kahve 1000 = 2200, Rumeli Cay 500 + Simit 150 = 650. SQL: ... WHERE month = 'Oct' GROUP BY campus, which gave the same result in SQLite.
Using the 8 cafeteria transactions in the text, what is the support of the itemset {cay, simit}?
Show answer
Support = the number of transactions in which the two items appear together / the total number of transactions. {cay, simit} is in T1, T2, T4, T7: 4 / 8 = 0.5.
What is the confidence of the rule cay ⇒ simit? Is it the same as simit ⇒ cay?
Show answer
. Cay is in 5 transactions, and in 4 of them simit is there too: 4/5 = 0.8. In the other direction, simit is in 4 transactions and cay is in all 4: 4/4 = 1.0. Confidence is not symmetric, support is symmetric.
Compute the lift of tost ⇒ cay. What does the value say?
Show answer
. Tost is in 4 transactions, and in 2 of them cay is there: conf = 0.5. supp(cay) = 5/8 = 0.625. lift = 0.5 / 0.625 = 0.8. Less than 1: someone who buys tost buys less cay than the average customer. Although a confidence of 0.5 does not look bad on its own, lift shows it is worse than independence.
Run Apriori on the 8 transactions with minimum support count 2. Which 2-itemsets are frequent, and why is there no candidate 3-itemset?
Show answer
L1: cay 5, kahve 3, simit 4, su 2, tost 4 (all at least 2). Of the 10 pairs in C2, only three appear at least 2 times. The C3 candidates are generated from L2: for {cay, simit, tost}, the subset {simit, tost} appears only 1 time, so it is not frequent. For {cay, kahve, tost}, {cay, kahve} never appears. The Apriori principle (every subset of a frequent set is frequent) prunes both without counting the data. C3 is empty, and the algorithm stops.
A training set has 10 students: 5 passed, 5 failed. Splitting on attendance: 'yes' has 4 passed and 1 failed, 'no' has 1 passed and 4 failed. Compute the information gain of attendance (log base 2, 3 decimals).
Show answer
Initial entropy: a 5/5 distribution, . Each branch is 4 to 1: . Weighted average . Gain . The decision tree chooses the attribute with the highest gain at the root.
k-means with k = 2 on A(1,2), B(2,1), C(2,3), D(8,8), E(9,7), F(7,9). Initial centroids are c1 = (1,2) and c2 = (2,3). Give the centroids after the first iteration, and the final clusters.
Show answer
Assignment (squared distance): A goes to c1 (0 and 2), B goes to c1 (2 and 4), C goes to c2 (2 and 0), D, E, F go to c2. New centroids: c1 = mean(A, B) = (1.5, 1.5), c2 = mean(C, D, E, F) = (26/4, 27/4) = (6.5, 6.75). In iteration 2, C's squared distance is 2.5 to c1 and 34.3125 to c2, so C moves to c1. The centroids become (1.67, 2) and (8, 8). In iteration 3 the assignment does not change, and the algorithm stops. SSE = 6.667.
Verification: verify/SEN2104/14.mjs: the cafeteria star schema was built in node:sqlite (SQLite 3.53) and all OLAP queries were run. Because SQLite does not support ROLLUP/CUBE (error: no such function: ROLLUP), the standard SQL results were produced with GROUP BYs combined by UNION ALL. Support, confidence, lift, Apriori candidates and pruning, entropy and information gain, and k-means iterations and SSE were computed in JS.