9148c358d0
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
5.1 KiB
5.1 KiB
id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id | title | category | status | source_trust_level | verification_status | created_at | updated_at | tags | tech_stack | applied_in | aliases | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| cs-snowflake-id-generation | ID 생성 — UUID v7 / Snowflake / KSUID | Coding | draft | B | conceptual | 2026-05-09 | 2026-05-09 |
|
|
|
ID Generation
AUTO_INCREMENT = 한계 (분산 X). UUID v4 = 안 정렬. UUID v7 / Snowflake / KSUID = 시간 정렬 + 분산 OK + 인덱스 friendly.
📖 핵심 개념
- 시간 정렬: 최신 INSERT 가 인덱스 끝 (페이지 수 적게).
- 분산 생성: 중앙 service 없이 다중 노드.
- 비밀: UUID v4 가 추측 불가 (URL 안전).
- 길이: 16-26 byte.
💻 코드 패턴
UUID v7 (modern, 표준 RFC 9562)
import { v7 as uuidv7 } from 'uuid';
const id = uuidv7();
// "01918fec-d2c5-7000-8aab-1234abcd"
// 첫 48 bit = unix ms timestamp → 시간 정렬
-- Postgres 17+
SELECT uuidv7();
→ UUID v4 호환 + 시간 정렬. 2026 권장 디폴트.
Snowflake (Twitter)
64-bit:
41 bit: timestamp (ms since epoch)
10 bit: machine ID
12 bit: sequence (per ms)
→ ms 당 4096 ID, 1024 machines.
class Snowflake {
private seq = 0;
private lastMs = 0;
constructor(private machineId: number) {}
next(): bigint {
const now = Date.now();
if (now === this.lastMs) {
this.seq++;
if (this.seq >= 4096) {
// wait for next ms
while (Date.now() === this.lastMs);
return this.next();
}
} else {
this.seq = 0;
}
this.lastMs = now;
return (BigInt(now) << 22n) | (BigInt(this.machineId) << 12n) | BigInt(this.seq);
}
}
→ 64-bit (BigInt). 빠르고 정렬. machine ID 충돌 위험.
KSUID (Segment)
import { KSUID } from 'ksuid';
const id = KSUID.randomSync().string;
// "0ujsswThIGTUYm2K8FjOOfXtY1K"
// 27 글자, 첫 4 byte = 32-bit unix seconds, 16 byte random
→ 27 char, sortable, URL-safe.
ULID
import { ulid } from 'ulid';
const id = ulid();
// "01ARZ3NDEKTSV4RRFFQ69G5FAV"
// 26 글자, 첫 10 = ms timestamp, 16 = random
→ KSUID 비슷, 더 짧음.
NanoID (random, secure)
import { nanoid } from 'nanoid';
const id = nanoid(); // 21 char
const short = nanoid(10); // 10 char
→ URL-safe, 빠름. 단 시간 정렬 X.
CUID2
import { createId } from '@paralleldrive/cuid2';
const id = createId();
→ Collision-resistant + URL-safe + 시간 정렬.
Postgres column type
-- UUID
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT uuidv7() -- PG 17+
);
-- 또는 string
CREATE TABLE orders (
id TEXT PRIMARY KEY -- KSUID / ULID / NanoID
);
-- BIGINT (Snowflake)
CREATE TABLE orders (
id BIGINT PRIMARY KEY
);
인덱스 영향
v4 UUID: random → 매 INSERT 가 인덱스 random page → 큰 cache miss.
v7 UUID: 시간 정렬 → 항상 끝 page → 빠름.
AUTO_INCREMENT: 같지만 분산 X.
→ 큰 테이블 = v7 가 v4 보다 INSERT 5-10x 빠름.
보안
v4: 122-bit random → 추측 불가. URL 안전.
v7: 첫 48 bit = 시간 노출 → 정확 시각 추적 가능.
(random 80-bit 도 함께 — collision 안전)
→ Public ID = v4 또는 짧은 nanoid. Internal = v7.
// 두 단계 — internal sortable + public random
{ id: 'uuid-v7', publicId: 'nanoid' }
분산 서비스 (Sonyflake / IdGen)
- Snowflake 변형, machine ID 자동 할당.
- Redis SETNX 또는 etcd.
class Sonyflake {
// sub-second precision, larger machine bits
// machine ID = MAC 주소 last 16 bit
}
Sequence database (PG / MySQL)
-- PG sequence
CREATE SEQUENCE orders_id_seq START 1;
SELECT nextval('orders_id_seq');
-- 단일 PG = bottleneck. 분산 X.
Encrypted ID (Hashids / Sqids)
import Sqids from 'sqids';
const sqids = new Sqids({ minLength: 8 });
const encoded = sqids.encode([userId]); // "yWBV0AVL"
const decoded = sqids.decode(encoded); // [userId]
→ Auto-increment 숨기기. URL 짧음 + 의미 있는 short link.
🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| 새 프로젝트 디폴트 | UUID v7 |
| Public URL ID | NanoID / KSUID |
| 분산 서비스 (Twitter scale) | Snowflake |
| Schema 호환 (UUID 컬럼) | UUID v7 |
| 짧은 ID 필요 | NanoID 10-12 |
| 정렬 + 짧음 | KSUID / ULID |
❌ 안티패턴
- UUID v4 + 큰 테이블: 인덱스 성능 추락.
- AUTO_INCREMENT 분산 환경: collision / sync.
- Snowflake machine ID hard-code: 충돌. 자동 할당.
- System clock backwards (NTP): ID 충돌. monotonic clock.
- 추측 가능 ID public 노출 (1, 2, 3): enumeration 공격.
- ID = 비즈니스 의미: ABC-2026-0001 같은 — 변경 어려움.
- 여러 system 다른 형식: 통일 (모두 UUID 또는 모두 KSUID).
🤖 LLM 활용 힌트
- 새 = UUID v7 (PG 17+ 또는 라이브러리).
- Public URL = NanoID.
- Distributed scale = Snowflake.
- 시간 정렬 + URL-safe = KSUID / ULID.