Course contentsShow
← Databases & SQL
Lesson 1124 of 1,95310. Embedded and Lightweight DatabasesFree lesson

Constraint Validation Patterns

Enforce business logic at the schema level using check constraints and foreign keys.

In this lesson, you will learn how to shift business logic from your application code directly into the database schema using CHECK constraints and FOREIGN KEY definitions to guarantee data integrity at the source.

Moving Logic Closer to Data

When building embedded applications, it is tempting to validate data (like ensuring an age is positive or a status code is valid) inside your application code. However, if multiple processes or external tools interact with your lightweight database, application-level validation can be bypassed. By enforcing these rules at the schema level, you create a "source of truth" that rejects invalid data regardless of how it is inserted.

Using CHECK Constraints

A CHECK constraint acts as a gatekeeper for a single row. For example, if you are managing a sensor device, you may want to ensure that a temperature reading never drops below absolute zero or exceeds a hardware safety threshold.

CREATE TABLE sensor_logs (
    id INTEGER PRIMARY KEY,
    temperature REAL CHECK(temperature >= -273.15 AND temperature <= 500.0),
    status TEXT CHECK(status IN ('active', 'idle', 'error'))
);

Here, any attempt to insert a temperature of 1000 or a status of 'broken' will cause the database engine to reject the transaction immediately, preventing corrupted data from entering your log.

Using FOREIGN KEY Constraints

While CHECK handles values, FOREIGN KEY constraints manage relationships between entities. In an embedded system with related tables—such as devices and readings—you should ensure that a reading cannot exist without a valid parent device.

CREATE TABLE readings (
    reading_id INTEGER PRIMARY KEY,
    device_id INTEGER,
    FOREIGN KEY(device_id) REFERENCES devices(id) ON DELETE CASCADE
);

By defining this relationship, you ensure that the database engine maintains referential integrity. If a device is deleted, the ON DELETE CASCADE rule ensures that all associated readings are automatically cleaned up, keeping your disk footprint lean and your data consistent without requiring complex application-side cleanup routines.

By baking these validation rules into your CREATE TABLE statements, you reduce the risk of logic errors and offload the burden of data sanitation from your software to the robust, atomic layer of the database engine itself.

Key Takeaway: Enforcing business logic through CHECK and FOREIGN KEY constraints ensures data consistency at the architectural level, preventing invalid state that application code might miss.