Referential integrity is the guarantee that foreign-key relationships stay valid — every child row points to an existing parent. An orphaned record is a child whose parent no longer exists (an order referencing a deleted user, an order_item referencing a missing order). Testers query for orphans to catch integrity defects.
Foreign keys model relationships (orders.user_id → users.id). When enforced by the database, they prevent orphans automatically. But integrity breaks down when constraints are missing, disabled for performance, or bypassed by bulk imports and soft-delete logic — and then orphaned records accumulate, causing broken pages, failed joins, and incorrect reports. The tester's job is to detect these gaps. The standard technique is the anti-join: LEFT JOIN the child to the parent and filter WHERE parent.id IS NULL to list children with no valid parent (or the equivalent NOT EXISTS). This should be run after operations that could break links, especially deletes and migrations. Related checks include verifying cascade behavior (does deleting a user correctly delete or reassign their orders per the spec) and confirming soft-deletes don't leave active children pointing at a logically-deleted parent. These checks are high value because orphaned data often passes functional tests yet corrupts analytics and crashes edge-case flows.
After a bulk user-deletion job, a tester checks for orphaned orders: SELECT o.id FROM orders o LEFT JOIN users u ON u.id = o.user_id WHERE u.id IS NULL — any returned order references a user that no longer exists, revealing the delete job didn't handle related orders.
-- Orphaned orders: reference a user that doesn't exist
SELECT o.id, o.user_id
FROM orders o
LEFT JOIN users u ON u.id = o.user_id
WHERE u.id IS NULL;
-- Orphaned line items: reference a missing order or product
SELECT oi.id
FROM order_items oi
LEFT JOIN orders o ON o.id = oi.order_id
WHERE o.id IS NULL;
SELECT oi.id
FROM order_items oi
WHERE NOT EXISTS (SELECT 1 FROM products p WHERE p.id = oi.product_id);
-- Soft-delete integrity: active orders pointing at a soft-deleted user
SELECT o.id
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE u.deleted_at IS NOT NULL AND o.status = 'confirmed';Scenario: After a data migration, some order-detail pages crash with 'user not found', but all the automated functional tests pass. You suspect orphaned records. How do you confirm it with SQL, and what checks would you add to catch this class of bug earlier?