Nullable vs not nullable troubleshooting¶
Common issues and solutions for nullable vs not nullable column decisions in ClickHouse and Tinybird.
When to use nullable¶
Optional data¶
Use case: Data that may not be available
Example: User profile fields that are optional
-- Use nullable for optional data CREATE TABLE users ( id UInt32, name String, email Nullable(String), -- Optional field phone Nullable(String) -- Optional field )
External data sources¶
Use case: Data from external sources that may be incomplete
Example: API responses with missing fields
-- Handle incomplete external data CREATE TABLE api_events ( id UInt32, user_id Nullable(UInt32), -- May be missing value Nullable(Float64) -- May be missing )
When to use not nullable¶
Required fields¶
Use case: Data that should always be present
Example: Primary keys and required business fields
-- Use not nullable for required fields CREATE TABLE events ( id UInt32, -- Required timestamp DateTime, -- Required event_type String -- Required )
Performance-critical columns¶
Use case: Columns used in filters and joins
Example: Frequently queried columns
-- Use not nullable for performance CREATE TABLE events ( user_id UInt32, -- Not nullable for performance date Date, -- Not nullable for performance value Float64 )
Performance considerations¶
Nullable performance impact¶
Issue: Nullable columns are slower than non-nullable
Solution: Use nullable only when necessary
-- Avoid nullable for performance-critical columns -- Instead of: Nullable(UInt32) user_id -- Use: UInt32 user_id DEFAULT 0
Index considerations¶
Issue: Nullable columns in indexes can be inefficient
Solution: Use non-nullable columns for indexes
-- Use non-nullable for indexes -- Instead of indexing nullable_column -- Use a computed non-nullable column ALTER TABLE events ADD INDEX idx_safe_column COALESCE(nullable_column, 'default') TYPE minmax GRANULARITY 1
Migration strategies¶
Adding nullable columns¶
Issue: Adding nullable columns to existing tables
Solution: Use ALTER TABLE with default values
-- Add nullable column with default ALTER TABLE events ADD COLUMN optional_field Nullable(String) DEFAULT NULL
Converting nullable to not nullable¶
Issue: Converting nullable columns to not nullable
Solution: Clean data first, then convert
-- Clean data before conversion UPDATE events SET nullable_column = 'default' WHERE nullable_column IS NULL ALTER TABLE events MODIFY COLUMN nullable_column String
Best practices¶
- Use nullable sparingly - Only for truly optional data
- Consider performance - Avoid nullable for frequently queried columns
- Use defaults - Consider default values instead of nullable
- Document decisions - Keep track of nullable vs not nullable choices
- Plan migrations - Consider impact when changing nullability