iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
Vibe Coding

Vibe Mode 開啟:30 天用 AI 打造網頁,邊做邊學 JavaScript系列 第 11 篇

# Day 11:Mock Data 生成:如何利用 AI 快速打樣測試資料庫

  • 分享至 

  • xImage
  •  

今日目標

在前幾天的開發中,我們已經搭好了資料庫 Schema、API 邏輯以及自動化測試。但空空如有的資料庫就像是沒有顧客的百貨公司——你看不出效能瓶頸,也無法在 UI 開發時想像真實的使用情境。

今天我們的任務是:利用 AI 快速生成大量、真實且具備關聯性的 Mock Data(模擬資料),讓我們的財務追蹤器瞬間填充滿滿的消費紀錄,為後續的前端 UI 頁面開發做好準備!


Human vs. AI 實戰記錄

要生成「好用」的 Mock Data,最忌諱給出模糊的指令。如果只跟 AI 說:「請幫我生成 50 筆記帳資料」,你只會得到一堆重複且毫無意義的文字。

1.給 AI 的指令 (Prompt)

我們需要 AI 結合 Faker.js 套件與 Prisma 的語法,產生出符合台灣在地消費情境的假資料:

你現在是一位 senior 後端工程師。請幫我撰寫一個 Prisma 的 Seed Script (prisma/seed.ts)。

需求如下:
1. 使用 `@faker-js/faker` 生成資料。
2. 先建立 1 個測試使用者 (User)。
3. 替該使用者生成 50 筆交易紀錄 (Transaction)。
4. 交易類型 (type) 包含 "INCOME" 與 "EXPENSE"。
5. 分類 (category) 請涵蓋日常消費(如:外食、交通、娛樂、薪水)。
6. 金額 (amount) 請符合合理台幣數字(例如外食 80~300 元,薪水 50000 元)。
7. 時間 (date) 隨機分佈在過去 30 天內。


2. AI 產出的結果 (Code)

AI 很快地給出了一份 prisma/seed.ts 草稿:

import { PrismaClient } from '@prisma/client';
import { faker } from '@faker-js/faker';

const prisma = new PrismaClient();

async function main() {
  // 清除舊資料
  await prisma.transaction.deleteMany();
  await prisma.user.deleteMany();

  // 建立預設使用者
  const user = await prisma.user.create({
    data: {
      email: 'demo@example.com',
      name: 'Test User',
    },
  });

  const categories = ['外食', '交通', '娛樂', '薪水'];

  // 生成 50 筆資料
  for (let i = 0; i < 50; i++) {
    const isIncome = faker.datatype.boolean();
    await prisma.transaction.create({
      data: {
        userId: user.id,
        amount: isIncome ? 50000 : faker.number.int({ min: 80, max: 300 }),
        type: isIncome ? 'INCOME' : 'EXPENSE',
        category: isIncome ? '薪水' : faker.helpers.arrayElement(categories.slice(0, 3)),
        note: faker.lorem.sentence(),
        date: faker.date.recent({ days: 30 }),
      },
    });
  }
}

main()
  .catch((e) => console.error(e))
  .finally(async () => await prisma.$disconnect());


3. 做出的修正與翻車紀錄 (Debug Experience)

這段程式碼看起來很完美,但一執行 npx prisma db seed 就踩坑了!

翻車點一:大量 N+1 Write 操作導致 Seed 速度慢如牛步

AI 使用了最直觀的 for 迴圈搭配 await prisma.transaction.create()。這意味著程式發送了 50 次獨立的資料庫 Request!雖然 50 筆感覺很快,但如果未來要測試 5,000 筆 Big Data 效能時,這會讓 Seed 過程花費數分鐘。

翻車點二:機率分配極度不合理

faker.datatype.boolean() 的機率是 50%/50%。這會導致生成出來的 50 筆紀錄裡有 25 筆都是「薪水」,這哪是什麼個人財務追蹤器,根本是發暴財的假象!

介入修復!

我們引導 AI 進行二次重構:

  1. **改用 prisma.transaction.createMany()** 進行批次插入(Batch Insert),提升 10 倍速度。
  2. 調整機率權重:把收入與支出的比例調整為合理的 5% vs. 95%。
  3. 優化備註文字:faker.lorem.sentence() 會生成拉丁文無意義句子,改成在地化的中文備註(如「午餐便當」、「捷運儲值」)。

修正後的精華程式碼:

  // 建立批次陣列
  const transactionsData = Array.from({ length: 50 }).map(() => {
    // 95% 概率為支出
    const isExpense = faker.number.float({ min: 0, max: 1 }) < 0.95; 

    return {
      userId: user.id,
      amount: isExpense 
        ? faker.number.int({ min: 60, max: 1500 }) 
        : faker.number.int({ min: 30000, max: 60000 }),
      type: isExpense ? 'EXPENSE' : 'INCOME',
      category: isExpense ? faker.helpers.arrayElement(['外食', '交通', '購物']) : '薪水',
      note: isExpense ? faker.helpers.arrayElement(['便利商店', '午餐搭計程車', '星巴克咖啡']) : '月薪發放',
      date: faker.date.recent({ days: 30 }),
    };
  });

  // 一次性高效插入
  await prisma.transaction.createMany({
    data: transactionsData,
  });


JavaScript / AI 學習小結

  1. JavaScript 的 Event Loop 與 Async/Await 代價:
    在迴圈中使用 await 會強制程式進入序列化執行(Sequential execution)。當我們處理大量資料注入時,優先考慮將資料集中至記憶體陣列,再透過批次寫入(createMany)來大幅減少 I/O 開銷。
  2. AI 沒有真實的生活經驗:
    AI 能夠精準掌握 Faker.js 的 API 語法,但它缺乏對真實業務邏輯(Business Domain Logic)的敏銳度(例如收支比例、合理消費金額)。工程師的核心價值就在於「輸入正確的世界觀」,引導 AI 吐出符合真實狀況的資料。

上一篇
# Day 10|睡個好覺的秘密武器!用 AI 自動生成 Vitest 單元與整合測試
下一篇
# Day 12:UI 框架建立:結合 Tailwind CSS + shadcn/ui 建立一致的設計系統(Design System)
系列文
Vibe Mode 開啟:30 天用 AI 打造網頁,邊做邊學 JavaScript 共 12 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言