Projektowanie schematu bazy danych z Cursor
Zespół produktowy właśnie sfinalizował specyfikację wielodostępowego systemu billingowego SaaS. Potrzebujesz kont użytkowników, organizacji, planów subskrypcji, śledzenia zużycia, faktur i ścieżki audytu. Relacje nie są oczywiste — czy użytkownik należy do jednej organizacji, czy może należeć do kilku? Czy faktury są powiązane z subskrypcjami, czy z rekordami zużycia? A wymagania wydajnościowe nie są trywialne: dashboard billingowy musi się ładować w poniżej 200ms nawet dla organizacji z 50 000 miesięcznych zdarzeń zużycia.
Zaprojektowanie schematu dobrze za pierwszym podejściem oszczędza tygodnie bolesnych migracji później. Zrobienie tego źle oznacza albo uruchamianie ALTER TABLE na produkcyjnej bazie pod obciążeniem, albo utrzymywanie wstecznie kompatybilnych skryptów migracji, od których boli głowa. Tryb Ask w Cursor jest zaskakująco dobry w wykrywaniu problemów z normalizacją, brakujących indeksów i błędów w relacjach, zanim napiszesz swoją pierwszą migrację.
Co wyniesiesz z tej lekcji
Dział zatytułowany „Co wyniesiesz z tej lekcji”- Workflow promptowy do przekształcania wymagań biznesowych w znormalizowany schemat bazy danych z trybem Ask w Cursor
- Prompt do generowania migracji, który produkuje pliki migracyjne Drizzle/Prisma/Knex ze wsparciem dla rollbacku
- Technikę wykorzystania trybu Agent do generowania danych seed, które testują przypadki brzegowe twojego schematu
- Prompt do optymalizacji indeksów, który wyłapuje zapytania N+1 i brakujące indeksy, zanim trafią na produkcję
- Listę kontrolną modelowania danych, która zapobiega najczęstszym błędom w projektowaniu schematów
Workflow
Dział zatytułowany „Workflow”Krok 1: Wyodrębnij encje i relacje z trybem Ask
Dział zatytułowany „Krok 1: Wyodrębnij encje i relacje z trybem Ask”Zacznij w trybie Ask. Nie skacz od razu do tworzenia tabel — najpierw opanuj model konceptualny. AI jest doskonałe w zadawaniu pytań uściślających, które ujawniają niejednoznaczności w wymaganiach.
Ten prompt celowo unika proszenia o SQL. Etap modelu konceptualnego wyłapuje błędy takie jak “czy użytkownik powinien należeć do jednej organizacji czy wielu?”, których naprawienie po utworzeniu tabel jest kosztowne. AI zazwyczaj ujawni 3-5 niejednoznaczności, które musisz rozwiązać z zespołem produktowym przed pisaniem kodu.
Krok 2: Wygeneruj schemat z prawidłowymi ograniczeniami
Dział zatytułowany „Krok 2: Wygeneruj schemat z prawidłowymi ograniczeniami”Gdy model konceptualny jest jasny, przełącz się na tryb Agent i wygeneruj właściwy schemat. Bądź precyzyjny co do ORM i bazy danych — ograniczenia i składnia różnią się znacząco.
Krok 3: Zwaliduj schemat względem rzeczywistych zapytań
Dział zatytułowany „Krok 3: Zwaliduj schemat względem rzeczywistych zapytań”Schemat, który wygląda czysto na papierze, może działać fatalnie pod rzeczywistymi wzorcami zapytań. Użyj trybu Ask, aby sprawdzić schemat względem faktycznych zapytań, które twoja aplikacja będzie wykonywać.
Ten krok prawie zawsze wyłapuje brakujące indeksy. Zapytanie o trend zużycia (zapytanie 7) zazwyczaj potrzebuje indeksu złożonego na (organization_id, month), który nie był oczywisty z samego schematu.
Krok 4: Wygeneruj dane seed testujące przypadki brzegowe
Dział zatytułowany „Krok 4: Wygeneruj dane seed testujące przypadki brzegowe”Dobre dane seed to nie losowe dane — to dane zaprojektowane do testowania ograniczeń schematu i ujawniania przypadków brzegowych.
Uruchom skrypt seed. Jeśli jakikolwiek insert zakończy się błędem naruszenia ograniczenia, którego się nie spodziewałeś, to jest problem w projekcie schematu do naprawienia teraz, a nie na produkcji.
Krok 5: Napisz migracje ze wsparciem dla rollbacku
Dział zatytułowany „Krok 5: Napisz migracje ze wsparciem dla rollbacku”Każda migracja powinna być odwracalna. Tryb Agent może wygenerować zarówno migrację “up”, jak i “down” w jednym przebiegu.
Krok 6: Optymalizuj z EXPLAIN ANALYZE
Dział zatytułowany „Krok 6: Optymalizuj z EXPLAIN ANALYZE”Po wypełnieniu schematu danymi seed użyj Cursor do analizy wydajności zapytań i sugestii optymalizacji.
Kiedy to się psuje
Dział zatytułowany „Kiedy to się psuje”AI sugeruje denormalizację zbyt agresywnie. Modele trenowane na treściach tutorialowych mają tendencję do rekomendowania przechowywania obliczonych wartości (jak “total_amount” na fakturach), aby uniknąć JOIN-ów. Dla systemu billingowego stwarza to ryzyka integralności danych — jeśli pozycja się zmieni, ale suma nie zostanie przeliczona, twoje faktury są nieprawidłowe. Denormalizuj tylko wtedy, gdy zmierzysz problem z wydajnością i ryzyko integralności jest akceptowalne.
Wygenerowane migracje nie są idempotentne. Jeśli migracja zawiedzie w połowie, ponowne uruchomienie nie powinno się wywalić. Dodaj sprawdzenia IF NOT EXISTS do CREATE TABLE i IF EXISTS do DROP. Poproś Agenta jawnie o uczynienie migracji idempotentymi.
Kaskady kluczy obcych usuwają za dużo danych. ON DELETE CASCADE na niewłaściwej relacji może wyczyścić całe tabele. Dla systemu billingowego prawie nic nie powinno mieć cascade-delete. Używaj RESTRICT domyślnie i CASCADE tylko dla prawdziwych relacji posiadania (jak usunięcie organizacji usuwa jej rekordy zużycia). Zawsze weryfikuj zachowanie ON DELETE w code review.
Zmiany schematu psują istniejące zapytania. Gdy zmieniasz nazwę kolumny lub typ, istniejący kod aplikacji się psuje. Użyj migracji dwufazowej: najpierw dodaj nową kolumnę, wdróż kod zapisujący do starej i nowej kolumny, potem usuń starą kolumnę w kolejnej migracji. Poproś Agenta o wygenerowanie pełnego planu dwufazowego.
AI generuje składnię specyficzną dla PostgreSQL dla SQLite. Jeśli twoje środowisko deweloperskie używa SQLite, ale produkcja PostgreSQL, napotkasz różnice w składni. Bądź precyzyjny co do docelowej bazy danych w swoim prompcie. Jeszcze lepiej, użyj abstrakcji dialektu Drizzle i testuj na tym samym silniku bazy, na którym wdrażasz.