INSERT Statement Syntax and Options
When inserting a row, the important choice for a PRIMARY KEY column is whether to supply a value or omit the column.
Try it: Keys and Constraints
How SQLite enforces PRIMARY KEY, UNIQUE, NOT NULL and FOREIGN KEY constraints on INSERT and DELETE, how an INTEGER PRIMARY KEY assigns ids (with and without AUTOINCREMENT), what INSERT OR IGNORE skips, and what ON DELETE RESTRICT, CASCADE and SET NULL do to child rows.
How it works
- INSERT: a NULL id is replaced by max(id) + 1 — or, with AUTOINCREMENT, by one more than the largest id ever used — and last_insert_rowid() reports it.
- Constraints are checked in order: NOT NULL, then the PRIMARY KEY, then UNIQUE, then the FOREIGN KEY (the parent row must exist). The first failure aborts the statement with SQLite's error message.
- INSERT OR IGNORE silently skips a row that breaks NOT NULL, PRIMARY KEY or UNIQUE — but a foreign-key failure is still an error.
- DELETE of a parent row that has children: RESTRICT refuses, CASCADE deletes the children too, SET NULL clears their foreign key. None of this happens unless PRAGMA foreign_keys = ON (SQLite's default is OFF).
Default run (5 steps): 3 artists and 3 albums. PRAGMA foreign_keys = ON, ON DELETE RESTRICT. Choose an operation. Example: INSERT INTO artist (name) VALUES ('Queen'). … Error: UNIQUE constraint failed: artist.name. Nothing was changed (the statement is rolled back).
Simplified: A toy relational engine in the browser, not SQLite itself: a small structured query model built from the controls (no SQL text is parsed or executed), typed INTEGER/TEXT/NULL values, and tables of at most a few rows. Results were checked against Python's sqlite3 (SQLite 3.49). Two fixed tables of at most 8 rows and ids up to 99; changing the schema recreates the tables with the starting rows. Error texts and ids were checked step by step against sqlite3.
Loading the simulation…
Why Separate Roles
Suppose many Member rows need to record roles such as administrator, editor, or reviewer. Role normalization moves role information into a dedicated Role table instead of repeating that information throughout the Member table. The Member table then stores a role_id value that points to the appropriate Role record.
Role Table Constraints
The normalized design gives the Role table two important constraints. Its id column is the PRIMARY KEY, identifying each Role record. Its name column is UNIQUE, so role names cannot be repeated. The Member table does not store the role name as its link; it uses role_id to reference the Role table's id column.
| Table | Column | Constraint or role |
|---|---|---|
| Role | id | PRIMARY KEY |
| Role | name | UNIQUE |
| Member | role_id | Foreign key referencing Role.id |
The columns and constraints used to centralize role information
PRIMARY KEY and UNIQUE both restrict duplication, but they apply to different columns in this design: the Role id column is the primary identifier, while the Role name column must also remain unique.
Member-to-Role Linking
A Member row points to a Role row through role_id. The value in Member.role_id must identify an existing Role record. This is the purpose of the foreign key constraint: it enforces referential integrity and prevents a Member row from referring to a Role that does not exist.
Connecting a member to an existing role
A Member must be assigned the Role record whose id represents the editor role.
- 1Find the Role record
Use the existing Role record identified by its id. The Role table centralizes the role information.
- 2Store the identifier
Insert the corresponding identifier into the Member row's
role_idcolumn. - 3Check the reference
The foreign key requires the referenced Role record to exist. A Member row cannot point to a non-existent Role record.
The Member row is linked to the centralized Role record through role_id.
Choosing INSERT Columns
When inserting a row, the important choice for a PRIMARY KEY column is whether to supply a value or omit the column. If you omit the PRIMARY KEY value, the database can generate it. If you include the column, you are manually assigning its value, and that value must satisfy the table's constraints.
Inserting a Role without choosing its id
Add a new Role named editor while allowing the database to generate the Role id.
- 1Omit the PRIMARY KEY column
The insertion supplies the role information but does not manually assign Role.id.
- 2Allow generation
Because the PRIMARY KEY value is omitted, the database can generate it.
- 3Use the generated identifier
The resulting Role identifier is the value that a related Member row can use in
role_id.
A Role record is added without manually choosing its PRIMARY KEY value.
Manual Primary Keys
A PRIMARY KEY value may also be assigned manually during insertion. The assigned value must be unique and must not already be present in the table. If it duplicates an existing PRIMARY KEY value, the insertion violates the PRIMARY KEY constraint. Manual assignment is therefore an option with a restriction, not permission to reuse any identifier.
What do you think happens?
A Role table already contains a row with a particular id. What should happen if another insertion manually assigns that same id?
Reveal answer
The insertion violates the PRIMARY KEY constraint.
The source requires manually assigned PRIMARY KEY values to be unique and not already present.
Mistakes with Insertions
Common mistake Repeating role names in Member rows instead of centralizing them in Role.
What it looks likeSeveral Member rows independently store the same role information.
Why it failsThe normalized design is intended to separate role information into a dedicated Role table and eliminate redundancy.
Do this insteadStore the role once in Role and connect each Member through role_id.
Common mistake Using a role_id that does not identify an existing Role record.
What it looks likeA Member insertion refers to a Role identifier that is not present in Role.
Why it failsThe foreign key enforces referential integrity and prevents references to non-existent Role records.
Do this insteadReference an existing Role record.
Common mistake Manually assigning a PRIMARY KEY value that already exists.
What it looks likeA new Role insertion uses an id already assigned to another Role row.
Why it failsPRIMARY KEY values must be unique and not already present.
Do this insteadUse a new unique value or omit the PRIMARY KEY so the database can generate it.
Common mistake Assuming that every insertion must manually provide a PRIMARY KEY.
What it looks likeThe insertion always supplies Role.id even though automatic generation is available.
Why it failsPRIMARY KEY values can be omitted to allow database generation.
Do this insteadOmit the PRIMARY KEY column when you want the database to generate its value.
Practice Decisions
For each situation, decide whether the insertion should manually assign the PRIMARY KEY or omit it: adding a new Role when the database should generate identifiers; adding a Role with a deliberately chosen unused identifier; adding a Role using an identifier already present; and adding a Member whose role_id points to no existing Role.
Hints
- Omitting the PRIMARY KEY allows database generation.
- A manually assigned PRIMARY KEY must be unique and not already present.
- A Member foreign key must reference an existing Role record.
Checking four insertion choices
Evaluate the four practice situations using the Role and Member constraints.
- 1Generated Role identifier
Omit the Role PRIMARY KEY value so the database can generate it.
- 2Unused manual identifier
Manual assignment is allowed when the chosen PRIMARY KEY value is unique and not already present.
- 3Existing manual identifier
Reject the choice because a duplicate PRIMARY KEY value violates the constraint.
- 4Missing referenced Role
Reject the Member reference because the foreign key cannot point to a non-existent Role record.
The valid choices depend on both insertion behavior and the constraints protecting Role and Member.
Key Takeaways
- 1Role normalization places role information in a dedicated Role table, reducing redundancy and centralizing role management.
- 2Role.id is the PRIMARY KEY, Role.name is UNIQUE, and Member.role_id references Role.id through a foreign key.
- 3A PRIMARY KEY value can be omitted during insertion so the database can generate it.
- 4A manually assigned PRIMARY KEY must be unique and must not already exist.
- 5Foreign key enforcement prevents Member rows from referring to non-existent Role records.
At a glance
- Normalize repeated role information by creating a separate Role table.
- Use Role.id as the PRIMARY KEY and Role.name as a UNIQUE column.
- Link Member to Role with the Member.role_id foreign key.
- Omit a PRIMARY KEY value when the database should generate it.
- Manually supplied PRIMARY KEY values must be unique and not already present.