Type Mapping Encyclopedia — Data Type Mapping Reference
A comprehensive reference for RDBMS-to-RDBMS data type mapping, special type conversions, and character set handling.
MySQL to PostgreSQL Mapping
| MySQL |
PostgreSQL |
Notes |
| TINYINT |
SMALLINT |
TINYINT UNSIGNED -> SMALLINT |
| INT |
INTEGER |
|
| INT UNSIGNED |
BIGINT |
PostgreSQL has no UNSIGNED |
| BIGINT |
BIGINT |
|
| FLOAT |
REAL |
|
| DOUBLE |
DOUBLE PRECISION |
|
| DECIMAL(M,N) |
NUMERIC(M,N) |
Identical |
| VARCHAR(N) |
VARCHAR(N) |
|
| CHAR(N) |
CHAR(N) |
|
| TEXT |
TEXT |
|
| MEDIUMTEXT |
TEXT |
PostgreSQL TEXT has no size limit |
| LONGTEXT |
TEXT |
|
| BLOB |
BYTEA |
|
| LONGBLOB |
BYTEA |
Or use Large Object |
| DATE |
DATE |
|
| DATETIME |
TIMESTAMP |
MySQL: not UTC; PG: timezone option |
| TIMESTAMP |
TIMESTAMPTZ |
MySQL: auto UTC conversion |
| TIME |
TIME |
|
| YEAR |
SMALLINT |
|
| ENUM('a','b') |
VARCHAR + CHECK |
Or CREATE TYPE |
| SET('a','b') |
VARCHAR[] |
Or normalize |
| JSON |
JSONB |
JSONB recommended (indexable) |
| BIT(N) |
BIT(N) |
|
| BOOLEAN |
BOOLEAN |
MySQL TINYINT(1) -> BOOLEAN |
| AUTO_INCREMENT |
GENERATED ALWAYS AS IDENTITY |
Or SERIAL (legacy) |
Special Conversion Patterns
-- MySQL ENUM -> PostgreSQL
-- Method 1: CHECK constraint
CREATE TABLE orders (
status VARCHAR(20) CHECK (status IN ('pending', 'paid', 'shipped'))
);
-- Method 2: Custom type
CREATE TYPE order_status AS ENUM ('pending', 'paid', 'shipped');
CREATE TABLE orders (status order_status);
-- MySQL AUTO_INCREMENT -> PostgreSQL IDENTITY
-- MySQL:
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY);
-- PostgreSQL:
CREATE TABLE users (id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY);
-- MySQL ON UPDATE CURRENT_TIMESTAMP -> PostgreSQL trigger
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_timestamp BEFORE UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION update_modified_column();
Oracle to PostgreSQL Mapping
| Oracle |
PostgreSQL |
Notes |
| NUMBER |
NUMERIC |
Precision specification required |
| NUMBER(N,0) |
INTEGER/BIGINT |
Choose based on size |
| VARCHAR2(N) |
VARCHAR(N) |
|
| CHAR(N) |
CHAR(N) |
|
| CLOB |
TEXT |
|
| BLOB |
BYTEA |
|
| DATE |
TIMESTAMP |
Oracle DATE includes time! |
| TIMESTAMP WITH TIME ZONE |
TIMESTAMPTZ |
|
| RAW |
BYTEA |
|
| LONG |
TEXT |
Deprecated — migration recommended |
| NVARCHAR2 |
VARCHAR |
PostgreSQL defaults to UTF-8 |
| ROWID |
N/A |
Use ctid or custom key |
| SEQUENCE |
SEQUENCE |
Similar syntax |
| SYSDATE |
CURRENT_TIMESTAMP |
|
| NVL() |
COALESCE() |
|
| DECODE() |
CASE WHEN |
|
RDBMS to MongoDB Conversion Patterns
Denormalization Strategy
Relational: Document:
+- users -+ +- orders -+ {
| id | | id | _id: ObjectId,
| name | | user_id |-> name: "John Doe",
| email | | total | email: "john@test.com",
+----------+ | items[] | orders: [
+----------+ { total: 50000,
items: [
{ product: "A", qty: 2 }
]
}
]
}
Embedding vs. Reference Decision
| Criterion |
Embedding (Nested) |
Reference (Separate) |
| Relationship |
1:1, 1:Few |
1:Many, M:N |
| Read pattern |
Always queried together |
Frequently queried independently |
| Update frequency |
Updated with parent |
Updated independently |
| Data size |
< 16MB (document limit) |
Size independent |
| Duplication |
Acceptable |
Deduplication required |
Character Set / Collation Conversion
MySQL to PostgreSQL
-- MySQL character set check
SHOW VARIABLES LIKE 'character_set%';
SELECT character_set_name, collation_name
FROM information_schema.columns WHERE table_name = 'users';
-- PostgreSQL collation
-- MySQL utf8mb4_general_ci -> PostgreSQL ICU collation
CREATE COLLATION korean_ci (
provider = icu, locale = 'ko-u-ks-level1', deterministic = false
);
-- Case-insensitive comparison
-- MySQL: utf8mb4_general_ci (default)
-- PostgreSQL: citext extension or LOWER() index
CREATE EXTENSION IF NOT EXISTS citext;
ALTER TABLE users ALTER COLUMN email TYPE citext;
Encoding Conversion Notes
| Issue |
Symptom |
Solution |
| MySQL utf8 (3-byte) |
Emojis break |
Convert to utf8mb4 before migration |
| Latin1 to UTF8 |
CJK characters corrupted |
Route through binary intermediate step |
| EUC-KR to UTF8 |
Rare CJK characters lost |
Use mapping tables |
| CP949 to UTF8 |
Extended characters need verification |
Pre-validate with iconv |
Irreversible Conversion Inventory
| Conversion |
Reason for Irreversibility |
Mitigation |
| ENUM -> VARCHAR |
Allowed value constraint lost |
Add CHECK constraint |
| UNSIGNED INT -> INT |
Negative range expanded |
Reinforce with business rules |
| DATETIME -> TIMESTAMPTZ |
Timezone info must be added |
Explicitly state assumed TZ |
| ROWID -> ctid |
Physical location dependent |
Replace with logical key |
| Oracle DATE -> PG DATE |
Time portion lost |
Use TIMESTAMP instead |
| CLOB -> TEXT |
Behavior is identical |
-- |
Type Mapping Verification Queries
-- Source (MySQL)
SELECT column_name, data_type, column_type,
character_maximum_length, numeric_precision, numeric_scale,
is_nullable, column_default, extra
FROM information_schema.columns
WHERE table_schema = 'mydb' AND table_name = 'orders'
ORDER BY ordinal_position;
-- Target (PostgreSQL)
SELECT column_name, data_type, udt_name,
character_maximum_length, numeric_precision, numeric_scale,
is_nullable, column_default
FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'orders'
ORDER BY ordinal_position;
1---2name: type-mapping-encyclopedia3description: RDBMS-to-RDBMS data type mapping tables, RDBMS-to-NoSQL conversion patterns, character set/collation conversion, and special type handling guide. Use this skill for requests involving 'type mapping', 'data type conversion', 'MySQL PostgreSQL conversion', 'Oracle migration', 'character set conversion', 'collation', 'AUTO_INCREMENT sequence', 'JSON type', etc. Enhances schema-mapper's type conversion capabilities. Note: ETL script writing and validation queries are outside the scope of this skill.4---56# Type Mapping Encyclopedia — Data Type Mapping Reference78A comprehensive reference for RDBMS-to-RDBMS data type mapping, special type conversions, and character set handling.910## MySQL to PostgreSQL Mapping1112| MySQL | PostgreSQL | Notes |13|-------|-----------|-------|14| TINYINT | SMALLINT | TINYINT UNSIGNED -> SMALLINT |15| INT | INTEGER | |16| INT UNSIGNED | BIGINT | PostgreSQL has no UNSIGNED |17| BIGINT | BIGINT | |18| FLOAT | REAL | |19| DOUBLE | DOUBLE PRECISION | |20| DECIMAL(M,N) | NUMERIC(M,N) | Identical |21| VARCHAR(N) | VARCHAR(N) | |22| CHAR(N) | CHAR(N) | |23| TEXT | TEXT | |24| MEDIUMTEXT | TEXT | PostgreSQL TEXT has no size limit |25| LONGTEXT | TEXT | |26| BLOB | BYTEA | |27| LONGBLOB | BYTEA | Or use Large Object |28| DATE | DATE | |29| DATETIME | TIMESTAMP | MySQL: not UTC; PG: timezone option |30| TIMESTAMP | TIMESTAMPTZ | MySQL: auto UTC conversion |31| TIME | TIME | |32| YEAR | SMALLINT | |33| ENUM('a','b') | VARCHAR + CHECK | Or CREATE TYPE |34| SET('a','b') | VARCHAR[] | Or normalize |35| JSON | JSONB | JSONB recommended (indexable) |36| BIT(N) | BIT(N) | |37| BOOLEAN | BOOLEAN | MySQL TINYINT(1) -> BOOLEAN |38| AUTO_INCREMENT | GENERATED ALWAYS AS IDENTITY | Or SERIAL (legacy) |3940### Special Conversion Patterns4142```sql43-- MySQL ENUM -> PostgreSQL44-- Method 1: CHECK constraint45CREATE TABLE orders (46 status VARCHAR(20) CHECK (status IN ('pending', 'paid', 'shipped'))47);4849-- Method 2: Custom type50CREATE TYPE order_status AS ENUM ('pending', 'paid', 'shipped');51CREATE TABLE orders (status order_status);5253-- MySQL AUTO_INCREMENT -> PostgreSQL IDENTITY54-- MySQL:55CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY);56-- PostgreSQL:57CREATE TABLE users (id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY);5859-- MySQL ON UPDATE CURRENT_TIMESTAMP -> PostgreSQL trigger60CREATE OR REPLACE FUNCTION update_modified_column()61RETURNS TRIGGER AS $$62BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END;63$$ LANGUAGE plpgsql;64CREATE TRIGGER update_timestamp BEFORE UPDATE ON users65FOR EACH ROW EXECUTE FUNCTION update_modified_column();66```6768## Oracle to PostgreSQL Mapping6970| Oracle | PostgreSQL | Notes |71|--------|-----------|-------|72| NUMBER | NUMERIC | Precision specification required |73| NUMBER(N,0) | INTEGER/BIGINT | Choose based on size |74| VARCHAR2(N) | VARCHAR(N) | |75| CHAR(N) | CHAR(N) | |76| CLOB | TEXT | |77| BLOB | BYTEA | |78| DATE | TIMESTAMP | Oracle DATE includes time! |79| TIMESTAMP WITH TIME ZONE | TIMESTAMPTZ | |80| RAW | BYTEA | |81| LONG | TEXT | Deprecated — migration recommended |82| NVARCHAR2 | VARCHAR | PostgreSQL defaults to UTF-8 |83| ROWID | N/A | Use ctid or custom key |84| SEQUENCE | SEQUENCE | Similar syntax |85| SYSDATE | CURRENT_TIMESTAMP | |86| NVL() | COALESCE() | |87| DECODE() | CASE WHEN | |8889## RDBMS to MongoDB Conversion Patterns9091### Denormalization Strategy9293```94Relational: Document:95+- users -+ +- orders -+ {96| id | | id | _id: ObjectId,97| name | | user_id |-> name: "John Doe",98| email | | total | email: "john@test.com",99+----------+ | items[] | orders: [100 +----------+ { total: 50000,101 items: [102 { product: "A", qty: 2 }103 ]104 }105 ]106 }107```108109### Embedding vs. Reference Decision110111| Criterion | Embedding (Nested) | Reference (Separate) |112|-----------|-------------------|---------------------|113| Relationship | 1:1, 1:Few | 1:Many, M:N |114| Read pattern | Always queried together | Frequently queried independently |115| Update frequency | Updated with parent | Updated independently |116| Data size | < 16MB (document limit) | Size independent |117| Duplication | Acceptable | Deduplication required |118119## Character Set / Collation Conversion120121### MySQL to PostgreSQL122123```sql124-- MySQL character set check125SHOW VARIABLES LIKE 'character_set%';126SELECT character_set_name, collation_name127FROM information_schema.columns WHERE table_name = 'users';128129-- PostgreSQL collation130-- MySQL utf8mb4_general_ci -> PostgreSQL ICU collation131CREATE COLLATION korean_ci (132 provider = icu, locale = 'ko-u-ks-level1', deterministic = false133);134135-- Case-insensitive comparison136-- MySQL: utf8mb4_general_ci (default)137-- PostgreSQL: citext extension or LOWER() index138CREATE EXTENSION IF NOT EXISTS citext;139ALTER TABLE users ALTER COLUMN email TYPE citext;140```141142### Encoding Conversion Notes143144| Issue | Symptom | Solution |145|-------|---------|----------|146| MySQL utf8 (3-byte) | Emojis break | Convert to utf8mb4 before migration |147| Latin1 to UTF8 | CJK characters corrupted | Route through binary intermediate step |148| EUC-KR to UTF8 | Rare CJK characters lost | Use mapping tables |149| CP949 to UTF8 | Extended characters need verification | Pre-validate with iconv |150151## Irreversible Conversion Inventory152153| Conversion | Reason for Irreversibility | Mitigation |154|-----------|--------------------------|-----------|155| ENUM -> VARCHAR | Allowed value constraint lost | Add CHECK constraint |156| UNSIGNED INT -> INT | Negative range expanded | Reinforce with business rules |157| DATETIME -> TIMESTAMPTZ | Timezone info must be added | Explicitly state assumed TZ |158| ROWID -> ctid | Physical location dependent | Replace with logical key |159| Oracle DATE -> PG DATE | Time portion lost | Use TIMESTAMP instead |160| CLOB -> TEXT | Behavior is identical | -- |161162## Type Mapping Verification Queries163164```sql165-- Source (MySQL)166SELECT column_name, data_type, column_type,167 character_maximum_length, numeric_precision, numeric_scale,168 is_nullable, column_default, extra169FROM information_schema.columns170WHERE table_schema = 'mydb' AND table_name = 'orders'171ORDER BY ordinal_position;172173-- Target (PostgreSQL)174SELECT column_name, data_type, udt_name,175 character_maximum_length, numeric_precision, numeric_scale,176 is_nullable, column_default177FROM information_schema.columns178WHERE table_schema = 'public' AND table_name = 'orders'179ORDER BY ordinal_position;180```