Before CREATE TABLE syntax and bind options, you need the ideas that make Db2 make sense: tables, rows, and columns; keys and relationships; set-based thinking versus record-at-a-time file processing; and how Db2 for z/OS implements the relational model for real applications. This page builds that foundation for beginners moving from COBOL files into SQL.
In the relational model, data is perceived as existing in tables. Each table has a name (for example CUSTOMER) and a fixed set of columns that describe attributes (CUST_ID, CUST_NAME, CITY). At any moment the table holds zero or more rows, each row storing one value (or NULL) per column. Rows are not inherently ordered; if you need a display order, you ask for it with ORDER BY in SQL.
Columns have data types. Db2 needs to know whether a column is character, integer, decimal, date, and so on, because storage, comparison, and arithmetic rules depend on type. NULL means “unknown or not applicable,” which is different from blank or zero—a critical idea when you write predicates.
1234567CREATE TABLE CUSTOMER ( CUST_ID INTEGER NOT NULL, CUST_NAME VARCHAR(40) NOT NULL, CITY VARCHAR(30), STATUS CHAR(1) NOT NULL, PRIMARY KEY (CUST_ID) );
You can picture one row as one customer. Unlike a COBOL FD that is private to a program’s file section, the table definition lives in Db2’s catalog and is shared. Privileges control who can SELECT or UPDATE. Many programs can use CUSTOMER at once.
A base table stores the data. A view is a named SELECT that presents columns—and often a filtered subset of rows—as if they were a table. Views help security and simplicity (expose only certain columns) without duplicating the base data. You will study views in a dedicated page; for relational thinking, remember that users still query something that looks like a table.
Relationships connect data across tables using values, not physical parent/child pointers like older hierarchical databases. Keys make those relationships reliable.
| Kind | Role | Example |
|---|---|---|
| Primary key | Uniquely identifies each row in a table | CUSTOMER(CUST_ID) |
| Unique key / unique constraint | Enforces uniqueness on one or more columns (alternate candidate keys) | CUSTOMER(EMAIL) if emails must be unique |
| Foreign key | Values must match a parent key (referential integrity) | ORDERS(CUST_ID) → CUSTOMER(CUST_ID) |
| Composite key | Uniqueness or relationship spans multiple columns | ORDER_LINE(ORDER_ID, LINE_NO) |
Example: every order belongs to a customer. ORDERS stores CUST_ID. That column is a foreign key referencing CUSTOMER. If referential integrity is enforced, Db2 rejects an order for a customer id that does not exist, and it can restrict or cascade deletes according to how the constraint was defined.
12345678CREATE TABLE ORDERS ( ORDER_ID INTEGER NOT NULL, CUST_ID INTEGER NOT NULL, ORDER_DATE DATE NOT NULL, ORDER_AMT DECIMAL(11,2) NOT NULL, PRIMARY KEY (ORDER_ID), FOREIGN KEY (CUST_ID) REFERENCES CUSTOMER (CUST_ID) );
Indexes often support keys for fast lookup and to enforce uniqueness. An index is not the same thing as a key: a key is a logical rule; an index is a physical access structure. In practice Db2 uses unique indexes to implement unique and primary key constraints.
Getting cardinality right matters more than memorizing jargon. If you store the wrong grain—for example stuffing many phone numbers into one column—you fight the relational model instead of using it.
COBOL file programs train you to think record-at-a-time: open file, read next record, decide, write, loop until end. That model maps to cursors when you must process query results in a host language. Relational SQL encourages set-based thinking: describe the set of rows to change or return, then let Db2 evaluate the set.
| Aspect | Record-at-a-time | Set-based |
|---|---|---|
| Unit of thought | One record in a loop | A set of rows matching a predicate |
| Typical code | READ / FETCH then IF logic then WRITE | UPDATE ... WHERE status = 'OPEN' |
| Who picks access path | Programmer’s next I/O call | Db2 optimizer (influenced by stats/indexes) |
| Risk when misused | Slow chatty logic; hard concurrency | Accidental mass update if WHERE is wrong |
Set-based example—close all open orders for one customer in a single statement:
1234UPDATE ORDERS SET STATUS = 'C' WHERE CUST_ID = 1001 AND STATUS = 'O';
A record-at-a-time approach would declare a cursor for those orders, fetch each row, and update one by one. Sometimes you need that (complex per-row logic, writing a report line per fetch). Often the set-based UPDATE is clearer, shorter, and easier for Db2 to optimize. Beginners coming from files should practice asking, “Can I express this as one SQL statement against a set?” before writing a cursor loop.
Joins combine rows from related tables into a wider set:
12345SELECT c.CUST_NAME, o.ORDER_ID, o.ORDER_AMT FROM CUSTOMER c INNER JOIN ORDERS o ON c.CUST_ID = o.CUST_ID WHERE c.CITY = 'LONDON';
Mentally: start from customers in London (a set), combine with matching orders (another set) using the key relationship, and project the columns you need. That is relational thinking in one query.
Db2 for z/OS implements the relational model for enterprise systems:
IBM’s introduction materials emphasize that in a relational database all data is logically contained in tables, and that referential integrity, check constraints, and triggers help keep data valid inside the DBMS rather than only inside each application. That is a major upgrade from “every COBOL program validates the file layout its own way.”
Db2 also extends beyond pure textbook relational features (large objects, XML, and other capabilities), but tables and SQL remain the center of gravity for most application work on z/OS.
Upcoming pages drill into tables, rows, columns, schemas, databases, and table spaces as concrete Db2 objects. Keep this mental model: relational concepts are how you design and query; Db2 objects are how the product stores, secures, and tunes that design on z/OS.
Think of a binder of baseball cards. Each page is a table. Each card is a row. Each fact printed on the card—name, team, batting average—is a column. A special number on the card that no other card shares is like a primary key. If another binder of “games schedules” writes that same player number to show who is playing, that number is like a foreign key. Instead of flipping every card by hand to find all Yankees hitters, you can ask a smart helper (SQL) to bring you the whole set at once. That helper is what Db2 is good at.
1. In the relational model, a table is perceived as:
2. A primary key’s main job is to:
3. Set-based SQL thinking means:
4. A foreign key relates:
5. How does Db2 fit the relational model for applications?