โ Back to list

postgres-schema
by eco2-team
๐ฑ ์ด์ฝ์์ฝ(Ecoยฒ) BE
โญ 0๐ด 0๐
Jan 25, 2026
SKILL.md
name: postgres-schema description: PostgreSQL ์คํค๋ง ์ค๊ณ ๊ฐ์ด๋. DDL ์์ฑ, ํ ์ด๋ธ ์ค๊ณ, ์ธ๋ฑ์ค ์ ๋ต, ๋ง์ด๊ทธ๋ ์ด์ ์ ์ฐธ์กฐ. "schema", "ddl", "table", "migration", "index", "constraint" ํค์๋๋ก ํธ๋ฆฌ๊ฑฐ.
PostgreSQL Schema Design Guide
Quick Reference
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Schema Design Principles โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ 1. TEXT ๊ธฐ๋ณธ โ VARCHAR ์์ธ (RFC ํ์ค๋ง) โ
โ 2. TIMESTAMPTZ ํ์ (ํ์์กด ๋ณด์กด) โ
โ 3. ENUM ์ ํ์ (๊ณ ์ ๊ฐ ์งํฉ๋ง) โ
โ 4. Partial Index ํ์ฉ (NULL ์ ์ธ) โ
โ 5. CASCADE ๋ช
์์ ์ค์ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Naming Conventions
| Type | Pattern | Example |
|---|---|---|
| Schema | ๋๋ฉ์ธ ์๋ฌธ์ | chat, users, auth |
| Table | snake_case ๋ณต์ํ | sessions, social_accounts |
| Column | snake_case | user_id, created_at |
| PK | id | id UUID PRIMARY KEY |
| FK Column | {entity}_id | session_id, user_id |
| Index | idx_{table}_{columns} | idx_sessions_user_updated |
| Constraint | {type}_{table}_{column} | fk_user, chk_role |
Column Type Strategy
1. TEXT ๊ธฐ๋ณธ ์์น
-- ์ข์ ์: ๊ธธ์ด ๋ถํ์คํ ์ปฌ๋ผ์ TEXT
content TEXT NOT NULL,
title TEXT NOT NULL,
description TEXT,
-- ๋์ ์: ์์ ๊ธธ์ด ์ ํ
title VARCHAR(255) NOT NULL, -- ์ 255์ธ๊ฐ?
2. VARCHAR ์์ธ (RFC/ํ์ค ๊ธฐ๋ฐ๋ง)
-- ์ด๋ฉ์ผ: RFC 5321 (64 + 1 + 255 = 320)
email VARCHAR(320) NOT NULL,
-- ์ ํ๋ฒํธ: E.164 ํ์ค (์ต๋ 15์๋ฆฌ + ๊ตญ๊ฐ์ฝ๋)
phone_number VARCHAR(20) UNIQUE,
-- ISO ์ฝ๋๋ฅ
country_code CHAR(2), -- ISO 3166-1 alpha-2
currency_code CHAR(3), -- ISO 4217
language_code VARCHAR(5), -- BCP 47 (ko-KR)
3. ENUM ์ฌ์ฉ ๊ธฐ์ค
-- ์ข์ ์: ๊ฐ ์งํฉ์ด ๊ณ ์ ๋๊ณ ๋ณ๊ฒฝ์ด ๋๋ฌธ ๊ฒฝ์ฐ
role VARCHAR(10) NOT NULL CHECK (role IN ('user', 'assistant')),
type VARCHAR(20) NOT NULL CHECK (type IN ('text', 'image', 'generated_image')),
-- ๋์: PostgreSQL ENUM ํ์
(๋ง์ด๊ทธ๋ ์ด์
์ฃผ์)
CREATE TYPE message_role AS ENUM ('user', 'assistant');
ENUM vs CHECK ๋น๊ต:
| ๋ฐฉ์ | ์ฅ์ | ๋จ์ |
|---|---|---|
| CHECK | ๋ง์ด๊ทธ๋ ์ด์ ์ฌ์, ๊ฐ ์ถ๊ฐ ๊ฐ๋จ | ์คํ ๊ฐ๋ฅ์ฑ |
| ENUM TYPE | ํ์ ์์ ์ฑ, ์ ์ฅ ๊ณต๊ฐ ํจ์จ | ๊ฐ ์ถ๊ฐ ์ ALTER TYPE ํ์ |
Timestamp Rules
-- ํ์: TIMESTAMPTZ ์ฌ์ฉ (ํ์์กด ๋ณด์กด)
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- ๊ธ์ง: TIMESTAMP WITHOUT TIME ZONE
created_at TIMESTAMP NOT NULL, -- ํ์์กด ์ ๋ณด ์์ค
SQLAlchemy์์ ์๋ ๊ฐฑ์ :
updated_at: Mapped[datetime] = mapped_column(
TIMESTAMP(timezone=True),
server_default=func.now(),
onupdate=func.now(),
)
Constraint Patterns
Foreign Key
-- CASCADE: ๋ถ๋ชจ ์ญ์ ์ ์์๋ ์ญ์ (1:N ์ข
์ ๊ด๊ณ)
CONSTRAINT fk_session FOREIGN KEY (session_id)
REFERENCES chat.sessions(id) ON DELETE CASCADE,
-- SET NULL: ๋ถ๋ชจ ์ญ์ ์ NULL๋ก ์ค์ (์ ํ์ ์ฐธ์กฐ)
CONSTRAINT fk_assignee FOREIGN KEY (assignee_id)
REFERENCES users.accounts(id) ON DELETE SET NULL,
-- RESTRICT: ์์ ์์ผ๋ฉด ๋ถ๋ชจ ์ญ์ ๋ฐฉ์ง (๋ณดํธ)
CONSTRAINT fk_owner FOREIGN KEY (owner_id)
REFERENCES users.accounts(id) ON DELETE RESTRICT,
Check Constraints
-- ๊ฐ ๊ฒ์ฆ
CONSTRAINT chk_role CHECK (role IN ('user', 'assistant')),
CONSTRAINT chk_type CHECK (type IN ('text', 'image', 'generated_image')),
-- ๋ฒ์ ๊ฒ์ฆ
CONSTRAINT chk_message_count CHECK (message_count >= 0),
Unique Constraints
-- ๋จ์ผ ์ ๋ํฌ
email VARCHAR(320) UNIQUE NOT NULL,
-- ๋ณตํฉ ์ ๋ํฌ (๋ช
๋ช
๋ ์ ์ฝ์กฐ๊ฑด)
CONSTRAINT uq_social_provider UNIQUE (provider, provider_user_id),
Index Strategy
๊ธฐ๋ณธ ์ธ๋ฑ์ค
-- ์กฐํ ํจํด ๊ธฐ๋ฐ ์ธ๋ฑ์ค
CREATE INDEX idx_sessions_user_updated
ON chat.sessions(user_id, updated_at DESC);
-- ํ์คํ ๋ฆฌ ์กฐํ์ฉ
CREATE INDEX idx_messages_session_ts
ON chat.messages(session_id, timestamp DESC);
Partial Index (์กฐ๊ฑด๋ถ ์ธ๋ฑ์ค)
-- NULL ์ ์ธ๋ก ์ธ๋ฑ์ค ํฌ๊ธฐ ์ต์ ํ
CREATE INDEX idx_accounts_nickname
ON users.accounts(nickname)
WHERE nickname IS NOT NULL;
-- Soft delete ์ง์
CREATE INDEX idx_sessions_active
ON chat.sessions(user_id, updated_at DESC)
WHERE is_deleted = FALSE;
Soft Delete Pattern
-- ๊ถ์ฅ: Boolean ํ๋๊ทธ
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
-- ๋์: ์ญ์ ์๊ฐ ๊ธฐ๋ก
deleted_at TIMESTAMPTZ,
-- ์ธ๋ฑ์ค์์ ์ญ์ ๋ ํ ์ ์ธ
CREATE INDEX idx_sessions_user_updated
ON chat.sessions(user_id, updated_at DESC)
WHERE is_deleted = FALSE;
Standard DDL Template
-- 1. Schema ์์ฑ
CREATE SCHEMA IF NOT EXISTS {schema_name};
-- 2. Table ์์ฑ
CREATE TABLE {schema_name}.{table_name} (
-- PK
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- FK
{parent}_id UUID NOT NULL,
-- Data columns
{column} {TYPE} [NOT NULL] [DEFAULT value],
-- Timestamps
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Soft delete (์ ํ)
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
-- Constraints
CONSTRAINT fk_{parent} FOREIGN KEY ({parent}_id)
REFERENCES {parent_schema}.{parent_table}(id) ON DELETE CASCADE,
CONSTRAINT chk_{column} CHECK ({column} IN ('val1', 'val2'))
);
-- 3. Index ์์ฑ
CREATE INDEX idx_{table}_{columns}
ON {schema_name}.{table_name}({columns})
[WHERE condition];
-- 4. Comment (์ ํ)
COMMENT ON TABLE {schema_name}.{table_name} IS 'ํ
์ด๋ธ ์ค๋ช
';
COMMENT ON COLUMN {schema_name}.{table_name}.{column} IS '์ปฌ๋ผ ์ค๋ช
';
Migration Structure
migrations/schemas/
โโโ 001_users_schema.sql # users ์คํค๋ง
โโโ 002_auth_schema.sql # auth ์คํค๋ง
โโโ 003_chat_schema.sql # chat ์คํค๋ง (์ ๊ท)
โโโ README.md # ๋ง์ด๊ทธ๋ ์ด์
๊ฐ์ด๋
Review Checklist
DDL ๋ฆฌ๋ทฐ ์ ํ์ธํ ํญ๋ชฉ:
- TEXT vs VARCHAR: VARCHAR๋ RFC ํ์ค ๊ธฐ๋ฐ์ธ๊ฐ?
- TIMESTAMPTZ: ๋ชจ๋ ์๊ฐ ์ปฌ๋ผ์ด ํ์์กด ํฌํจ์ธ๊ฐ?
- FK CASCADE: ์ญ์ ๋์์ด ๋ช ์์ ์ผ๋ก ์ค์ ๋์๋๊ฐ?
- Index: ์ฃผ์ ์กฐํ ํจํด์ ์ธ๋ฑ์ค๊ฐ ์๋๊ฐ?
- Partial Index: Soft delete๋ NULL ์ปฌ๋ผ์ ์กฐ๊ฑด๋ถ ์ธ๋ฑ์ค ์ ์ฉ?
- Naming: ์ปจ๋ฒค์ ์ ๋ฐ๋ฅด๋๊ฐ?
- NOT NULL: ํ์ ์ปฌ๋ผ์ NOT NULL ์ ์ฝ์ด ์๋๊ฐ?
- DEFAULT: ์ ์ ํ ๊ธฐ๋ณธ๊ฐ์ด ์ค์ ๋์๋๊ฐ?
Reference Files
- DDL conventions: See ddl-conventions.md
- Index strategy: See index-strategy.md
Ecoยฒ Project Notes
- ๋ธ๋ก๊ทธ ์ฐธ์กฐ: https://rooftopsnow.tistory.com/132
- ๊ธฐ์กด ์คํค๋ง:
migrations/schemas/users_schema.sql - ORM: SQLAlchemy 2.0 with asyncpg
Score
Total Score
60/100
Based on repository quality metrics
โSKILL.md
SKILL.mdใใกใคใซใๅซใพใใฆใใ
+20
โLICENSE
ใฉใคใปใณในใ่จญๅฎใใใฆใใ
+10
โ่ชฌๆๆ
100ๆๅญไปฅไธใฎ่ชฌๆใใใ
0/10
โไบบๆฐ
GitHub Stars 100ไปฅไธ
0/15
โๆ่ฟใฎๆดปๅ
3ใถๆไปฅๅ ใซๆดๆฐใใใ
0/10
โใใฉใผใฏ
10ๅไปฅไธใใฉใผใฏใใใฆใใ
0/5
โIssue็ฎก็
ใชใผใใณIssueใ50ๆชๆบ
+5
โ่จ่ช
ใใญใฐใฉใใณใฐ่จ่ชใ่จญๅฎใใใฆใใ
+5
โใฟใฐ
1ใคไปฅไธใฎใฟใฐใ่จญๅฎใใใฆใใ
0/5
Reviews
๐ฌ
Reviews coming soon