Unit 7 · 4 hrs · CSUE301 Big Data Analytics

Scalable
Visualization & Analytics

Six chapters have stored, processed, streamed, learned from, and now this one has to answer for it: "how many distinct restaurants ordered today," "has this customer ordered before," "which restaurant is secretly our biggest," rendered onto a dashboard that has to load in under a second. At citywide scale, exact answers to these questions cost more than anyone needs to pay — this chapter is about the structures that trade a little accuracy for a lot of speed, on purpose.

Five restaurants, twenty bits

"Definitely not" is sometimes all you need

A wrong "maybe" is cheap. A wrong "definitely" would be a bug.

A tiny bit array can tell you a restaurant is definitely new, or maybe already known — never the other way around. Section 7.2 shows exactly where that "maybe" comes from.

Colour contract for this chapter Hub N's server Hub S's server Hub E's server What the sketch had to trade away
7.1 · WHY EXACT ANSWERS DON'T SCALE

Three Questions, Three Expensive Habits

"Have we seen this before," "how many distinct ones," "how many times" — three questions any dashboard might ask, and three data structures whose exact form gets expensive in exactly the same way: they grow with the data.

At sixteen orders, exact tracking is free. A Python set of restaurant names, an exact counter per restaurant, a full histogram of every value that ever appeared — all trivially small. Citywide, at 46,080 orders a day across (Section 3.4's estimate) roughly 1,200 distinct restaurants, "just keep an exact record" stops being a rounding error and starts being a real memory and bandwidth bill, paid every single day, forever.

three questions, three sketches Is X in the set? exact: a hash set, growing with every distinct item → approximate: a Bloom filter (Section 7.2) How many distinct X? exact: the same hash set, or a sort-and-dedupe → approximate: HyperLogLog (Section 7.3) How many times has X occurred? exact: a full histogram, one counter per distinct key → approximate: Count-Min Sketch (Section 7.4)

Every approximate structure in this chapter answers its question using a FIXED amount of memory, chosen in advance, regardless of how large the true dataset grows. That single property — memory that doesn't scale with cardinality — is the entire reason any of them exist.

this is Chapter 1's five V's, resolved with a trade instead of a fight

Section 1.1 named Volume as a real, structural challenge, not something you fix by buying more disk forever. Every structure in this chapter is a concrete instance of the same resolution Chapter 4 applied to memory-vs-disk and Chapter 5 applied to latency-vs-completeness: pick a bounded, known error budget, and buy a specific, predictable, much smaller amount of memory with it.

Worked Example · The Bill for "Just Store Everything"
Exact restaurant tracking, one year of CityCourier
1,200 distinct restaurants, citywide
exact set of seen restaurants1,200 distinct identifiers, roughly 8 bytes each once hashed to a fixed-size key: 9,600 bytes. Small today — but it was small at 16 orders too, and the number that matters is how it grows: linearly, forever, with every new restaurant CityCourier ever partners with.
Section 7.3's answerA HyperLogLog sketch answering "how many distinct restaurants" to within 1% needs roughly 256 bytes — and stays at 256 bytes whether the true count is 1,200 or 12 million. The exact set's 9,600 bytes was never going to do that.
Answer: the exact structure's cost is a function of the data. The approximate structure's cost is a decision, made once, about how much error is tolerable.
pitfalls
  • "Approximate means unreliable." Every structure in this chapter comes with a provable, mathematical error bound, not a vague "usually close enough." Section 7.3's 26% or 0.2% error at different sketch sizes are exact predictions of a known formula, not guesses.
  • "You'd only use these at Google scale." The crossover point is much lower than intuition suggests — a hash set of a few hundred thousand distinct strings already costs megabytes an exact structure that a few kilobytes of sketch would answer almost as well.
  • "Once you choose an approximate structure, you're stuck with its error rate." Every structure here is tunable — more bits, more hash functions, more buckets — the error rate is a dial you set when building the structure, traded directly against the memory you're willing to spend.
Practice
  1. If CityCourier's distinct-restaurant count grew from 1,200 to 12,000 (10×), what happens to the exact set's memory cost, and what happens to a fixed-size HyperLogLog sketch's memory cost?
    Solution

    The exact set grows 10×, to roughly 96,000 bytes — linear in the count, as always. The HyperLogLog sketch's memory doesn't change at all; the same 256-byte sketch answers the question for 12,000 distinct items too, just with the same ~1% error rate it always had, regardless of the true count.

  2. A system needs to know EXACTLY which specific restaurants have ordered, not just how many. Would a HyperLogLog sketch answer that?
    Solution

    No — HyperLogLog only estimates the COUNT of distinct items, and by design never stores or can reconstruct which specific items were seen. A system that needs the actual identities back needs an exact structure (or a different sketch entirely); approximate cardinality and "give me the list" are fundamentally different questions.

  3. Why might the exact set actually be the right choice at CityCourier's current, un-scaled size, even though this section argues for approximation?
    Solution

    Because at 1,200 restaurants (or fewer), 9,600 bytes is genuinely nothing — smaller than the sketch's own error-handling code, arguably. Approximate structures earn their keep at the point where exact tracking's LINEAR growth actually starts to hurt; below that point, exactness is free and strictly better.

  4. Section 4.3 distinguished a cache (a performance optimization, not a durability guarantee) from a replicated block (a durability guarantee). Is a Bloom filter's "maybe present" answer closer to a cache or to a replicated block, in terms of what you can trust it for?
    Solution

    Closer to a cache — it's explicitly a probabilistic shortcut, not a source of truth. Exactly as a cache miss falls back to recomputing from source, a Bloom filter's "maybe present" typically triggers a fallback to an authoritative check, never stands alone as the final answer to something that actually matters.

7.2 · BLOOM FILTERS

Probably In, Definitely Out

"Has CityCourier ever partnered with this restaurant?" A 20-bit array can answer — and it will never wrongly say no, only, occasionally, wrongly say maybe.

A Bloom filter is a bit array of size m, plus k hash functions. Inserting an item sets k bits (one per hash function). Checking an item reads the same k positions: if ANY is still 0, the item was definitely never inserted. If ALL are 1, the item was probably inserted — probably, because some other combination of items could have set those same bits by coincidence.

Worked Example · Five Restaurants, Twenty Bits

Insert CityCourier's five known restaurants into a 20-bit array using 2 simple hash functions:

bit positions set by each restaurant (k=2 hash functions)
restauranth1h2
Curry Point75
Momo Hut59
Wrap City118
Sushi Go180
Pizza Barn55

7 of 20 bits end up set (some restaurants share positions by coincidence — Pizza Barn's two hashes collide with each other, and with Curry Point's and Momo Hut's). Now query three never-inserted names:

Query the filter
m=20 · k=2 · 5 inserted
Never inserted. Both bit positions land on 0 — the filter correctly says "definitely absent."

"Delhi Cafe" was never inserted either — but it hashes to positions 5 and 0, and both happen to already be set (5 by three different real restaurants, 0 by Sushi Go). The filter reports "maybe present." It's wrong, and it was never claiming otherwise: this is a false positive, the one kind of error a Bloom filter is allowed to make.

false-positive rate P(false positive) ≈ (1 − e−kn/m)k with k=2, n=5, m=20: (1 − e−0.5)² ≈ 15.5%
mergeable, exactly like Section 3.3's combiners

If Hub N, Hub S, and Hub E each built their own local Bloom filter of restaurants they've personally seen, the filter for "any restaurant any hub has seen" is just the bitwise OR of the three arrays — no restaurant names ever need to travel between machines, only m bits per filter. Same shape as a distributed sum: compute a small local summary, combine centrally, get the correct global answer.

pitfalls
  • "A Bloom filter can tell you an item IS in the set." It can only ever say "maybe" for presence and "definitely not" for absence. Confidence in the positive direction never reaches certainty, by construction.
  • "You can remove an item from a standard Bloom filter." Clearing a bit could un-set a bit another item also depends on — Pizza Barn and Curry Point share bit 5 in the worked example, so clearing it to "remove" Pizza Barn would break membership testing for Curry Point too. Deletion needs a variant (a counting Bloom filter), not the structure described here.
  • "More hash functions always reduce the false-positive rate." Only up to a point — too many hash functions set so many bits that the array saturates faster, which can raise the false-positive rate again. There's a genuine optimum, not a monotonic "more is better."
Practice
  1. Using this section's formula, estimate the false-positive rate if the same 5 restaurants were inserted into a 40-bit array instead of 20, keeping k=2.
    Solution

    (1−e−2×5/40)² = (1−e−0.25)² ≈ (0.221)² ≈ 4.9% — roughly a third of the 20-bit array's 15.5%, from doubling the array size alone.

  2. Would testing "Curry Point" itself (an actually-inserted restaurant) ever return "definitely absent"?
    Solution

    Never — both of Curry Point's bit positions (7 and 5) were set at insertion time and Bloom filter bits are only ever set, never cleared (barring the counting-filter variant). Every genuinely inserted item is guaranteed a "maybe present" (true positive) result, with 100% certainty in that direction.

  3. Hub E builds its own Bloom filter for restaurants IT has personally served, separate from Hub N's and Hub S's. A new order arrives at Hub E for a restaurant that only Hub N has served before. What does Hub E's own filter say, and is that wrong?
    Solution

    Hub E's own filter almost certainly says "definitely absent" (correctly — Hub E genuinely never inserted that restaurant), which isn't wrong at all; it's answering "has HUB E seen this," not "has ANYONE seen this." Getting the broader answer needs the merged (OR'd) filter across all three hubs, exactly this section's note box.

  4. Section 7.1 distinguished a Bloom filter's role from a source of truth. Sketch a realistic use: CityCourier wants to avoid an expensive database lookup for "is this a brand-new restaurant we need to onboard." How would a Bloom filter fit in, and what still has to happen afterward?
    Solution

    Check the filter first: "definitely absent" skips the database lookup entirely (genuinely new, proceed to onboarding) with full confidence. "Maybe present" still requires the real database lookup to confirm, since it might be a false positive — the filter's job is only to cheaply skip the EXPENSIVE check in the common case where the answer is a clean "no," never to replace the check when the answer might be "yes."

7.3 · HYPERLOGLOG

Counting Distinct Things Without Storing Them

1,200 distinct restaurants, citywide. HyperLogLog never stores a single restaurant's name and still lands within 1% of the true count — if you give it enough buckets.

HyperLogLog hashes every item to a long bit string and looks only at ONE property: how many leading zeros appear before the first 1. A short run is common; a long run is rare — specifically, a run of length r should occur with probability roughly 2−r, purely by chance. See a long run anywhere in the stream, and it's evidence that MANY distinct items have been hashed, since a rare event needed a lot of tries to show up at all. Split the incoming hashes across m buckets, keep only the LONGEST run seen in each bucket, and combine the m longest-runs into one estimate.

Worked Example · Estimating 1,200 Restaurants at Three Sketch Sizes
same true count (1,200), different bucket counts
buckets (m)memoryestimateerror
1616 B886.526.1%
6464 B1,086.79.4%
256256 B1,197.70.2%

The standard error follows a known formula, 1.04÷√m — at m=16 that predicts ~26%, at m=256 it predicts ~6.5% (this particular run happened to land closer to the truth than its own typical spread, which is normal statistical variation, not a broken formula). Quadrupling the buckets roughly halves the expected error, every time — a genuine dial, not a leap of faith.

Try the Dial
Buckets vs. accuracy, same true count
true count: 1,200 restaurants
Buckets (m):
16 buckets, 16 bytes: estimate 886.5 vs true 1,200 — 26.1% off.
mergeable by taking the max, not by adding

Give each of CityCourier's three hubs its own 256-bucket sketch tracking restaurants IT has seen. The sketch for "restaurants ANY hub has seen" merges the three by taking the MAXIMUM run-length in each bucket position, not a sum — exactly reflecting that a longer run seen by any one hub is still valid evidence, and a shorter run elsewhere in the same bucket adds nothing new. This is a different merge rule than Section 7.2's OR-the-bits or Section 3.3's sum-the-counts, but the same underlying shape: a small local summary, combined centrally, correct without ever moving the raw data.

pitfalls
  • "HyperLogLog can tell you which items were distinct." It can't — it never stores any item, only the longest zero-run per bucket. The count is real; the identities are gone the moment they're hashed.
  • "Errors only ever undercount." HyperLogLog's error is genuinely two-sided — it can land above or below the true count, unlike Section 7.4's Count-Min Sketch, which is guaranteed to only ever overestimate.
  • "Small cardinalities are estimated just as well as large ones." The 1.04/√m formula is an asymptotic result; real implementations (Redis's HLL, for instance) switch to a different, exact-counting strategy for small cardinalities specifically because the leading-zero-run logic is noisy when very few items have been hashed at all.
Practice
  1. Using the 1.04/√m formula, what bucket count would be needed to target roughly a 2% standard error?
    Solution

    1.04/√m = 0.02 → √m = 52 → m ≈ 2,704, rounded up to a convenient power of two (4,096 in most real implementations) — still only a few kilobytes for a 2%-accurate distinct count at any true cardinality.

  2. Two independently-run 256-bucket HyperLogLog sketches, one per data center, need to be combined into a single global distinct-restaurant count. What's the actual merge operation?
    Solution

    Take the elementwise maximum of the two sketches' 256 registers, one bucket at a time, producing a single merged 256-register sketch — then apply the same estimation formula to the merged result. No raw data or restaurant names are ever exchanged between data centers, only the 256 register values.

  3. A dashboard needs "distinct restaurants today" refreshed every few seconds, at citywide volume. Why would an exact hash-set implementation struggle here in a way a HyperLogLog sketch wouldn't?
    Solution

    An exact set has to be read, updated, and (for a live dashboard) possibly transmitted on every refresh, with a size that grows all day; a HyperLogLog sketch stays at a small, fixed size (256 bytes, say) regardless of how many restaurants have been seen so far, making every refresh cost the same small, predictable amount of work no matter how the day's true count has grown.

  4. Section 6.3's K-means recompute step summed local (sum, count) pairs across machines. Is HyperLogLog's max-based merge doing the same kind of aggregation, or a genuinely different one?
    Solution

    Genuinely different — K-means needed an average, which requires a SUM (an associative, additive combination). HyperLogLog's registers need a MAXIMUM, an entirely different (though still associative and commutative) combination rule. Both distribute cleanly by Section 6.1's litmus test, but "sum" and "max" are different operations with different correctness arguments, not the same trick twice.

7.4 · COUNT-MIN SKETCH

Frequency Without a Full Histogram

Section 3.4's Curry Point — the 144×-skewed chain — is exactly the kind of heavy hitter a Count-Min Sketch finds cheaply. Small, rare restaurants pay a much rougher price for that same cheapness.

A Count-Min Sketch is d separate hash tables of width w, each a row of counters. Every occurrence of a key increments one counter in EVERY row (a different hash function per row). To query a key's count, hash it into each row and take the MINIMUM of the d counters found — the minimum, because any single row's counter might be inflated by collisions with other keys, but it's never possible for a counter to hold LESS than the truth.

Worked Example · Seventeen Restaurants, One Hour

A 3-row, 8-wide sketch (d=3, w=8), fed one hour of orders across 17 restaurants including the skewed Curry Point chain:

true count vs Count-Min Sketch estimate (selected rows)
restauranttrueestimateerror
Curry Point (the heavy hitter)230248+18 (7.8%)
Momo Hut1414+0 (0%)
Grill House930+21 (233%)
Ocean Grill716+9 (129%)

Every single estimate is at or above the truth — never once below. But look at the SHAPE of the error: Curry Point's absolute error (+18) is large in raw terms but tiny relative to its own size (7.8%). Grill House's absolute error (+21) is actually bigger in raw terms, yet relative to Grill House's true count of 9, that's a 233% distortion. The sketch's error is roughly uniform in ABSOLUTE terms across all keys — which means it's cheapest, relatively, for exactly the heavy hitters you're usually trying to find.

this is why Count-Min Sketch is the standard heavy-hitter tool

Section 3.4 needed to identify that Curry Point was a skew problem in the first place. A Count-Min Sketch answers "which keys have the highest estimated count" cheaply and finds Curry Point reliably, precisely because a heavy hitter's relative error stays small even while a long tail of small restaurants gets noisy, largely-irrelevant estimates. The structure is bad at precisely the thing nobody was trying to use it for.

See the Guarantee
pitfalls
  • "Count-Min Sketch estimates can come in low." Never — the minimum-of-d-counters construction makes underestimation mathematically impossible. Every error in this section's table is zero or positive, not a coincidence of this particular run.
  • "A small count is estimated about as reliably as a big one." The worked example's Grill House (233% relative error) versus Curry Point (7.8%) makes the opposite true: absolute error is roughly uniform, so it hurts small counts far more, proportionally, than large ones.
  • "More hash collisions mean the sketch is broken." Collisions are the expected, designed-for source of the sketch's (bounded) overestimation — not a malfunction, the mechanism itself.
Practice
  1. Two machines each keep their own Count-Min Sketch (same d, w, and hash functions) over half of citywide traffic. How is a combined sketch produced?
    Solution

    Add the two sketches cell-by-cell — row 1's counters add to row 1's, and so on. Because every counter is just a sum of increments, and sums distribute across machines cleanly (Section 3.1's litmus test again), the combined sketch is exactly as if all the traffic had gone through one machine's sketch from the start.

  2. Would increasing w (the width, more counters per row) or d (the depth, more rows) do more to fix Grill House's 233% relative error?
    Solution

    Increasing w — more counters per row means fewer keys collide into the same counter, directly shrinking the overestimation for every key, small or large. Increasing d (more independent rows to take the minimum across) helps guard against a single row having an unusually bad collision, but doesn't shrink the baseline collision rate the way more width does.

  3. A key that was NEVER inserted at all is queried against this section's sketch. Can its estimate come back as a large positive number?
    Solution

    Yes — if that key happens to collide, in every one of the d rows, with counters that real keys pushed high (Curry Point's counters, say), the minimum across rows could still be large, purely from collision. This is the Count-Min Sketch analogue of Section 7.2's Bloom filter false positive: a plausible-looking wrong answer, bounded but not impossible.

  4. Chapter 3 introduced salting as a fix for a skewed reducer key. Does salting help or hurt a Count-Min Sketch tracking that same skewed key's true frequency?
    Solution

    It would hurt the SKETCH's usefulness for finding the heavy hitter, even though it helps the reduce job it was designed for: salting splits Curry Point's true count across several sub-keys, so any one sub-key's count looks smaller and less obviously "heavy" to the sketch, potentially hiding the very pattern Section 3.4 and this section are both trying to surface. The two techniques solve different problems and can work against each other if applied to the same key without care.

7.5 · OLAP CUBES & VISUALIZING AT SCALE

The Last Mile: From Numbers to a Screen

Every chapter before this one produced a correct number. This section asks the question a dashboard actually has to answer: which numbers, pre-computed how, and how many pixels can a human actually read?

A head-office dashboard rarely asks one flat question. It asks the same data sliced by hub, by time window, by both at once, by neither — and re-running a full aggregation for every slice, on demand, is Section 3's shuffle cost paid over and over for a page that needs to load in under a second.

Worked Example · One Cube, Every Slice For Free

Pre-compute revenue once, cross-tabulated by hub and by Section 1.3's tumbling window — an OLAP cube:

revenue cube: hub × window, plus every roll-up
W0W1W2TOTAL
Hub N1,0205205452,085
Hub S76593001,695
Hub E7107702851,765
TOTAL2,4952,2208305,545

"Revenue by hub" (Chapter 1's original question) is the rightmost column — a roll-up that drops the window dimension by summing across it. "Revenue by window" is the bottom row, the same roll-up in the other direction. The grand total, 5,545, is both dimensions rolled up at once. Every one of these answers was ALREADY computed the moment the 3×3 cube itself was built; none of them need the raw 16 rows touched again.

drill-down is the same cube, read the other way

Given only "Hub S: ₹1,695," a manager asking "which part of the shift drove that" is asking to DRILL DOWN — add the window dimension back and read Hub S's own row: ₹765, ₹930, ₹0. Nothing is recomputed; the finer-grained numbers were sitting in the same cube the coarse one rolled up from. Roll-up and drill-down are the same pre-computed structure, read at different resolutions.

The Other Half: Rendering

Suppose the dashboard also wants a literal scatter plot of every order's amount versus delivery time, citywide, for the whole day. 46,080 points on one chart is not a chart — it's a solid smear of ink, unreadable at any zoom level a screen can show.

a readable scatter plot: roughly 3,000 points before density makes individual points meaningless 46,080 ÷ 3,000 ≈ 15.4× downsample needed — keep roughly 1 point in every 15

Sampling for rendering is a genuinely different problem from Section 7.1's sketches: those trade memory for a controlled COUNTING error. Downsampling for a scatter plot trades render time and legibility for a controlled REPRESENTATION error — the 3,000 shown points need to be a fair, unbiased sample of the 46,080 real ones, exactly Section 6.5's "any 20% with equal probability" bar, applied to pixels instead of a train/test split.

pitfalls
  • "An OLAP cube has to be rebuilt for every new question." Only for questions along a dimension the cube didn't include from the start. Every roll-up and drill-down ALONG existing dimensions is free; a genuinely new dimension (say, restaurant) needs a new or bigger cube.
  • "Downsampling for a chart is the same trade-off as a Bloom filter's error." Related in spirit, not in kind — a Bloom filter's error is a provable probability bound on a yes/no answer; a downsampled scatter plot's "error" is closer to Section 6.5's sampling-fairness question, with no single formula playing the role Section 7.2's false-positive-rate formula does.
  • "More dimensions in a cube cost proportionally more to precompute." Cube size grows with the PRODUCT of each dimension's cardinality, not the sum — adding a restaurant dimension (5 values) to this section's hub×window cube (3×3=9 cells) doesn't add 5 cells, it multiplies to 3×3×5=45.
Practice
  1. Add a restaurant dimension (5 values) to this section's hub×window cube. How many cells does the full cube now have?
    Solution

    3 (hub) × 3 (window) × 5 (restaurant) = 45 cells — the pitfall box's multiplicative growth rule, not an additive one.

  2. Using the cube in this section, what's Hub N's revenue in window W2 specifically, without recomputing anything from the raw 16 rows?
    Solution

    ₹545 — read directly from the Hub N row, W2 column of the pre-built cube.

  3. At 10× today's citywide volume (460,800 orders/day), how many points would need to be sampled to keep the same readable-scatter target of ~3,000?
    Solution

    Still about 3,000 — the render budget is set by what a screen and a human eye can distinguish, not by how much data exists. The DOWNSAMPLE RATIO gets more extreme (460,800÷3,000 ≈ 153.6× instead of 15.4×), but the target point count barely moves.

  4. This chapter opened by calling every structure in it a memory-or-speed-for-accuracy trade. Is a pre-computed OLAP cube also making that trade, or something else?
    Solution

    A different trade, and a more familiar one: a cube spends STORAGE (every roll-up, precomputed and kept) to buy QUERY SPEED, with NO accuracy loss at all — every cube answer is exact. Sections 7.2–7.4 traded accuracy for memory; Section 7.5's cube trades memory for speed while keeping accuracy perfect, and its downsampled scatter plot (a genuinely different half of this section) trades fidelity for legibility instead. Three different trades, three different currencies, in one closing section.

CLOSING · CHEAT SHEET

Chapter 7, One Page

7.1 · Why Exact Doesn't Scale

Exact structures grow with the data · sketches use fixed, chosen-in-advance memory

Three questions: membership, cardinality, frequency — three sketches

7.2 · Bloom Filters

k hash functions, m bits · "definitely absent" is certain, "maybe present" isn't

FPR ≈ (1−e−kn/m)k · mergeable via bitwise OR

7.3 · HyperLogLog

Tracks longest zero-run per bucket · never stores actual items

Standard error ≈ 1.04/√m · mergeable via per-bucket MAX

7.4 · Count-Min Sketch

d rows × w counters · query = minimum across rows

Never underestimates · small counts hurt relatively more than heavy hitters

Mergeable via cell-wise sum

7.5 · OLAP & Visualization

Cube size grows multiplicatively across dimensions, not additively

Roll-up/drill-down: same precomputed cube, different resolution, zero recompute

Downsampling for rendering trades fidelity for legibility, not accuracy for memory

CLOSING · SELF-TEST

Mixed Review

Eight questions, deliberately out of section order.

  1. A Bloom filter says "definitely absent" for a restaurant that was, in fact, inserted earlier. Is this possible?
    Solution

    No — a genuinely inserted item's bits are always set, so it can never return "definitely absent." Only false POSITIVES are possible, never false negatives.

  2. A HyperLogLog sketch with 64 buckets estimates 1,086.7 against a true count of 1,200. Does increasing to 256 buckets guarantee an estimate closer to 1,200?
    Solution

    Not a guarantee for any single run — it reduces the EXPECTED error (the standard error shrinks from ~13% to ~6.5%), but any individual estimate is still a random draw around the truth, which can occasionally land further off despite the better expected accuracy.

  3. Why does a Count-Min Sketch's minimum-across-rows query rule guarantee no underestimation?
    Solution

    Every row's counter for a key can only be inflated by collisions with other keys (adding extra count), never reduced below the key's true contribution. Taking the minimum across several such counters picks the LEAST-inflated available estimate, which is still ≥ the truth.

  4. An OLAP cube has dimensions hub (3), window (3), and restaurant (5). How many cells hold the fully rolled-up grand total?
    Solution

    Exactly 1 — rolling up every dimension collapses the whole 45-cell cube to a single grand-total number, regardless of how many dimensions or cells the full cube has.

  5. Which of this chapter's structures would help answer "list every restaurant CityCourier has ever partnered with"?
    Solution

    None of them, directly — Bloom filters, HyperLogLog, and Count-Min Sketch all discard the actual item identities by design. That question needs an exact structure (a set, a database table); this chapter's sketches only answer membership, count, or frequency questions, never "give me the list."

  6. Two machines each hold a Count-Min Sketch over half of CityCourier's citywide traffic. What operation combines them correctly?
    Solution

    Cell-wise addition — add each row's corresponding counters together, since every counter is fundamentally a sum of increments and sums distribute cleanly across machines.

  7. A dashboard's scatter plot samples 3,000 of 46,080 daily orders. Is this the same kind of operation as Section 6.5's train/test split?
    Solution

    The same FAIRNESS requirement (any point should have had an equal chance of being the one shown, just as any row should have had an equal chance of landing in the test set), applied to a different purpose — legible rendering instead of unbiased model evaluation.

  8. Would a Bloom filter, a HyperLogLog sketch, and a Count-Min Sketch all built over the exact same stream of restaurant names take up the same amount of memory?
    Solution

    Not necessarily — each has its own independent size parameter (m bits for the Bloom filter, m buckets for HyperLogLog, d×w counters for Count-Min Sketch), chosen based on that structure's own accuracy target, not tied to the others or to how large the underlying stream happens to be.

FURTHER READING

If You Want the Long Version

  • Mining of Massive Datasets — Leskovec, Rajaraman & Ullman. Its stream-mining chapters cover Bloom filters, cardinality estimation, and frequency-moment sketches (Sections 7.2–7.4) as a connected family, with the underlying probability arguments worked in full.
  • Designing Data-Intensive Applications — Martin Kleppmann. Frames materialized views and pre-aggregation (Section 7.5's OLAP cube) as instances of a general derived-data pattern that recurs across this entire course.
  • Spark: The Definitive Guide — Chambers & Zaharia. Covers Spark SQL's approximate aggregation functions (approx_count_distinct, and similar), which are production implementations of exactly Sections 7.3 and 7.4's ideas.

Chapter 7 of 7 · CSUE301 Big Data Analytics · the last chapter. CityCourier's sixteen orders have now been stored (Ch.2), processed (Ch.3), cached (Ch.4), streamed (Ch.5), learned from (Ch.6), and summarized (Ch.7) — the same sixteen rows, seven different questions asked of them.
This completes CSUE301 Big Data Analytics. See index.html for the full course map.