Loading learning content...
At the heart of the network data model lies a deceptively simple construct: the set. In network database terminology, a set represents a one-to-many (1:N) relationship between two record types—an owner and its members. But this simplicity is deceptive; sets incorporate rich semantics that control ordering, membership constraints, insertion behavior, and navigation patterns.
Mastering set relationships means understanding not just what they connect, but how they control data behavior. A set isn't merely a container—it's a behavioral specification that governs how records interact, when they can be connected or disconnected, and what order they maintain. These semantics, formalized in CODASYL, represent one of the most sophisticated relationship modeling systems ever designed for databases.
In this page, we dissect set relationships completely—from basic anatomy through advanced multi-member configurations—providing the deep understanding necessary to design and program network databases effectively.
By the end of this page, you will understand: (1) Set type components: owner, member, and set occurrence structures, (2) Ordering specifications and their implementation, (3) Membership class semantics—MANDATORY, OPTIONAL, FIXED, (4) Insertion modes—AUTOMATIC vs. MANUAL, (5) Set selection mechanisms for determining set occurrence, (6) Multi-member sets and their applications.
Every set type in a network database defines a relationship between exactly two record types: one owner and one (or more) members. Understanding the distinction between set types and set occurrences is fundamental.
Set Type (Schema Level):
A set type is a named relationship defined in the database schema. It specifies:
Set Occurrence (Data Level):
A set occurrence is a specific instance of a set type, consisting of:
For each owner record that exists in the database, there is exactly one set occurrence of each set type where that record type is the owner.
1234567891011121314151617181920212223242526272829303132
SET TYPE DEFINITION (Schema Level):━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SET NAME IS DEPARTMENT_EMPLOYEE OWNER IS DEPARTMENT MEMBER IS EMPLOYEE ORDER IS SORTED BY Name This DEFINES the relationship structure.It exists once in the schema. SET OCCURRENCES (Data Level):━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ OCCURRENCE 1: Owner: DEPARTMENT "Engineering" Members: EMPLOYEE "Alice", EMPLOYEE "Bob", EMPLOYEE "Charlie" (Linked as: Engineering → Alice → Bob → Charlie → Engineering) OCCURRENCE 2: Owner: DEPARTMENT "Marketing" Members: EMPLOYEE "Diana", EMPLOYEE "Eve" (Linked as: Marketing → Diana → Eve → Marketing) OCCURRENCE 3: Owner: DEPARTMENT "Finance" Members: (empty - no members yet) (Linked as: Finance → Finance, i.e., owner points to itself) Each DEPARTMENT record owns exactly one OCCURRENCE of DEPARTMENT_EMPLOYEE.Multiple occurrences exist - one per department.The Owner-Member Asymmetry:
Sets are inherently asymmetric. The owner is singular and authoritative; members are plural and dependent:
| Aspect | Owner | Member |
|---|---|---|
| Count per occurrence | Exactly 1 | 0 to many |
| Existence requirement | Must exist for set to exist | Optional; set can be empty |
| Navigation role | Entry point; start of traversal | Linked sequence; traversal targets |
| Structural role | Contains first-member pointer | Contains next/prior/owner pointers |
| Conceptual role | The "parent" or "container" | The "children" or "contained" |
This design decision embeds a power relationship into the data structure—owners control; members belong. This isn't neutral information architecture; it imposes interpretation on the data.
Unlike mathematical sets which exist only if they have elements, a network database set occurrence can be empty—containing an owner but no members. A newly created department with no employees yet has a valid (empty) DEPARTMENT_EMPLOYEE set occurrence. The owner's first-member pointer simply points back to itself.
Unlike mathematical sets (which are unordered collections), network database sets are ordered sequences. The ORDER clause specifies how members are arranged within each set occurrence and where new members are inserted.
Ordering Options:
CODASYL defines several ordering semantics:
| Order Mode | Description | Insert Behavior | Use Case |
|---|---|---|---|
| FIRST | Insert at beginning | New member becomes first in set | Stack-like access; most recent first |
| LAST | Insert at end | New member becomes last in set | Queue-like access; chronological order |
| NEXT | Insert after current | New member follows current position | Insert at navigation point |
| PRIOR | Insert before current | New member precedes current position | Insert before navigation point |
| SORTED | Maintain sort order | Insert at sorted position using key | Alphabetical/numerical ordering |
| IMMATERIAL | System-determined | Insert wherever convenient | Order doesn't matter; optimize for storage |
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
/* ORDER IS FIRST - Insert at beginning (Stack behavior) */ SET NAME IS DEPARTMENT_MEMO OWNER IS DEPARTMENT MEMBER IS MEMO ORDER IS FIRST Insert Sequence: Resulting Order: 1. Insert Memo_Jan [Memo_Jan] 2. Insert Memo_Feb [Memo_Feb → Memo_Jan] 3. Insert Memo_Mar [Memo_Mar → Memo_Feb → Memo_Jan] First member is always the most recently inserted. /* ORDER IS LAST - Insert at end (Queue behavior) */ SET NAME IS CUSTOMER_ORDER OWNER IS CUSTOMER MEMBER IS ORDER ORDER IS LAST Insert Sequence: Resulting Order: 1. Insert Order_001 [Order_001] 2. Insert Order_002 [Order_001 → Order_002] 3. Insert Order_003 [Order_001 → Order_002 → Order_003] Maintains chronological order of insertion. /* ORDER IS SORTED - Maintain sort key order */ SET NAME IS SUPPLIER_PART OWNER IS SUPPLIER MEMBER IS PART ORDER IS SORTED BY PartName ASCENDING DUPLICATES ARE LAST Insert Sequence: Resulting Order: 1. Insert "Widget" [Widget] 2. Insert "Bolt" [Bolt → Widget] 3. Insert "Nut" [Bolt → Nut → Widget] 4. Insert "Bolt" (dup) [Bolt → Bolt → Nut → Widget] Alphabetical order maintained automatically. Duplicate keys placed LAST among duplicates.Sorted Set Keys and Duplicates:
When using ORDER IS SORTED, you must specify:
Duplicate handling options:
Composite Sort Keys:
Multiple fields can form the sort key, evaluated in order:
ORDER IS SORTED BY DeptName ASCENDING, HireDate DESCENDING
This sorts members first by department name (A-Z), then within each department by hire date (newest first).
ORDER IS SORTED requires insertion into the correct sorted position, which may require traversing the member chain. For large sets, this is O(n) per insert. ORDER IS FIRST or LAST is O(1) since inserts occur at fixed positions. Choose ordering based on access patterns, not just logical preference.
Perhaps the most semantically significant aspect of CODASYL sets is the membership class, specified by the RETENTION clause. This determines whether and how member records can be connected to and disconnected from set occurrences.
RETENTION IS MANDATORY:
A member with MANDATORY retention must always belong to some occurrence of this set type. The member cannot exist independent of the set relationship.
Implications:
12345678910111213141516171819202122232425262728293031
SET NAME IS DEPARTMENT_EMPLOYEE OWNER IS DEPARTMENT MEMBER IS EMPLOYEE RETENTION IS MANDATORY INSERTION IS AUTOMATIC /* Behavior with MANDATORY retention: */ -- Storing a new employee automatically inserts into a DEPARTMENT_EMPLOYEE setSTORE EMPLOYEE. -- Employee is now a member of some department's employee set -- Set selection determines which department -- Cannot disconnect an employee from ALL departmentsDISCONNECT EMPLOYEE FROM DEPARTMENT_EMPLOYEE. -- ERROR: MANDATORY members cannot be disconnected -- CAN move employee to different departmentRECONNECT EMPLOYEE WITHIN DEPARTMENT_EMPLOYEE. -- Employee moves from current department to new department -- Always belongs to exactly one department -- Deleting employee removes from setERASE EMPLOYEE. -- Employee removed from their department's set -- Employee record deleted -- Deleting department with mode "ALL" cascadesERASE DEPARTMENT ALL. -- Department deleted -- All MANDATORY members (employees) also deletedRETENTION IS OPTIONAL:
A member with OPTIONAL retention can exist without belonging to any set occurrence. The member has independent existence.
Implications:
1234567891011121314151617181920212223242526272829
SET NAME IS PROJECT_EMPLOYEE OWNER IS PROJECT MEMBER IS EMPLOYEE RETENTION IS OPTIONAL INSERTION IS MANUAL /* Behavior with OPTIONAL retention: */ -- Storing employee doesn't connect to any projectSTORE EMPLOYEE. -- Employee exists but belongs to no PROJECT_EMPLOYEE occurrence -- Must explicitly connect to a projectFIND ANY PROJECT USING ProjectCode = "P100".CONNECT EMPLOYEE TO PROJECT_EMPLOYEE. -- Employee now belongs to Project P100's member set -- Can disconnect from projectDISCONNECT EMPLOYEE FROM PROJECT_EMPLOYEE. -- Employee no longer belongs to any project -- Employee record still exists in database -- Can connect to different projectFIND ANY PROJECT USING ProjectCode = "P200".CONNECT EMPLOYEE TO PROJECT_EMPLOYEE. -- Employee now belongs to Project P200 -- Can be member of NONE, allowing unassigned employees-- This models "employee not currently assigned to any project"RETENTION IS FIXED:
A member with FIXED retention, once inserted into a set occurrence, cannot be moved or removed. The relationship is permanent until the member is deleted.
Implications:
12345678910111213141516171819202122232425262728293031
SET NAME IS CUSTOMER_ORDER OWNER IS CUSTOMER MEMBER IS ORDER RETENTION IS FIXED INSERTION IS AUTOMATIC /* Behavior with FIXED retention: */ -- Creating an order permanently associates it with a customerMOVE "C1001" TO CustomerID IN ORDER.STORE ORDER. -- ORDER inserted into Customer C1001's set -- This relationship can NEVER be changed -- Cannot disconnectDISCONNECT ORDER FROM CUSTOMER_ORDER. -- ERROR: FIXED members cannot be disconnected -- Cannot move to different customerRECONNECT ORDER WITHIN CUSTOMER_ORDER. -- ERROR: FIXED members cannot be reconnected -- Order belongs to C1001 until deletedERASE ORDER. -- Removes order from set and deletes order /* Use case: Historical integrity An order placed by Customer A should NEVER be moved to Customer B. The FIXED constraint enforces this business rule at the database level. Even if Customer A is deleted, the historical record should remain (or be explicitly handled, not accidentally moved). */| Operation | MANDATORY | OPTIONAL | FIXED |
|---|---|---|---|
| Exist without membership | No | Yes | Depends on INSERTION |
| DISCONNECT allowed | No | Yes | No |
| RECONNECT allowed | Yes | N/A (use DISCONNECT+CONNECT) | No |
| Move between owners | Yes (via RECONNECT) | Yes | No |
| Delete removes from set | Yes | Yes | Yes |
| Typical use case | Employees ↔ Departments | Employees ↔ Projects | Orders ↔ Customers |
The INSERTION clause determines whether storing a new member record automatically inserts it into a set occurrence or requires manual insertion via the CONNECT operation.
INSERTION IS AUTOMATIC:
When a new member record is STOREd, the DBMS automatically inserts it into the appropriate set occurrence. The "appropriate" occurrence is determined by the SET SELECTION clause.
123456789101112131415161718
SET NAME IS DEPARTMENT_EMPLOYEE OWNER IS DEPARTMENT MEMBER IS EMPLOYEE INSERTION IS AUTOMATIC SET SELECTION IS BY VALUE OF DeptCode IN EMPLOYEE /* With AUTOMATIC insertion: */ -- Simply storing the employee connects to departmentMOVE "D100" TO DeptCode IN EMPLOYEE.MOVE "John Smith" TO Name IN EMPLOYEE.STORE EMPLOYEE. -- DBMS finds DEPARTMENT with DeptCode = "D100" -- Automatically inserts employee into that department's set -- One operation does both: create record AND establish relationship -- Application doesn't need explicit CONNECT-- But must provide data for SET SELECTION to workINSERTION IS MANUAL:
When a new member record is STOREd, it is NOT automatically inserted into any set occurrence. The application must explicitly CONNECT it afterward.
123456789101112131415161718192021
SET NAME IS PROJECT_TASK OWNER IS PROJECT MEMBER IS TASK INSERTION IS MANUAL RETENTION IS OPTIONAL /* With MANUAL insertion: */ -- Storing the task does NOT connect it to any projectMOVE "Implement Login" TO TaskDescription IN TASK.STORE TASK. -- Task record created -- Task belongs to NO project yet (OPTIONAL allows this) -- Application must explicitly connectFIND ANY PROJECT USING ProjectCode = "P100".CONNECT TASK TO PROJECT_TASK. -- Now task belongs to Project P100 -- Multiple steps, but application has full control-- Can create tasks, evaluate, then assign to projects laterSome combinations have special implications: MANDATORY + MANUAL requires the application to explicitly CONNECT before any subsequent access. MANDATORY + AUTOMATIC is common—records are born connected and stay connected. OPTIONAL + MANUAL allows full flexibility—records can exist unconnected indefinitely.
When inserting a member into a set (whether automatically on STORE or explicitly via CONNECT), the DBMS must determine which set occurrence to use. If there are 100 departments, which department's employee set should receive the new employee? The SET SELECTION clause specifies this logic.
Selection Methods:
| Method | Description | When to Use |
|---|---|---|
| CURRENT OF SET | Use current currency of set type | When navigation has positioned to desired owner |
| BY VALUE OF field IN OWNER | Match field value to find owner | When member contains foreign key to owner |
| BY STRUCTURAL field = field | Match member field to owner field | Explicit field mapping between record types |
| BY APPLICATION | Application explicitly sets currency | When app has complex selection logic |
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
/* SET SELECTION IS CURRENT OF SET */ SET NAME IS DEPT_MEMO OWNER IS DEPARTMENT MEMBER IS MEMO INSERTION IS AUTOMATIC SET SELECTION IS CURRENT OF DEPT_MEMO -- Application must establish currency BEFORE store:FIND ANY DEPARTMENT USING DeptCode = "D100". -- Department D100 is now CURRENT OF DEPT_MEMOSTORE MEMO. -- Memo inserted into D100's memo set /* SET SELECTION IS BY VALUE OF field IN OWNER */ SET NAME IS DEPARTMENT_EMPLOYEE OWNER IS DEPARTMENT MEMBER IS EMPLOYEE INSERTION IS AUTOMATIC SET SELECTION IS BY VALUE OF DeptCode IN DEPARTMENT -- Employee record contains DeptCode that matches owner:MOVE "D100" TO DeptCode IN EMPLOYEE.MOVE "John Smith" TO Name IN EMPLOYEE.STORE EMPLOYEE. -- DBMS finds DEPARTMENT where DeptCode = "D100" -- Inserts employee into that department's set -- No explicit FIND needed - value-based matching /* SET SELECTION IS STRUCTURAL */ SET NAME IS SUPPLIER_PART OWNER IS SUPPLIER MEMBER IS PART INSERTION IS AUTOMATIC SET SELECTION IS STRUCTURAL SUPPLIER.SupplierID = PART.PrimarySupplier -- Explicit field mapping:MOVE "S1001" TO PrimarySupplier IN PART.STORE PART. -- DBMS finds SUPPLIER where SupplierID = "S1001" -- Inserts part into that supplier's set /* SET SELECTION IS BY APPLICATION */ SET NAME IS PRIORITY_TASK OWNER IS PRIORITY_LEVEL MEMBER IS TASK INSERTION IS MANUAL -- Often paired with MANUAL SET SELECTION IS BY APPLICATION -- Application has full control:-- Evaluate task properties, business rules, etc.IF task-is-urgent FIND ANY PRIORITY_LEVEL USING Level = "HIGH"ELSE FIND ANY PRIORITY_LEVEL USING Level = "NORMAL"END-IF.CONNECT TASK TO PRIORITY_TASK. -- App logic determined the ownerIf SET SELECTION fails to identify a valid owner (e.g., BY VALUE references a non-existent owner record), the STORE or CONNECT operation fails with a database error. For MANDATORY retention, this means the member cannot be stored at all. Robust applications must handle these potential failures.
While most set types have a single member record type, CODASYL allows multi-member sets where one owner can have members of different record types. This enables sophisticated modeling of heterogeneous collections.
Multi-Member Set Structure:
A multi-member set has:
123456789101112131415161718192021222324252627282930313233343536
/* Multi-member set example: Customer has different types of communications */ SET NAME IS CUSTOMER_COMMUNICATION OWNER IS CUSTOMER ORDER IS LAST -- All members ordered by insertion time MEMBER IS PHONE_CALL INSERTION IS AUTOMATIC RETENTION IS FIXED MEMBER IS EMAIL INSERTION IS AUTOMATIC RETENTION IS FIXED MEMBER IS LETTER INSERTION IS MANUAL RETENTION IS OPTIONAL /* Result: Each customer has ONE set occurrence containing: - PHONE_CALL records (automatically linked on creation) - EMAIL records (automatically linked on creation) - LETTER records (manually linked, can be disconnected) All intermixed in insertion order. */ /* Navigation example: */FIND ANY CUSTOMER USING CustomerID = "C1001".FIND FIRST PHONE_CALL WITHIN CUSTOMER_COMMUNICATION. -- Finds first PHONE_CALL (skips EMAIL, LETTER) FIND FIRST ANY WITHIN CUSTOMER_COMMUNICATION. -- Finds first member of ANY type FIND NEXT ANY WITHIN CUSTOMER_COMMUNICATION. -- Next member, whatever type it is -- Could be PHONE_CALL, EMAIL, or LETTERMulti-Member Set Applications:
Heterogeneous Collections: A folder containing different document types (text, images, spreadsheets).
Polymorphic Relationships: An account with various transaction types (deposit, withdrawal, transfer, fee).
Audit Trails: An entity with different kinds of history records (creation, modification, access, deletion).
Event Sourcing: An aggregate root owning different event types in sequence.
Navigation in Multi-Member Sets:
When navigating multi-member sets, you can:
FIND NEXT EMAIL WITHIN CUSTOMER_COMMUNICATIONFIND NEXT ANY WITHIN CUSTOMER_COMMUNICATIONThe DBMS tracks the current record's type, allowing type-conditional processing:
PERFORM UNTIL end-of-set
FIND NEXT ANY WITHIN CUSTOMER_COMMUNICATION
EVALUATE TRUE
WHEN DB-RECORD-NAME = "PHONE_CALL"
PERFORM PROCESS-PHONE-CALL
WHEN DB-RECORD-NAME = "EMAIL"
PERFORM PROCESS-EMAIL
WHEN OTHER
PERFORM PROCESS-OTHER
END-EVALUATE
END-PERFORM
Multi-member sets add modeling flexibility but increase navigation complexity. Programs must handle different record types within the same loop. Modern practice often prefers separate, single-member sets for clarity, using application logic to combine results. However, when members are truly intermixed (like a timeline of different events), multi-member sets model the reality elegantly.
A special case in network databases is the system-owned set (also called SINGULAR set). These sets have a virtual "SYSTEM" owner rather than a user-defined record type.
Purpose of System-Owned Sets:
System-owned sets provide entry points into the database for record types that have no natural owner. They answer the question: "How do I find the first CUSTOMER if CUSTOMER isn't owned by anything?"
Without system-owned sets, records accessible only via CALC (hash) lookup would require knowing a key value. System-owned sets provide sequential access to all records of a type.
123456789101112131415161718192021222324252627282930
/* System-owned set for all customers */ SET NAME IS ALL_CUSTOMERS OWNER IS SYSTEM ORDER IS SORTED BY CustomerName ASCENDING MEMBER IS CUSTOMER INSERTION IS AUTOMATIC RETENTION IS MANDATORY /* Every CUSTOMER record is automatically a member of the single ALL_CUSTOMERS set occurrence owned by SYSTEM. */ /* Navigation: */ -- Find first customer (alphabetically)FIND FIRST CUSTOMER WITHIN ALL_CUSTOMERS. -- Iterate through all customersPERFORM UNTIL end-of-set GET CUSTOMER. DISPLAY CustomerName IN CUSTOMER. FIND NEXT CUSTOMER WITHIN ALL_CUSTOMERS.END-PERFORM. /* Use cases for system-owned sets: 1. Report all records of a type (no CALC key needed) 2. Provide ordered access (sorted by name, date, etc.) 3. Entry point for batch processing 4. Starting point for recursive navigation*/System-Owned Sets vs. CALC Access:
| Aspect | System-Owned Set | CALC Access |
|---|---|---|
| Access pattern | Sequential, ordered | Direct, by key value |
| Find first | FIND FIRST rec WITHIN set | Must know key value |
| Find all | Traverse set | No inherent mechanism |
| Ordering | Controlled by ORDER clause | No ordering |
| Entry point | Always available | Requires prior knowledge |
| Overhead | Maintains linked list | Hash index only |
Well-designed schemas typically use both:
A record type can be a member of multiple system-owned sets with different orderings. ALL_CUSTOMERS_BY_NAME and ALL_CUSTOMERS_BY_REGION could both exist, providing different ordered access paths to the same customer records. This is an early form of what we'd now call secondary indexes.
Sets are far more than simple containers—they're comprehensive behavioral specifications that define how records relate, how they're ordered, and what operations are permissible.
What's Next:
Understanding set structure and semantics prepares us for the operational aspects of network databases. Next, we'll explore navigation—how programmers traverse the network structure, maintain currency, and construct queries by explicitly walking through set relationships. This navigational paradigm is what distinguished network databases from their relational successors.
You now understand the rich semantics of set relationships in the network model. Sets aren't just links—they're behavioral contracts that specify ordering, membership rules, insertion behavior, and selection criteria. This comprehensive approach to relationship specification was remarkably sophisticated for its era. Next, we'll see how programmers navigate through these structures.