Data warehouses and Snowflake

After this lesson you will tell OLTP from OLAP in the slides' words, define a data warehouse with Inmon's four adjectives, design a star schema and name the cube operations on it, and explain what Snowflake changed by separating storage from compute — including the two places where the slides blur scaling and caching.

Your bank's app shows your balance in a blink. Ask it how your spending changed over the last ten years and it has nothing to say: it keeps the current state of your account, not its history. The bank answers that question somewhere else, on a second copy of its data, filled in advance — a copy that, the slides admit, does not necessarily hold "most current information" (p. 491).

That second copy has a name and a 1992 definition, and the deck spends almost forty slides on its theory. Then it turns the page with one line: ".. So old school …" (p. 520). Yet on 16 September 2020 Snowflake, a company that sells exactly this kind of copy as a cloud service, raised 3.36 billion dollars on the New York Stock Exchange, in what was reported as the largest software IPO of all time.

If the theory is old school, what was new enough to be worth that much? Keep the question: the last section answers it.

Two kinds of work: OLTP feeds, OLAP asks

The deck opens with two acronyms (p. 483):

OLTP — On Line Transaction Processing: "Describes processing at operational sites".

OLAP — On Line Analytical Processing: "Describes processing at large, integrated data warehouses".

Picture a chain of electronics stores in Rome and Milan. Each till is an operational site: all day it runs short transactions — scan, pay, update the stock — each touching a few rows found by their key. Head office asks how many keyboards each region sold last quarter: a question that reads every sale of the quarter, but only a few columns of each. "OLTP systems provide source data to data warehouses, whereas OLAP systems help to analyze it" (p. 484); the slide draws the loop that joins them, from transactions to the warehouse, to analytics and decisions, and back to the business strategy.

Why not run both kinds of work on one database? Because they grow along different axes, as the slide "Challenges of Scale Differ" draws (p. 485, Fig. 1).

Amount of data # of concurrent sessions Data Warehouse OLTP few users, long scans many sessions
Fig. 1. "Challenges of Scale Differ" (p. 485), redrawn. A warehouse grows in the amount of data it holds and serves few users; an OLTP system grows in the number of concurrent sessions. The slide draws no numbers: it draws two directions, and a system built for one is not built for the other.

Two slides list the differences. Read each row as a consequence of the access pattern: a till looks up one product by its primary key, so OLTP keeps an "Index/hash on p.k." and only the "Current snapshot"; head office scans a year of sales, so the warehouse is built for "Lots of scans" and keeps "History". Even the schema follows: many narrow, normalised tables for OLTP (lesson 9), few wide ones for the warehouse — section 4 shows why.

OLTP against OLAP, as pp. 489 and 505 print them (p. 505 puts the warehouse column first).
Standard DB / operational system (OLTP)Warehouse (OLAP)p.
Mostly updatesMostly reads489
Many small transactionsQueries long and complex489
Mb - Gb of dataGb - Tb of data489
Current snapshotHistory489
Index/hash on p.k.Lots of scans489
Raw dataSummarized, reconciled489
Thousands of users (e.g., clerical users)Hundreds of users (e.g., decision-makers, analysts)489
Transaction orientedSubject oriented505
Small (MB up to several GB)Large (hundreds of GB up to several TB)505
Current dataHistoric data505
Normalized table structure (many tables, few columns per table)De-normalized table structure (few tables, many columns per table)505
Continuous updatesBatch updates505
Simple to fairly complex queriesUsually very complex queries505

A yin-yang closes the comparison (p. 506): "OLTP, Operational System, Data Entry" against "OLAP, Data Warehouse, Data Retrieval" — data enters through one half and comes out, analysed, through the other.

OLTP runs many short transactions on the current state; OLAP runs few long scans over history. They grow along different axes, so they live in different systems.

Copy it in advance: what a data warehouse is

The chain's data sits in many places — tills, web shop, loyalty cards, suppliers' spreadsheets — each with its own codes and its own idea of a "product". Page 487 names the problem: "Integrated Data Analytics", "Coherent Insights Extraction", "Heterogeneous and distributed data sources". The deck shows two ways to answer a question across such sources (Fig. 2).

Clients Integration System Metadata Wrapper Wrapper Wrapper Source Source Source

Before: query-driven, lazy, on demand (p. 488)

Clients Data Warehouse Integration System Metadata Extractor/ Monitor Extractor/ Monitor Extractor/ Monitor Source Source Source

After: the warehousing approach, integrated in advance (p. 490)

Fig. 2. The same sources, two architectures. Orange arrows are queries, blue arrows are data. Before: every query travels down through the wrappers to the live sources, and the answers travel back; nothing is stored in between. After: data travels up once, in advance, into the warehouse; the queries stop there and never reach the sources.

The traditional approach is "Query driven", "Lazy", "On-demand" (p. 488): an integration system splits each question, sends a piece to every source through a wrapper — an adapter that speaks the source's language — and merges the answers, helped by metadata on what each source holds. The warehousing approach turns this around: "Information integrated in advance", "Stored in dwh for direct querying and analysis" (p. 490). An extractor/monitor at each source extracts its data and detects changes, the integration system merges them, and the result is loaded into the data warehouse that clients query. Lesson 4 met the same choice as "virtual ETL" against ETL (p. 175).

"High query performance" — "But not necessarily most current information".

"Doesn't interfere with local processing at sources": "Complex queries at warehouse", "OLTP at information sources".

"Information copied at warehouse": it "Can modify, annotate, summarize, restructure, etc." and "Can store historical information".

"Widely adopted in industry".

"Rapidly changing information"

"Rapidly changing sources"

"Truly vast amounts of data from large numbers of sources"

"Clients with unpredictable needs"

The reasons: the copy is fast because it is local and pre-integrated, and stale because it is only as fresh as its last load; it does not interfere because the long scans run on the copy; it keeps history because it is yours — the till overwrites the stock level, the warehouse keeps every sale. The right column is where copying in advance fails: data or sources that change too fast, too much data, questions nobody can foresee.

Two definitions to learn

Data warehouse, a practitioner's viewpoint — "A data warehouse is simply a single, complete, and consistent store of data obtained from a variety of sources and made available to end users in a way they can understand and use it in a business context." Barry Devlin, IBM consultant (p. 493).

Data warehouse, an analytical viewpoint — "A DW is a subject-oriented, integrated, time-varying, non-volatile collection of data that is used primarily in organizational decision making." W.H. Inmon, Building the Data Warehouse, 1992 (p. 494).

Inmon's four adjectives are the ones to learn, and pp. 495–496 unfold them. Subject-oriented: "Organized by subject, not by application" (p. 495) — one Customer subject assembled from tills, web shop and loyalty cards. Integrated: many sources brought to one format and meaning; p. 495 calls the warehouse "A solution to data integration problem". Time-varying: every record carries its time, so the warehouse holds history, not only the present. Non-volatile: what is loaded is not overwritten. Page 496 prints these two together: under "Non-volatile" it lists "Historical" and "Time attributes are important", then "Updates infrequent" and "Maybe append-only" — data that is never overwritten piles up as history. Its examples are all history: "All transactions ever at a bank", "Complete client histories at insurance firm", "Financial information and portfolios of customers" — the app holds your balance, the warehouse every movement since you opened the account.

"Non-volatile means the warehouse is never written." It is written by loads, in batches; what it does not get is the stream of small updates of an OLTP database. A sale, once loaded, stays as it was.

A data warehouse is a subject-oriented, integrated, time-varying, non-volatile collection of data used for decision making, integrated in advance from many sources.

Inside the warehouse: layers, tiers, ETL and marts

The "Generic Warehouse Architecture" (p. 497) draws the warehousing approach bottom-up: sources, an extractor/monitor each, an integrator, the warehouse with its metadata, query and analysis, clients. Its grey labels — "Design Phase", "Loading", "Maintenance", "Optimization" — name the jobs around it, and p. 500, "Issues in Data Warehousing", lists them as problems: warehouse design; extraction, with "Wrappers, monitors (change detectors)"; integration, "Cleansing & merging" (extraction and integration together make the loading); optimization; maintenance, which keeps the copy in step with changing sources.

Pages 498–499 see the same thing as layers of data:

The reconciled layer makes reports agree: every derived view starts from the same cleaned base. Read "really requires" as the argument for it, not as a law — the previous slide calls two layers the industry's usual choice.

Who reads the derived data? Decision support systems, "Information technology to help the knowledge worker (executive, manager, analyst) make faster & better decisions" (p. 501), with sample questions such as "What were the sales volumes by region and product category for the last year?", "How did the share price of comp. manufacturers correlate with quarterly profits over the past 10 years?" and "Which orders should we fill to maximize revenues?". "On-line analytical processing (OLAP) is an element of decision support systems (DSS)". Their architecture has three tiers (Fig. 3).

Information sources Tier 1 warehouse server Tier 2 OLAP servers Tier 3 clients semistructured operational DBs Data Warehouse data marts MOLAP ROLAP serve Analysis Query/Reporting Data Mining extract, transform, load, refresh, etc. ETL
Fig. 3. The DSS architecture of p. 502. The ETL arrow fills the warehouse server of tier 1, which feeds departmental data marts; the OLAP servers of tier 2, multidimensional (MOLAP) or relational (ROLAP), serve the analysis, reporting and mining tools of tier 3, which the warehouse can also serve directly.

The arrow into tier 1 reads "extract, transform, load, refresh, etc." (p. 502): ETL — extract the data from the sources, transform it to the warehouse's format and meaning, load it, refresh it periodically. (Loading raw data first and transforming it inside the warehouse is often called ELT — not a slide term, but how Snowflake loads in section 6.) Tier 2 has two kinds of OLAP server (p. 503). ROLAP, a "Relational specialized DBMS to store and manage warehouse data" plus "OLAP middleware to support missing pieces", keeps the cube virtual, in tables queried with SQL. MOLAP, with "Array-based storage structures" and "Direct access to array data structures", stores the cube as an array addressed by the dimension values.

Last, scope (p. 504). An enterprise warehouse "collects all information about subjects that span the entire organization". Data marts are "Departmental subsets that focus on selected subjects", like the "Marketing data mart: customer, product, sales" — "Faster roll out, but complex integration in the long run", since separate marts end up defining "customer" differently. A virtual warehouse is "views over operational DBs", "Easy to build but require excess capability on operat. db servers".

ETL — extract, transform, load, refresh — fills the warehouse; data marts are its departmental subsets; ROLAP keeps the cube in relational tables, MOLAP in arrays.

The star, the snowflake and the cube

An operational schema is a network of entities and relationships; p. 508 draws it as an "ER Diagram" next to the warehouse's "Star Schema", one central box with the others around it. Page 509 draws the star in the course's ER notation (Fig. 4).

Sale Product Store Promo Time (0,N) (1,1) (0,N) (1,1) (1,1) (0,N) (1,1) (0,N) Central unit: FACT Rays: DIMENSIONS
Fig. 4. The star schema of p. 509 in the course's ER notation, with the slide's two labels. Every sale has exactly one product, one store, one promotion and one time, (1,1); a product, store, promotion or time may take part in no sale or in many, (0,N).

The centre is the fact, the event being measured: a sale. The rays are the dimensions, the points of view from which you analyse it. Page 510 adds the table of the fact — Sale, with CodProd, CodStore, CodPromo, CodTime underlined and the bullets Amount, Qty — and five lines:

Why keep the dimensions un-normalised, after lesson 9? Because users never update them: only the batch load writes them, and it changes a city's region in every row at once, so the update anomalies of lesson 9 do not bite; the repetition costs little, since dimension tables are small; and every question saves joins. This is p. 505's "De-normalized table structure": a narrow, very long fact table among wide, short dimensions.

Normalise them anyway and the star becomes a snowflake schema, "Hierarchies for not normalized dimensions" (p. 512): Store points to City, City to Region, Region to Country; time becomes Day, Month, Year; Product gets its Producer and Category (Fig. 5). Page 511's pictograms explain the name: a star's dimensions all touch the fact, a snowflake's branch.

Producer Product Category Store Sale Offer City Region Country Day Month Year (0,N) (1,1) (1,1) (0,N) (0,N) (1,1) (0,N) (1,1) (1,1) (0,N) (1,1) (0,N) (1,1) (0,N) (1,1) (0,N) (1,1) (0,N) (1,1) (0,N) (1,1) (0,N) a Day: one Month (1,1) a Month: many Days (0,N) hierarchies
Fig. 5. The snowflake schema of p. 512. Promo is renamed Offer, and Time is split into the chain Day, Month, Year. Each chain is a hierarchy: Store, City, Region, Country; Day, Month, Year; Product with its Category and Producer.

The price is joins: "sales by country" takes one join in the star (Sale with Store) and four in the snowflake. The gain is explicit hierarchies and a little space — little, because a dimension is tiny next to the fact table. And the snowflake schema shares only its name with Snowflake, the product of section 5.

Operations on the cube

Now see the facts as points in a space whose axes are the dimensions. Page 514 draws the cube of the store chain: Store (Roma-1, Roma-2, Milano-1, Milano-2) by Product (PCs, Mouses, Keyboards, TVs) by Time ("1 trim. 2003" to "4 trim. 2003"), with an arrow labelled Quantity on one small cube. Each of the 4 × 4 × 4 = 64 cells holds the measure of one combination: one row of the fact table. Page 513 defines the operations:

Drill-down — "Add one analysis dimension (disaggregation)".

Roll-up — "Remove one analysis dimension (aggregation)".

Slice and dice — "Datacube (slice and dice)": cut a part out of the cube, "Select and Project" (p. 515).

From sales by region and month, a roll-up removes a dimension — sales by region, each total the sum of that region's months; a drill-down adds one — by region, month and category, finer groups, same grand total. A slice fixes one dimension to one value; a dice keeps ranges of values on several. Pages 516–519 shade them on the cube (Fig. 6).

Sales in an area (p. 516) slice: Store fixed Time Product Store Sales of a product (p. 517) slice: Product fixed Time Product Store Sales in a period (p. 518) slice: Time fixed Time Product Store Strategic: a dice (p. 519) dice: a range on every axis Time Product Store
Fig. 6. Slice and dice on the cube of p. 514, four members per axis. A slice fixes one dimension to one member and leaves a 4 × 4 slab — "Sales in an area", "Sales of a product", "Sales in a period". A dice keeps a range on several dimensions and leaves a smaller cube: "STRATEGIC DECISION SUPPORT: Category of products in a region and mid-term time span" (p. 519), here 2 × 2 × 2 = 8 cells.

"Roll-up only removes a dimension." That is p. 513's definition. Textbooks also call climbing a hierarchy (months to years, cities to regions) a roll-up and descending it a drill-down — the snowflake's chains are exactly such paths. In SQL both are the same move: a coarser GROUP BY.

Each operation edits one star query: join the fact to the dimensions you need, filter and group on their attributes, sum the measures. The first question of p. 501, with 2003 as the last year:

-- p. 501: sales volumes by region and category, last year
SELECT st.Region, p.Category, SUM(s.Qty) AS Qty
FROM Sale s
  JOIN Store st ON s.CodStore = st.CodStore
  JOIN Product p ON s.CodProd = p.CodProd
  JOIN Time t ON s.CodTime = t.CodTime
WHERE t.Year = 2003
GROUP BY st.Region, p.Category;

Roll-up and drill-down change only the GROUP BY; slice and dice only the WHERE. Build the star yourself and watch it happen.

Build the star, then ask it questions

The four keys are in place. A card under the drawing shows one attribute at a time: decide in which table it belongs, then press that table's button. When all eleven are placed, choose a question: the drawing marks the tables it joins, the attributes it groups by or sums, and those it filters; below it you get the SQL and the result on 16 fact rows of sample data (one row per product, store, promotion and day — the data are invented for this widget).

  1. Before pressing anything, decide where City and then Amount belong. Press your answers.
    What you should see

    City goes in Store: it describes where a sale happened, and in the fact it would be repeated in every sale of the same store. Amount goes in Sale: it is a number summed over many sales, a measure. This is the one rule of the star: the fact holds the dimension keys and the measures, the dimensions hold the descriptions.

  2. Finish the star and choose "sales by region and month". Before you look: which tables does the query join, and how many groups do you expect from 2 regions and 4 months?
    What you should see

    Sale, Store and Time; Product and Promo turn grey because the question does not name them. All 16 fact rows are read and fall into 8 groups, from Lazio 2002-12 = 1600 to Lombardia 2003-06 = 4680; the total is 19295 euro.

  3. Predict the result of "roll-up: remove Time" from the table you just saw, then choose it. Then try "month → year".
    What you should see

    Each region's months add up: Lazio 1600 + 3600 + 2790 + 420 = 8410, Lombardia 10885. Only the SELECT and the GROUP BY lines change, and Time is no longer joined; the total stays 19295. Month to year keeps four groups, one per region and year: same total again.

  4. Compare the slice "only the Milano stores" with the dice "Accessories × Lombardia × May–June 2003". Which lines of the SQL light up, and how many fact rows survive each?
    What you should see

    Only WHERE lines change (the dice also joins Product, to filter on its category). The slice keeps 8 of the 16 rows, the dice 3; the GROUP BY is the same as in the first question. Roll-up and drill-down edit the GROUP BY, slice and dice the WHERE.

A star is one narrow fact table, dimension keys plus measures, among wide dimension tables. Every OLAP question joins the fact to the dimensions it names; roll-up and drill-down edit the GROUP BY, slice and dice the WHERE.

So old school? Snowflake's three layers

After the cube comes ".. So old school …" (p. 520), and the deck switches to a product. Its key features (p. 521): "Enterprise-ready cloud data warehouses that automatically scales for balancing performances and costs"; "Separation between compute and storage" — "Other databases combine the two together, meaning you must size for your largest workload and incur the cost that comes with it"; "Single place for storing all the data", one copy for every workload.

The middle one is the key. In a classic warehouse cluster every machine holds a share of the data and the processors that work on it. To have enough processors for the Monday-morning rush you buy machines that idle the rest of the week, and adding processors means moving data onto them. Separated, storage and compute each grow, shrink or stop on their own. Page 523 draws the two traditional designs, p. 524 Snowflake's (Fig. 7).

shared-disk shared-nothing each node, its slice

Before: the two traditional architectures (p. 523)

Cloud Services login, metadata, optimizer, access Query Processing VW 1 VW 2 VW 3 Database Storage

After: Snowflake's layers (p. 524); VW = virtual warehouse

Fig. 7. Before: in shared-disk every node reads one storage, which becomes the bottleneck; in shared-nothing each node owns its slice of the data, so compute and storage grow together. After: one central storage, as in shared-disk, read by independent compute clusters of any size, as in shared-nothing, with a coordinating layer on top. Blue marks where the data lives.

Snowflake takes one idea from each. The slides draw it; Snowflake's documentation names it, "a hybrid of traditional shared-disk and shared-nothing database architectures". Its layers, bottom up:

"A virtual warehouse is where the data is." The deck uses the phrase in two senses: on pp. 498 and 504 it is views over operational databases; in Snowflake (p. 526) it is a compute cluster that holds no data of its own, at most a cache of what it has read.

With no indexes, how does Snowflake avoid reading the whole table?

Background from Snowflake's documentation and its SIGMOD 2016 paper, not from the slides. Tables are split automatically into micro-partitions of 50 to 500 MB of uncompressed data, stored column by column. For each one the cloud services layer records the range of values of every column, so a filter on a date skips every micro-partition whose range cannot match: pruning, which does for scans what indexes do for lookups. Micro-partitions are never modified, only replaced, which makes two features cheap that the slides do not name: time travel (querying a table as it was) and zero-copy cloning (a copy that is only new metadata over the same files).

Page 522, "Why is data warehousing important?", lists what a managed cloud warehouse adds: "Consistency", "Security and Data Protection" (multi-factor authentication, single sign-on, TLS), "Connectivity" (Python and Spark connectors, Node.js and .NET drivers), "Fault Tolerance". Separation pays most when teams share data: p. 542 gives the data scientists DATASCIENCE_WH and the DBAs DBA_WH, two warehouses over the same transactions table, and p. 545 builds a multi-cluster AS_WH for a changing load. The widget puts a team of analysts on AS_WH: that assignment is this lesson's scenario, not the slides'.

Two teams, one copy of the data

At the bottom, the storage layer holds transactions once. Above it, two virtual warehouses with the slides' names: DATASCIENCE_WH (p. 542) for a data scientist, AS_WH (p. 545) for a team of analysts; each small square is one unit of compute, and a size step doubles it. Change the sizes, the number of clusters and the load. The credit rates are Snowflake's documented ones (1, 2, 4, 8, 16 credits per hour from XSMALL to XLARGE), not printed on the slides; the times come from this widget's simple model, not from Snowflake: the full scan needs 32 minutes of XSMALL compute and splits perfectly; a dashboard query takes 4 s on XSMALL and never less than 2 s; each cluster runs at most 8 queries at once.

  1. Keep 24 analysts and MAX_CLUSTER_COUNT = 1. How many dashboard queries wait, and how slow is the slowest answer? Predict, then raise MAX_CLUSTER_COUNT to 3, as on p. 545.
    What you should see

    With one cluster, 8 queries run and 16 wait: three rounds of 4 s, so the slowest analyst waits 12 s. With three clusters all 24 run at once and the slowest answer takes 4 s; AS_WH costs 3 credits per hour instead of 1. Scaling out removes the queue; no single query got faster.

  2. Now set MAX_CLUSTER_COUNT back to 1 and make AS_WH bigger instead: SMALL, then MEDIUM. Predict the slowest answer.
    What you should see

    SMALL: each query takes 2 s, but 16 still wait, so the slowest answer is 6 s at 2 credits per hour. MEDIUM: still 6 s, now at 4 credits per hour — a dashboard query is too small to spread over more compute. For many small queries, more clusters beat a bigger size.

  3. Change DATASCIENCE_WH from SMALL to LARGE. What happens to the scan, to its cost, and to the analysts' readouts?
    What you should see

    The scan drops from 16 to 4 minutes; the warehouse costs 8 credits per hour instead of 2, so the scan still costs about 0.53 credits. The analysts' readouts do not move: dedicated warehouses share no compute (p. 526). Scale up for one big query; and the copy of the data in storage stays one — this is the separation of storage and compute.

  4. Untick the scan and set the analysts to 0. Predict the credits per hour, and what happens to transactions.
    What you should see

    Zero credits per hour: both warehouses suspend after AUTO_SUSPEND = 300 seconds and the drawing greys them out. The table is untouched in storage, ready for the next query, which AUTO_RESUME = TRUE answers by restarting the warehouse.

Storage is one shared, columnar copy; compute is any number of independent virtual warehouses that can be resized, multiplied or suspended without touching the data.

Loading and tuning: stages, Snowpipe, warehouses, caches, clustering keys

Clients connect through a web interface, command-line clients, ODBC and JDBC drivers (Tableau), native connectors for Python and Spark, and third-party ETL and BI connectors (p. 528). Snowflake loads CSV, TSV, JSON, Avro, ORC, Parquet and XML, compressed or not (p. 529); the slide also lists Amazon S3, Google Cloud Storage and Microsoft Azure among the "Types of data", but they are places to load from, not formats. Two ways in (p. 530):

"Snowflake provides the COPY command for batch loading". It "uses Virtual Warehouse computing resources" and is "Managed manually". It "Allows basic transformations such as reordering and excluding columns, data typing, truncating strings".

"Snowpipe used for loading streaming data". "Scaling up / down is done automatically". It "Doesn't use the virtual warehouse computing resources".

A bulk load has four steps (p. 532): prepare the files, stage the data ("Make snowflake aware of the data"), execute COPY, schedule regular loads. A stage is "an intermediate, transient place used to process data for extracting, transforming and loading processes" (p. 533), classically an S3 bucket or an Azure blob store, "Long term cheap storage for raw data"; in Snowflake such an external stage is a named pointer to that place, written @name. COPY INTO then loads the files (p. 534, with the names of pp. 536–537):

-- load the stage's CSV files: '|'-separated, one header line
COPY INTO transactions
  FROM @snowpipe_copy_example_stage
  pattern = '.*.csv'
  file_format = (type = csv field_delimiter = '|' skip_header = 1);

pattern is a regular expression on file names; for JSON the format is file_format = (type = json). COPY's transformations are deliberately basic — the rest is SQL inside the warehouse, the ELT order of section 3. To leave files where they are, an external table queries them in place, "Useful when there is a lot of data externally but we want to query only a small subset of data", sped up by materialized views (p. 531). Fig. 8 compares the two ways in.

S3 bucket CSV stage @name your warehouse COPY INTO you, by hand or on a schedule transactions

Bulk: you run COPY on your warehouse (pp. 530–534)

S3 bucket new event SQS queue serverless compute transaction_pipe transactions

Continuous: the bucket wakes the pipe (pp. 535–540)

Fig. 8. The two ways in. Left: a stage (violet) points at the bucket, and COPY INTO, run by you on your own warehouse, moves the files into the table. Right: when a file lands, the bucket sends an event to a queue, and Snowflake runs the pipe — a stored COPY — on its own compute. Blue arrows carry data, black ones carry control.

Snowpipe is a "Mechanism to enable loading of streaming data" with a "Serverless architecture": "It has its own processing", "No virtual warehouse instances involved" (p. 535). A pipe is a stored COPY that Snowflake runs whenever a new file is announced, set up in four steps: "Stage data", "Validate copy command", "Create Pipe", "Configure cloud event or use REST APIs". The hands-on of pp. 536–540, in run order:

  1. Create the database and make it the current one (p. 536).

    CREATE DATABASE ingest_data;
    USE DATABASE ingest_data;
  2. Create an external stage on the S3 bucket, then list the files Snowflake can now see there.

    CREATE OR REPLACE STAGE snowpipe_copy_example_stage
    url='s3://snowpipe-streaming/example_table';
    LIST @snowpipe_copy_example_stage;
  3. Create the target table (p. 537).

    CREATE TABLE transactions
    (
      Transaction_Date DATE,
      Customer_ID NUMBER,
      Transaction_ID NUMBER,
      Amount NUMBER
    );
  4. Create the pipe: the COPY of p. 534 wrapped in CREATE PIPE … AS; auto_ingest = true makes it listen for cloud events.

    CREATE OR REPLACE PIPE transaction_pipe
    auto_ingest = true
    AS COPY INTO transactions FROM
    @snowpipe_copy_example_stage
    file_format = (type = csv field_delimiter = '|'
      skip_header = 1);
  5. Read the address (ARN) of the pipe's queue: in Snowflake's documentation it is the notification_channel column (p. 540).

    SHOW PIPES;
  6. In the AWS console, "Amazon S3 > bucket_name > properties > events" (p. 538): a notification "Snowflake Notification" for "All object create events", prefix transactions, sent to the "SQS Queue" with that ARN — "Insert here your snowpipe queue id" (p. 539).

  7. Upload a file and count the rows: "Now if a new file is uploaded on S3, the data arrives automatically on Snowflake" (p. 540) — with no COPY typed and no warehouse running.

    SELECT COUNT(*) FROM transactions;

Keeping it fast

With no indexes and no files to tune, five levers remain (p. 541): "Use dedicated virtual warehouses for different workloads", "Scale up for know large workloads", "Scale up with virtual warehouses for unknown workloads", "Design the production workflow to maximize cache usage", "Use cluster keys for partitioning large tables". Dedicated warehouses first (p. 542):

-- virtual warehouse for data scientists
CREATE WAREHOUSE DATASCIENCE_WH WITH WAREHOUSE_SIZE = 'SMALL'
WAREHOUSE_TYPE = 'STANDARD' AUTO_SUSPEND = 300 AUTO_RESUME = TRUE;

AUTO_SUSPEND = 300 suspends the warehouse after 300 idle seconds, so it stops costing; AUTO_RESUME = TRUE restarts it at the next query. The DBAs get DBA_WH, XSMALL "because of queries size". Privileges complete the pattern (pp. 542–543): the PUBLIC role may use the database and its schema and read the table (GRANT USAGE, GRANT SELECT); each team's role may use its warehouse (GRANT USAGE ON WAREHOUSE … TO ROLE …); a user such as DS_1 gets that role and warehouse as defaults.

For a workload whose load changes, pp. 544–545 create a multi-cluster warehouse:

-- 1 to 3 XSMALL clusters, started as queries queue
CREATE WAREHOUSE AS_WH
WITH WAREHOUSE_SIZE = 'XSMALL'
MIN_CLUSTER_COUNT = 1
MAX_CLUSTER_COUNT = 3
SCALING_POLICY = 'STANDARD'
AUTO_SUSPEND = 300
AUTO_RESUME = TRUE;

Its requirements are "a minimum and maximum number" and the "Enterprise Edition of Snowflake" (p. 544); SCALING_POLICY = 'STANDARD' starts a cluster as soon as queries queue (Snowflake's documentation). What is automatic here is suspend and resume, and the number of running clusters between the two counts; a warehouse's size changes only when you change it — so p. 521's "automatically scales" holds for clusters, not for sizes. The slide calls all this "scale up" — the first slip to correct.

"In Snowflake caching is automatic", says p. 546: "Results are cached for 24 hours", and "Snowflake knows when data has changed and it re-executes the query if necessary". The advice that follows mixes two caches.

Last lever (p. 547): "For very large tables, automatic partitioning scheme may not be optimal", so you can create "custom cluster keys to partition table according to the needs", "Normally used for columns involved frequently in WHERE, JOIN or ORDER BY statements"; "Only very large tables (multi terabyte size) will benefit from clustering". A clustering key keeps close values in the same micro-partitions, so filters on it prune more. Page 548, with the commas it forgot:

-- the transactions table, kept in Transaction_date order
CREATE TABLE transactions_clustered_date
(
  Transaction_date DATE,
  Transaction_id Integer,
  Customer_id String,
  Amount integer
) CLUSTER BY (Transaction_date);

Pages 533–534 and 542–543 print typographic quotes (‘SMALL’): type straight ones. Page 543 writes DBA _WH for DBA_WH and omits the semicolon after MUST_CHANGE_PASSWORD = TRUE; p. 548 omits the commas. Page 533's credentials='login_password' is a placeholder: real stages use a CREDENTIALS = (…) clause or a storage integration. Its "Data can also be staged on local file system" means uploading local files (with PUT) into a stage that Snowflake keeps, an internal stage: Snowflake never reads your own disk.

Back to the puzzle

What did Snowflake sell, if the theory is old school? Not a new model: the star, the cube and ETL work inside it unchanged, and section 4's star query runs there as written. It changed the machinery, and one decision explains nearly every Snowflake slide: storage separated from compute. With the data stored once in cheap cloud storage, each team gets its own warehouse on the same table; a warehouse grows, multiplies or stops without moving a byte; a pipe loads files with no warehouse running; a cached result needs no warehouse at all. The old warehouse was sized "for your largest workload", with "the cost that comes with it" (p. 521). This one is sized minute by minute.

Two neighbours complete the picture. A data lake (lesson 4) keeps raw files and applies the schema when reading, a warehouse before loading — and external tables let Snowflake read lake files in place. Hadoop (lesson 31; Hive's SQL over files, lesson 32) and Spark (lesson 40) are engines over files: Snowflake loads the Parquet and ORC files they write (p. 529) and has a Spark connector (p. 528).

Exam-style questions

Theory questions in the forms the theory part uses — true/false, multiple choice and short open answers, where a wrong tick may cost points — and one design exercise. The nine past papers contain no data-warehouse or Snowflake exercise; this material belongs to the theory part, which covers the content of the theoretical and practical lectures.

True or false: a data warehouse always contains the most current information available in the operational systems.

  • True The warehouse is a copy integrated in advance and refreshed by loads: between two loads it lags behind the sources.
  • False The first advantage of p. 491 comes with its price: "High query performance — But not necessarily most current information".
Show model answer

False. In the warehousing approach information is integrated in advance and copied into the warehouse, which is refreshed by periodic batch loads. Queries are fast and do not interfere with the sources, but the data is not necessarily the most current: it is as fresh as the last load. For rapidly changing information the query-driven approach is still better.

The trap is the word "always". A good justification names the price of copying in advance — staleness — and the case in which the lazy, query-driven approach wins.

According to the lecture, which of the following characterise a data warehouse (OLAP) rather than an operational OLTP database? Select all that apply.

  • Mostly reads p. 489, warehouse column.
  • Many small transactions The OLTP column of p. 489: the till's short transactions.
  • History rather than the current snapshot p. 489: "History" against "Current snapshot"; p. 505: "Historic data".
  • Index/hash on the primary key That is how OLTP finds one row by key; the warehouse does "Lots of scans".
  • Lots of scans p. 489: analytical queries read large parts of the data.
  • Normalized table structure, many tables with few columns p. 505 gives this to the operational system; the warehouse is "De-normalized … few tables, many columns".
  • Batch updates p. 505: the warehouse is loaded in batches, the operational system has "Continuous updates".
Show model answer

Mostly reads, history, lots of scans and batch updates. Many small transactions, an index or hash on the primary key and a normalized structure with many narrow tables characterise the OLTP database.

A select-all question built from the two comparison slides, pp. 489 and 505. Every option is a row of one of them: learn each row as a pair, and the wrong ticks become easy to avoid.

Give Inmon's definition of a data warehouse and explain each of its four properties with an example. Then explain how the warehousing approach differs from the query-driven approach to integrating heterogeneous sources.

Show model answer

Inmon defines a data warehouse as "a subject-oriented, integrated, time-varying, non-volatile collection of data that is used primarily in organizational decision making". Subject-oriented: data is organised by business subject, such as customer, product or sales, not by the application that produced it. Integrated: data from heterogeneous sources is reconciled into one consistent format and meaning. Time-varying: history is kept and every record is tied to a time — all transactions ever made at a bank, not only the current balance. Non-volatile: data is loaded in batches and then not updated, possibly append-only. In the warehousing approach information is integrated in advance: an extractor/monitor at each source feeds an integrator that loads the warehouse, and clients query the warehouse directly, with high performance and no interference with the sources, but not necessarily the most current data. In the query-driven approach (lazy, on demand) an integration system decomposes each query and sends it through wrappers to the live sources; it remains better for rapidly changing information or sources, truly vast amounts of data and clients with unpredictable needs.

A complete answer has three parts: the four adjectives with a concrete example each, the eager-versus-lazy contrast, and at least one case where each approach wins. Inmon's book writes "time-variant"; the slide prints "time-varying": use the slide's word and recognise the other.

A chain of pharmacies records its sales in an operational database whose ER diagram has these entities (primary key first): Sale Line (Line_ID, Date, Quantity, Amount), Medicine (Medicine_ID, Name, Category, Producer), Pharmacy (Pharmacy_ID, Name, City, Region) and Campaign (Campaign_ID, Description). Each sale line refers to exactly one medicine (1,1), exactly one pharmacy (1,1) and at most one campaign (0,1); a medicine, a pharmacy or a campaign can appear in any number of sale lines (0,N). Management wants to analyse quantities and amounts by medicine category, region and month.

(a) Design a star schema with one fact row per medicine, pharmacy, campaign and day: give the fact table with its key and its measures, and the dimension tables with their attributes, with the (min,max) cardinalities. (b) Say which tables are normalised and why. (c) Show how the Pharmacy dimension changes in a snowflake schema. (d) Write the SQL query that returns the total amount by region and month.

Show model answer

(a) Fact Sale(Medicine_ID, Pharmacy_ID, Campaign_ID, Time_ID, Quantity, Amount): the key is composed of the four dimension keys, the measures are Quantity and Amount, and each row aggregates all the sale lines of that combination in that day. Dimensions: Medicine(Medicine_ID, Name, Category, Producer), Pharmacy(Pharmacy_ID, Name, City, Region), Campaign(Campaign_ID, Description), with a "no campaign" row for sales without one so that the key stays complete, and Time(Time_ID, Day, Month, Year). Every relationship is (1,1) on the Sale side and (0,N) on the dimension side.

(b) The fact table is in BCNF: its only functional dependency goes from the whole key to the measures. The dimensions are not normalised: Pharmacy_ID → City → Region and Day → Month → Year are transitive dependencies, kept on purpose because the warehouse is loaded in batches and not updated in place, and every attribute stays one join away from the fact.

(c) In a snowflake schema the hierarchy becomes separate entities: Pharmacy (1,1)—(0,N) City (1,1)—(0,N) Region, that is Pharmacy(Pharmacy_ID, Name, City_ID), City(City_ID, Name, Region_ID), Region(Region_ID, Name).

(d)

SELECT ph.Region, t.Year, t.Month, SUM(s.Amount) AS Amount
FROM Sale s
  JOIN Pharmacy ph ON s.Pharmacy_ID = ph.Pharmacy_ID
  JOIN Time t ON s.Time_ID = t.Time_ID
GROUP BY ph.Region, t.Year, t.Month;

The design reasoning of pp. 509–512 applied to a new scenario. A complete answer has the composed key, the measures in the fact and the descriptions in the dimensions, the normalisation argument of p. 510, and a query that joins only the dimensions it needs — grouped by year and month, or April of two different years would fall into one group. The "no campaign" row is the detail that keeps the key complete: the slide's star puts Promo (1,1) on every sale, which needs exactly such a row for sales without a promotion.

Consider the cube Store × Product × Time with measure Quantity. Define drill-down, roll-up, slice and dice, give an example of each, and say which clause of the SQL star query each operation changes.

Show model answer

Drill-down adds one analysis dimension (disaggregation): from sales by product and quarter to sales by product, quarter and store. Roll-up removes one analysis dimension (aggregation): from sales by product, quarter and store back to sales by product and quarter, each cell being the sum over the stores; climbing a hierarchy, such as from month to year or from city to region, is also a roll-up. A slice fixes one dimension to one value and leaves a sub-cube with one dimension less, for example the sales of one product over all stores and periods. A dice selects ranges of values on several dimensions and leaves a smaller cube, for example a category of products in a region over a mid-term time span: two products, two stores and two quarters, 8 cells. In the star query, roll-up and drill-down change the GROUP BY (fewer or more grouping attributes, or a coarser or finer level of a hierarchy); slice and dice add conditions on dimension attributes to the WHERE.

Give the slide's definitions (p. 513) first, word for word, then the hierarchy form as a complement. The link to SQL shows that you understand the operations rather than remember the pictures.

Which statement describes the architecture of Snowflake?

  • Shared-disk: every compute node works on one common disk system, and all queries compete for it Half of the picture: Snowflake keeps one central storage, like shared-disk, but runs its queries on independent MPP clusters (virtual warehouses) that do not compete with each other.
  • Shared-nothing: every node owns a partition of the data on its own disks Nodes do process data in parallel, but the data is not owned by them: it sits in one central storage.
  • A hybrid: a central columnar storage readable by all compute nodes, independent MPP compute clusters (virtual warehouses), and a cloud services layer that coordinates them The three layers of pp. 524–527: Database Storage, Query Processing, Cloud Services.
  • A single large server with columnar storage, scaled by moving to a bigger machine Virtual warehouses are MPP clusters of many nodes "allocated by Snowflake from a cloud provider" (p. 526).
Show model answer

The third. Snowflake is a hybrid of the two traditional architectures: like shared-disk it keeps the data in one central repository that every compute node can access, stored in an optimized, compressed, columnar format; like shared-nothing it processes queries on MPP clusters, the virtual warehouses, which share no compute resources with each other. A cloud services layer handles authentication, infrastructure, metadata, query parsing and optimization, and access control.

The slides draw the two traditional architectures (p. 523) and Snowflake's layers (p. 524) without the word "hybrid"; Snowflake's documentation uses it. The question checks that you can place Snowflake against both, not just name its layers.

Explain the separation between compute and storage in Snowflake and why the lecture presents it as a key feature. Then explain how resizing a virtual warehouse differs from a multi-cluster warehouse, and write the statement that creates a warehouse of size XSMALL that runs between 1 and 3 clusters and suspends after 5 minutes of inactivity.

Show model answer

In Snowflake the data is stored once, in a central cloud storage layer, in a compressed columnar format managed by Snowflake, while queries are processed by virtual warehouses: independent MPP compute clusters that read that storage and share no compute resources with each other. Other databases combine compute and storage, so they must be sized for the largest workload and that cost is paid all the time. With the two separated, each workload gets its own warehouse on the same data without interference, and a warehouse can be suspended when idle (AUTO_SUSPEND) and resumed automatically (AUTO_RESUME), so compute is paid only while it is used. Resizing a warehouse — scaling up, for example from XSMALL to LARGE — gives each query more compute and makes large, complex queries faster. A multi-cluster warehouse — scaling out — keeps the size but runs between MIN_CLUSTER_COUNT and MAX_CLUSTER_COUNT identical clusters, started automatically when queries queue: it serves more concurrent users but does not make a single query faster, and it requires the Enterprise Edition.

CREATE WAREHOUSE AS_WH
WITH WAREHOUSE_SIZE = 'XSMALL'
MIN_CLUSTER_COUNT = 1
MAX_CLUSTER_COUNT = 3
SCALING_POLICY = 'STANDARD'
AUTO_SUSPEND = 300
AUTO_RESUME = TRUE;

Two traps: the slides title multi-cluster warehouses "Scale Up" (p. 544), so name both moves and say what each one does; and AUTO_SUSPEND is in seconds, so five minutes is 300.

Check yourself

A bank wants a report of how its customers' spending changed over ten years. Why does it run the report on a data warehouse and not on the database behind its banking app?

  • Because the app's database cannot compute aggregates such as SUM or AVG It can; the problem is what the report would do to the app, and what the app's database keeps.
  • Because the long scans would compete with the short transactions of the app, and the app's database keeps the current state, not ten years of history "Doesn't interfere with local processing at sources" and "Can store historical information" (p. 491); OLTP keeps the "Current snapshot" (p. 489).
  • Because the warehouse holds fresher data than the app The opposite: the warehouse is "not necessarily most current information" (p. 491).
  • Because an OLTP database is always smaller than a terabyte Size is not the reason, and the slides' sizes are dated anyway; access pattern and history are.

A row of the fact table Sale holds Qty = 50 for Keyboards, Milano-1, no promotion, 15 April 2003. What does the row represent?

  • One receipt line: a customer bought 50 keyboards "FACT is an aggregate" (p. 510): one row per combination of the dimensions, not per receipt line.
  • The stock of keyboards left at Milano-1 that day A stock level is a current state, the OLTP side; the fact records what was sold.
  • A row of the Product dimension describing Keyboards A dimension row has descriptions such as name and category, and no store or date.
  • The total of all the keyboards sold at Milano-1 without promotion on that day Its key is the combination of the four dimension codes, and the measure is aggregated at that grain.

Starting from "sales by region and month", which of these are roll-ups? Select all that apply.

  • Sales by region One analysis dimension removed: the definition of p. 513.
  • Sales by city and month Finer than region: that is a drill-down along the Store hierarchy.
  • Sales by region and year Climbing the Time hierarchy from month to year: the textbook form of roll-up.
  • Sales by region and month, Milano stores only A slice: a condition in the WHERE, not a coarser grouping.
  • Sales by region, month and product category One dimension added: a drill-down.

Roll-up makes the groups coarser; drill-down makes them finer; slice and dice keep the groups and drop rows.

You snowflake the Store dimension of the star into Store, City, Region, Country. What happens to the query "sales by country"?

  • It needs no join any more, because Country has its own table The fact table still holds only CodStore: you must walk from it to Country.
  • It becomes impossible: the fact table loses its key CodStore The fact keeps its key; only the dimension is split.
  • It needs four joins instead of one: Sale, Store, City, Region, Country The price of normalised dimensions: one join per level of the hierarchy.
  • It needs fewer joins, because the dimension tables are smaller Smaller tables, more of them: more joins, not fewer.

At 9:00, 40 analysts open dashboards and their queries queue on a one-cluster XSMALL warehouse; at the same time one data scientist's full scan is too slow on its own warehouse. Which change fits each problem?

  • More clusters for the analysts' warehouse, a larger size for the data scientists' warehouse Scale out for many concurrent queries, scale up for one heavy query — the two moves that p. 544 calls by one name.
  • A larger size for the analysts' warehouse, more clusters for the data scientists' warehouse Swapped: a second cluster does not speed up the one scan, and a bigger size does little for many small queries.
  • A second copy of the table in storage for the analysts Not needed: every warehouse reads the same single copy.
  • One large warehouse for both teams, so they share the resources Then the scan and the dashboards slow each other down; p. 541 advises dedicated warehouses.

A dashboard sends exactly the same query as an hour ago; no data has changed since, and its warehouse has been suspended for fifty minutes. What happens?

  • The warehouse resumes and recomputes the query from the stored data Not needed: the result of an identical query on unchanged data is still in the result cache.
  • The query fails until someone resumes the warehouse by hand There is AUTO_RESUME; and here no warehouse is needed at all.
  • The result is returned only if the query reaches the same warehouse as an hour ago That is the slide's mix-up of p. 546: the result cache does not belong to a warehouse.
  • Snowflake returns the stored result from the result cache, kept by the cloud services layer, without starting the warehouse Results are cached for 24 hours, and Snowflake knows the data has not changed.

New CSV files land in an S3 bucket every few minutes, day and night. Why does Snowpipe fit better than a scheduled COPY?

  • Because COPY cannot read CSV files It can: the COPY of p. 534 loads pipe-separated CSV.
  • Because Snowpipe runs on Snowflake's own serverless compute when a file is announced, so no virtual warehouse has to stay awake for a trickle of files "No virtual warehouse instances involved" (p. 535); the COPY of a bulk load "uses Virtual Warehouse computing resources" (p. 530).
  • Because Snowpipe can transform the data much more than COPY A pipe is a stored COPY, with the same basic transformations.
  • Because Snowpipe leaves the files in the bucket and queries them in place That is an external table (p. 531); Snowpipe loads the files into a table.

Key take-aways

What to watch and read