Drizzle schema

Drizzle๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ง€์›ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ชจ๋ธ๊ณผ ์†์„ฑ์„ TypeScript๋กœ ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๋ฉด, ์ด๋Š” ์ฟผ๋ฆฌ(Drizzle-ORM ์‚ฌ์šฉ)์™€ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜(Drizzle-Kit ์‚ฌ์šฉ)์˜ ํ–ฅํ›„ ์ˆ˜์ •์— ๋Œ€ํ•œ ๋‹จ์ผ ์†Œ์Šค๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ”„๋กœ์„ธ์Šค์— Drizzle-Kit์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, Drizzle-Kit์ด ์ด๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ diff ํ”„๋กœ์„ธ์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์Šคํ‚ค๋งˆ ํŒŒ์ผ์— ์ •์˜๋œ ๋ชจ๋“  ๋ชจ๋ธ์„ ๋‚ด๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์Šคํ‚ค๋งˆ ํŒŒ์ผ ๊ตฌ์„ฑํ•˜๊ธฐ

SQL ์Šคํ‚ค๋งˆ๋ฅผ TypeScript์—์„œ ์ง์ ‘ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ผ schema.ts ํŒŒ์ผ์— ์„ ์–ธํ•˜๊ฑฐ๋‚˜, ์—ฌ๋Ÿฌ ํŒŒ์ผ์— ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค โ€” ์›ํ•˜๋Š” ๋Œ€๋กœ ์„ ํƒํ•˜์„ธ์š”. ์™„์ „ํ•œ ์ž์œ ์ž…๋‹ˆ๋‹ค!

๋‹จ์ผ ํŒŒ์ผ ์Šคํ‚ค๋งˆ

Drizzle๋กœ ์Šคํ‚ค๋งˆ๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ ๋ชจ๋“  ํ…Œ์ด๋ธ”์„ ํ•˜๋‚˜์˜ schema.ts ํŒŒ์ผ์— ๋„ฃ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ : ์Šคํ‚ค๋งˆ ํŒŒ์ผ์˜ ์ด๋ฆ„์€ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด models.ts๋‚˜ ๋‹ค๋ฅธ ์ด๋ฆ„๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ์ •์˜๋œ ํ…Œ์ด๋ธ” ๋ชจ๋ธ์ด ๋„ˆ๋ฌด ๋งŽ์ง€ ์•Š๊ฑฐ๋‚˜, ๋ชจ๋“  ํ…Œ์ด๋ธ”์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๊ดœ์ฐฎ์€ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค

์˜ˆ์‹œ:

๐Ÿ“ฆ <project root>
 โ”” ๐Ÿ“‚ src
    โ”” ๐Ÿ“‚ db
       โ”” ๐Ÿ“œ schema.ts

drizzle.config.ts ํŒŒ์ผ์—์„œ ์Šคํ‚ค๋งˆ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ฉด Drizzle์ด schema.ts ํŒŒ์ผ์„ ์ฝ๊ณ  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ƒ์„ฑ ํ”„๋กœ์„ธ์Šค์—์„œ ์ด ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. drizzle.config.ts ํŒŒ์ผ๊ณผ Drizzle ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”: ๋งํฌ

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: 'postgresql', // 'mysql' | 'sqlite' | 'turso'
  schema: './src/db/schema.ts'
})

์—ฌ๋Ÿฌ ํŒŒ์ผ๋กœ ๊ตฌ์„ฑ๋œ ์Šคํ‚ค๋งˆ

Drizzle ๋ชจ๋ธ(ํ…Œ์ด๋ธ”, ์—ด๊ฑฐํ˜•, ์‹œํ€€์Šค ๋“ฑ)์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์›ํ•˜๋Š” ๋ชจ๋“  ํŒŒ์ผ์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ, Drizzle Kit์ด ์ด๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋‹น ํŒŒ์ผ์—์„œ ๋ชจ๋“  ๋ชจ๋ธ์„ ๋‚ด๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๊ฐ ํ…Œ์ด๋ธ”์„ ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๐Ÿ“ฆ <project root>
 โ”” ๐Ÿ“‚ src
    โ”” ๐Ÿ“‚ db
       โ”” ๐Ÿ“‚ schema
          โ”œ ๐Ÿ“œ users.ts
          โ”œ ๐Ÿ“œ countries.ts
          โ”œ ๐Ÿ“œ cities.ts
          โ”œ ๐Ÿ“œ products.ts
          โ”œ ๐Ÿ“œ clients.ts
          โ”” ๐Ÿ“œ etc.ts

drizzle.config.ts ํŒŒ์ผ์—์„œ ์Šคํ‚ค๋งˆ ํด๋”์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ฉด Drizzle์ด schema ํด๋”๋ฅผ ์ฝ๊ณ  ๋ชจ๋“  ํŒŒ์ผ์„ ์žฌ๊ท€์ ์œผ๋กœ ์ฐพ์•„์„œ ๋ชจ๋“  Drizzle ํ…Œ์ด๋ธ”์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. drizzle.config.ts ํŒŒ์ผ๊ณผ Drizzle ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”: ๋งํฌ

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: 'postgresql', // 'mysql' | 'sqlite' | 'turso'
  schema: './src/db/schema'
})

์›ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž ๊ด€๋ จ ํ…Œ์ด๋ธ”, ๋ฉ”์‹œ์ง• ๊ด€๋ จ ํ…Œ์ด๋ธ”, ์ œํ’ˆ ๊ด€๋ จ ํ…Œ์ด๋ธ” ๋“ฑ์˜ ๊ทธ๋ฃน์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“ฆ <project root>
 โ”” ๐Ÿ“‚ src
    โ”” ๐Ÿ“‚ db
       โ”” ๐Ÿ“‚ schema
          โ”œ ๐Ÿ“œ users.ts
          โ”œ ๐Ÿ“œ messaging.ts
          โ”” ๐Ÿ“œ products.ts

๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ์ •์˜ํ•˜๊ธฐ

Drizzle ์Šคํ‚ค๋งˆ๋Š” ์‚ฌ์šฉ ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์—ฌ๋Ÿฌ ๋ชจ๋ธ ์œ ํ˜•์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. Drizzle์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณด๋ฉด์„œ Drizzle๋กœ ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค

ํ…Œ์ด๋ธ” ๋ฐ ์—ด ์„ ์–ธ

Drizzle์˜ ํ…Œ์ด๋ธ”์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ตœ์†Œ 1๊ฐœ์˜ ์—ด๋กœ ์ •์˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•Œ์•„์•ผ ํ•  ์ค‘์š”ํ•œ ์ ์€ Drizzle์—๋Š” ๊ณตํ†ต ํ…Œ์ด๋ธ” ๊ฐ์ฒด์™€ ๊ฐ™์€ ๊ฒƒ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์ค‘์ธ ๋ฐฉ์–ธ(PostgreSQL, MySQL ๋˜๋Š” SQLite)์„ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

PostgreSQL Table
MySQL Table
SQLite Table
import { pgTable, integer } from "drizzle-orm/pg-core"

export const users = pgTable('users', {
  id: integer()
});

๊ธฐ๋ณธ์ ์œผ๋กœ Drizzle์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฟผ๋ฆฌ์—์„œ ์—ด์— ๋Œ€ํ•ด TypeScript ํ‚ค ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์˜ˆ์ œ์˜ ์Šคํ‚ค๋งˆ์™€ ์ฟผ๋ฆฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ SQL ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด ์˜ˆ์ œ๋Š” db ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ๊ทธ ์ดˆ๊ธฐํ™”๋Š” ๋ฌธ์„œ์˜ ์ด ๋ถ€๋ถ„์—์„œ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๋ ค๋ฉด ์—ฐ๊ฒฐ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.


TypeScript ํ‚ค = ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ‚ค

// schema.ts
import { integer, pgTable, varchar } from "drizzle-orm/pg-core";

export const users = pgTable('users', {
  id: integer(),
  first_name: varchar()
})
// query.ts
await db.select().from(users);
SELECT "id", "first_name" from users;

TypeScript ์ฝ”๋“œ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์—ด ๋ณ„์นญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// schema.ts
import { integer, pgTable, varchar } from "drizzle-orm/pg-core";

export const users = pgTable('users', {
  id: integer(),
  firstName: varchar('first_name')
})
// query.ts
await db.select().from(users);
SELECT "id", "first_name" from users;

์นด๋ฉœ ์ผ€์ด์Šค์™€ ์Šค๋„ค์ดํฌ ์ผ€์ด์Šค

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ์ด๋ฆ„์€ ์ข…์ข… snake_case ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ˜๋ฉด, TypeScript์—์„œ๋Š” ๋ชจ๋ธ ์ด๋ฆ„์— camelCase๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์Šคํ‚ค๋งˆ์— ๋งŽ์€ ๋ณ„์นญ ์ •์˜๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Drizzle์€ Drizzle ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ดˆ๊ธฐํ™” ์‹œ ํ•˜๋‚˜์˜ ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํฌํ•จํ•˜์—ฌ TypeScript์˜ camelCase๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ snake_case๋กœ ์ž๋™ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋งคํ•‘์„ ์œ„ํ•ด Drizzle DB ์„ ์–ธ์—์„œ casing ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋ช…๋ช… ๊ทœ์น™์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋ฉฐ ๋ชจ๋“  JavaScript ํ‚ค๋ฅผ ์ ์ ˆํžˆ ๋งคํ•‘ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

// schema.ts
import { drizzle } from "drizzle-orm/node-postgres";
import { integer, pgTable, varchar } from "drizzle-orm/pg-core";

export const users = pgTable('users', {
  id: integer(),
  firstName: varchar()
})
// db.ts
const db = drizzle({ connection: process.env.DATABASE_URL, casing: 'snake_case' })
// query.ts
await db.select().from(users);
SELECT "id", "first_name" from users;

๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•

Drizzle ORM์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. Drizzle์€ ์™„์ „ํžˆ TypeScript ํŒŒ์ผ์— ์žˆ์œผ๋ฏ€๋กœ ์ผ๋ฐ˜ TypeScript ํ”„๋กœ์ ํŠธ์—์„œ ์ฝ”๋“œ๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์ž‘์—…์„ ๋ณธ์งˆ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” ์—ด์„ ์„œ๋กœ ๋‹ค๋ฅธ ์œ„์น˜๋กœ ๋ถ„๋ฆฌํ•œ ๋‹ค์Œ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด updated_at, created_at, deleted_at ์—ด์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”. ๋งŽ์€ ํ…Œ์ด๋ธ”/๋ชจ๋ธ์ด ์‹œ์Šคํ…œ์—์„œ ์—”ํ‹ฐํ‹ฐ์˜ ์ƒ์„ฑ, ์‚ญ์ œ ๋ฐ ์—…๋ฐ์ดํŠธ๋ฅผ ์ถ”์ ํ•˜๊ณ  ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•ด ์ด ์„ธ ๊ฐ€์ง€ ํ•„๋“œ๋ฅผ ํ•„์š”๋กœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์—ด์„ ๋ณ„๋„์˜ ํŒŒ์ผ์— ์ •์˜ํ•œ ๋‹ค์Œ ๊ฐ€์ ธ์™€์„œ ๋ชจ๋“  ํ…Œ์ด๋ธ” ๊ฐ์ฒด์— ์ „๊ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// columns.helpers.ts
const timestamps = {
  updated_at: timestamp(),
  created_at: timestamp().defaultNow().notNull(),
  deleted_at: timestamp(),
}
// users.sql.ts
export const users = pgTable('users', {
  id: integer(),
  ...timestamps
})
// posts.sql.ts
export const posts = pgTable('posts', {
  id: integer(),
  ...timestamps
})

์Šคํ‚ค๋งˆ

PostgreSQL
MySQL
SQLite


PostgreSQL์—๋Š” schema๋ผ๋Š” ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์šฐ๋ฆฌ๋Š” ์ด๋ฅผ folders๋ผ๊ณ  ๋ถˆ๋Ÿฌ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค). ์ด๋Š” PostgreSQL์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค:

pgSchema๋กœ PostgreSQL ์Šคํ‚ค๋งˆ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ๊ทธ ์•ˆ์— ๋‹ค๋ฅธ ๋ชจ๋ธ์„ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Drizzle์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋ ค๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

import { pgSchema } from "drizzle-orm/pg-core"

export const customSchema = pgSchema('custom');

๊ทธ๋Ÿฐ ๋‹ค์Œ ์Šคํ‚ค๋งˆ ๊ฐ์ฒด ์•ˆ์— ํ…Œ์ด๋ธ”์„ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.

import { integer, pgSchema } from "drizzle-orm/pg-core";

export const customSchema = pgSchema('custom');

export const users = customSchema.table('users', {
  id: integer()
})

์˜ˆ์ œ

๊ธฐ๋ณธ ์‚ฌํ•ญ์„ ์•Œ์•˜์œผ๋‹ˆ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์Šคํ‚ค๋งˆ ์˜ˆ์ œ๋ฅผ ์ •์˜ํ•˜์—ฌ ๋” ๋‚˜์€ ์ดํ•ด๋ฅผ ์–ป์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์˜ˆ์ œ๋Š” generateUniqueString์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ตฌํ˜„์€ ๋ชจ๋“  ์Šคํ‚ค๋งˆ ์˜ˆ์ œ ์ดํ›„์— ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

PostgreSQL
MySQL
SQLite
import { AnyPgColumn } from "drizzle-orm/pg-core";
import { pgEnum, pgTable as table } from "drizzle-orm/pg-core";
import * as t from "drizzle-orm/pg-core";

export const rolesEnum = pgEnum("roles", ["guest", "user", "admin"]);

export const users = table(
  "users",
  {
    id: t.integer().primaryKey().generatedAlwaysAsIdentity(),
    firstName: t.varchar("first_name", { length: 256 }),
    lastName: t.varchar("last_name", { length: 256 }),
    email: t.varchar().notNull(),
    invitee: t.integer().references((): AnyPgColumn => users.id),
    role: rolesEnum().default("guest"),
  },
  (table) => [
    t.uniqueIndex("email_idx").on(table.email)
  ]
);

export const posts = table(
  "posts",
  {
    id: t.integer().primaryKey().generatedAlwaysAsIdentity(),
    slug: t.varchar().$default(() => generateUniqueString(16)),
    title: t.varchar({ length: 256 }),
    ownerId: t.integer("owner_id").references(() => users.id),
  },
  (table) => [
    t.uniqueIndex("slug_idx").on(table.slug),
    t.index("title_idx").on(table.title),
  ]
);

export const comments = table("comments", {
  id: t.integer().primaryKey().generatedAlwaysAsIdentity(),
  text: t.varchar({ length: 256 }),
  postId: t.integer("post_id").references(() => posts.id),
  ownerId: t.integer("owner_id").references(() => users.id),
});

generateUniqueString ๊ตฌํ˜„:

function generateUniqueString(length: number = 12): string {
  const characters =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let uniqueString = "";

  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * characters.length);
    uniqueString += characters[randomIndex];
  }

  return uniqueString;
}

๋‹ค์Œ ๋‹จ๊ณ„