3 PostgreSQL-Schemata für eine saubere App – Supabase von Anfang an strukturieren
Wenn Sie ein Projekt starten, ist die Versuchung groß, alles in das public-Schema von PostgreSQL zu packen. Eine Tabelle hier, eine andere dort, und nach drei Wochen haben Sie 40 Tabellen durcheinander, ohne jegliche Logik.
Ich habe mich sehr früh entschieden, TAMSIV mit drei separaten Schemata zu strukturieren.
Die drei Schemata
privat— Alle persönlichen Daten: Aufgaben, Memos, Kalenderereignisse, Benutzerprofile, Anhängecollaborative— Alles, was mit Gruppen zu tun hat: Mitglieder, Rollen, geteilte Aufgaben, Gruppen-Checklistengamification— Statistiken, Abzeichen, Streaks, tägliche Herausforderungen, Punkteverlauf
Warum privat und nicht private? Weil private ein reserviertes Wort in SQL ist. Das habe ich auf die harte Tour nach einer fehlgeschlagenen Migration gelernt.
Warum trennen?
1. Lesbarkeit. Wenn ich SELECT * FROM privat.tasks ausführe, weiß ich sofort, dass es sich um persönliche Daten handelt.
2. Sicherheit. RLS-Richtlinien sind leichter zu begründen, wenn die Tabellen nach Domänen gruppiert sind. Die Regeln des privat-Schemas sind einfach: Sie sehen nur Ihre Daten. Die des collaborative-Schemas sind komplexer: Sie sehen die Daten der Gruppen, denen Sie angehören, entsprechend Ihrer Rolle.
3. Evolution. Als ich drei Monate nach Projektbeginn die Gamification hinzufügte, erstellte ich ein neues Schema, ohne die beiden anderen zu berühren. Null Risiko, das Bestehende zu beschädigen.
Der Albtraum der RLS-Richtlinien
Supabase verwendet RLS, um den Datenzugriff zu sichern. Das Prinzip ist einfach: Jede Tabelle hat Regeln, die bestimmen, wer lesen, schreiben, ändern, löschen darf. In der Praxis ist es ein Labyrinth.
Insgesamt umfasst das Projekt mehr als 30 RLS-Richtlinien. Jede einzeln getestet.
Die Namenskonventionen
Ich habe strenge Konventionen übernommen: Tabellen in snake_case im Plural, Spalten in snake_case, RPC-Parameter mit Präfix p_. Dieses Präfix p_ vermeidet Kollisionen mit Spaltennamen in Abfragen. An dem Tag, an dem Ihr Parameter user_id mit der Spalte user_id kollidiert, verstehen Sie, warum.
Diese Struktur hat mir im weiteren Verlauf viel Zeit gespart. Jede neue Funktion findet ihren natürlichen Platz.