Overview
This guide provides recommendations for working with common data types in Metadb. Following these practices ensures consistency, accuracy, and compatibility across your analytics environment.Text and Character Data
Use TEXT for Strings
TheTEXT data type is recommended for strings of characters without length constraints.
VARCHAR for Legacy Compatibility
UseVARCHAR(n) only when working with older database clients that require explicit length specifications:
Comparison
| Type | Use Case | Length Limit |
|---|---|---|
TEXT | Recommended for all new development | Unlimited (up to 1GB) |
VARCHAR(n) | Legacy applications requiring fixed length | Specified by n |
VARCHAR | Equivalent to TEXT | Unlimited |
CHAR(n) | Fixed-length fields (avoid if possible) | Exactly n characters |
TEXT, VARCHAR, and CHAR all use the same internal storage mechanism in PostgreSQL, so there’s no performance difference.Numeric and Monetary Data
Monetary Amounts
For monetary values, useNUMERIC(19, 4) to avoid floating-point rounding errors:
- 19 total digits (sufficient for large amounts)
- 4 decimal places (handles sub-cent precision)
- Exact decimal representation (no rounding errors)
Exchange Rates
For currency exchange rates, useNUMERIC(19, 14) for higher precision:
Example: Calculating with Monetary Data
Numeric Type Comparison
| Type | Precision | Use Case |
|---|---|---|
NUMERIC(19, 4) | Exact, 4 decimal places | Monetary amounts |
NUMERIC(19, 14) | Exact, 14 decimal places | Exchange rates |
INTEGER | Exact, no decimals | Counts, IDs |
BIGINT | Exact, larger range | Large counts |
REAL | Approximate, 6 decimal digits | ❌ Avoid for money |
DOUBLE PRECISION | Approximate, 15 decimal digits | ❌ Avoid for money |
Date and Time Data
Querying Date Ranges
The most reliable method for querying within date ranges uses the inequality patternstart <= t < end:
Why this pattern?
- Handles timestamps precisely without worrying about time components
- Prevents off-by-one errors at boundaries
- Works correctly with
DATEandTIMESTAMPcolumns - Aligns with interval semantics
[start, end)
Date Range Examples
Avoid Common Date Pitfalls
Date Type Recommendations
| Type | Use Case | Example |
|---|---|---|
DATE | Calendar dates without time | 2023-01-01 |
TIMESTAMP | Date and time without timezone | 2023-01-01 14:30:00 |
TIMESTAMPTZ | Date and time with timezone (recommended) | 2023-01-01 14:30:00+00 |
TIME | Time of day without date | 14:30:00 |
INTERVAL | Duration or time span | '2 days 3 hours' |
UUID (Universally Unique Identifiers)
Metadb uses UUIDs extensively for identifiers.Working with UUIDs
The
__id column in Metadb tables is a BIGINT surrogate key, not a UUID. Don’t confuse it with id columns from source data, which may be UUIDs.Boolean Data
PostgreSQL supports native boolean types:Boolean Values
| Literal | Type | Notes |
|---|---|---|
TRUE, true, 't', 'true', 'y', 'yes', '1' | True | |
FALSE, false, 'f', 'false', 'n', 'no', '0' | False | |
NULL | Unknown | Three-valued logic |
JSON and JSONB
Metadb often works with JSON data from source systems.JSONB vs JSON
Always useJSONB (binary JSON) rather than JSON:
| Feature | JSONB | JSON |
|---|---|---|
| Storage | Binary, decomposed | Text, exact copy |
| Indexing | Supported | Limited |
| Query performance | Fast | Slower |
| Whitespace preservation | No | Yes |
| Key order preservation | No | Yes |
Querying JSON Data
Consider Transformed Tables
Instead of repeatedly extracting JSON fields, use transformed tables for better performance and simpler queries.Array Types
PostgreSQL supports array types for any data type:Best Practices Summary
Text Data
Use
TEXT for strings; VARCHAR(n) only for legacy compatibilityMoney
Use
NUMERIC(19, 4) for amounts; NUMERIC(19, 14) for exchange ratesDates
Use
start <= date AND date < end pattern for rangesJSON
Prefer
JSONB over JSON; consider transformed tablesAdditional Resources
- Querying Data Guide - Learn about table types and metadata columns
- PostgreSQL Data Types Documentation - Complete PostgreSQL type reference
