Vibe coding tools can spin up apps in minutes. And while the goal of vibe coding isn't to create perfectly optimal databases, if you don’t understand the basics of how the backend is structured, you risk ending up with messy database schemas that are hard to use, extend, and maintain.
This doesn’t mean you need to become a backend engineer. Instead, learning just the basic principles of modelling relational databases means you can sanity-check what the AI gives you better and spot glaring issues before you go into production.
Let’s walk through the basics with a simple example: an internal business app for booking company cars.
- Start with the problem your app is trying to solve
- Identify your key objects
- Define attributes and relationships for each object
- Watch for duplication and normalise
- Confirm your attribute types
- Sanity-check the vibe coded data model
- Summary
- FAQ
Start with the problem your app is trying to solve
When designing a data model, it's easy to start jumping straight to defining database tables. But instead, it's better to think about the overall problem first. In our example, the problem is simple: employees need to book company cars. To solve that, you need to know:
- Which employees are booking
- Which cars are available
-
When a booking happens
That’s the foundation of your data model. From this, you can start thinking about the objects or entities you want to store.
Identify your key objects
Objects (also known as entities) are the “things” your app cares about. This step is known as the conceptual data model.
Each object would have its own table where objects of the same type are stored. For the car booking app, the core objects are:
- Employees
- Cars
-
Bookings
But these might not be the only objects that your app needs, depending on whether you need to normalise your data or not (discussed below).
Define attributes and relationships for each object
The attributes are the columns of your tables. They describe what the object is and define the information you want to know about each of your objects. For example:
- Employee: first name, last name, email, department, phone number, driving licence
- Car: licence plate, model, manufacturer, lease contract, lease start date, lease end date, lease supplier, fuel type, transmission type, location, status, condition notes
-
Booking: car, employee, start date and time, end date and time, status
You'll notice two attributes are in bold. These two define relationships or references between the different objects. A booking will be linked to a specific employee object and a specific car object.
This step, of defining attributes and relationships, is known as the logical model of your database. It's a high level view of your data and how it all connects together.
A note on IDs
You'll notice above that there is no employee ID, car ID, or booking ID in our list of attributes. This is because Starhive, and other vibe/no-code tools like Airtable, abstract IDs from the user. In Starhive you just create a 'reference attribute' and choose which of the car or employee objects you want to link to a booking.
If you are working in a more traditional database, you will need to include an explicit ID so your database knows what object it's referencing. In which case, the logical model will look like this:
- Employee: employee ID, first name, last name, email, department, phone number, driving licence
- Car: car ID, licence plate, model, manufacturer, lease contract, lease start date, lease end date, lease supplier, fuel type, transmission type, location, status, condition notes
- Booking: booking ID, car ID, employee ID, start date and time, end date and time, status
Watch for duplication and normalise
In my experience this is where AI can struggle a little bit without careful prompting. For example, AI generated the example logical model I wrote above. And we can see some duplication in the car object.
Do we really need model, manufacturer, fuel type, and transmission type listed on every car if we have 40 of the exact same model of car? Instead it might be better to do something like this:
- Employee: first name, last name, email, department, phone number, driving licence
- Car: licence plate, car model, location, lease agreement, current status, condition notes
- Car model: name, manufacturer, fuel type, transmission
- Lease agreement: start date, end date, supplier
-
Booking: car, employee, start date and time, end date and time, status
Here we have normalised our data model by creating two new objects: car model and lease agreement. This way we are not storing Volvo for every XC40 we have. Or the lease start and end date on every single car on the same lease agreement. It's a way of making data easier to read (by humans), cutting down on storage, and reducing the risk of inconsistent data as the fewer times the value is added, the easier it is to keep things consistent.
You can ask the AI tool to keep normalisation principles in mind while building your backend.
Is it worth normalising data?
Whether you should normalise or not is ultimately up to you as the designer of your app. You can get AI's recommendation after your first iteration of building your data model too. In our opinion normalisation is good for more transactional apps as it's easier to keep updated and accurate. But, if you value performance and simpler queries, e.g. if you're building a database for analytics, it might be better to avoid normalisation and even denormalise as it's faster and easier to query data this way.
Normalisation | Denormalisation |
✅ Removes duplication → avoids inconsistencies when data changes ✅ Smaller storage footprint (less repeated data) ✅ Easier to enforce integrity with constraints and relationships ❌ Queries can become more complex (more JOINs) ❌ Performance might suffer if you need to pull lots of related data together often |
✅ Simpler queries (no JOINs, easier for reporting or dashboards) ✅ Can improve performance in read-heavy workloads ❌ Updates are riskier → you must change the same value in multiple places ❌ Higher storage usage ❌ Greater chance of inconsistent data |
Confirm your attribute types
Another thing to think about is the data types of your attributes (e.g. text, date, date-time, integar). If you're using SQL based databases your options are a bit limited, but if you're using a modern database, attribute types can include the classics but also things like maps, star ratings, calculations, options, or even ordered transition states (perfect for status attributes).
I find it's good to double check that AI has chosen something sensible for an attribute. For example, it has chosen a transition state or option attribute type instead of text for a status attribute. Or ensure there is some validation to ensure it can only be certain values. Otherwise you risk introducing new statuses via typos which can break your app's logic.
Sanity-check the vibe coded data model
When an AI tool generates a schema, take a few minutes to review it so you can spot any glaring mistakes sooner rather than later. It's easier to get AI to fix an empty database model than having to alter the model later and deal with migrating the data too.
Quick things to check include:
- Do the objects map to real things in your process?
- Are relationships clear and logical?
- Is data duplicated unnecessarily? Should it be normalised?
-
Are the attribute data types sensible?
Summary
There is much more to data modelling than is written here but if you're new to backend and databases, this should give you some basic pointers of what to check before continuing to build your app. If you would like a more in-depth guide, you can read our blog for no-code applications here which is more in-depth.
FAQ on data modelling for vibe coders
A data model is the blueprint of how information is organised in your app. It defines what “things” you want to track (like employees, cars, bookings) and how they relate to each other. Without a model, your data quickly becomes messy and inconsistent, making it harder for your app to work smoothly.
A conceptual model is the high-level sketch — it lists your core objects (employees, cars, bookings) and how they connect. A logical model goes a step further by adding the attributes of each object (like licence plate for cars, or date for bookings). A physical model is the actual implementation inside your chosen database or tool. For vibe coders, the first two stages help you think clearly before you let the AI or no-code platform generate the physical model.
For vibe coding, a flexible database that supports custom schemas is ideal. Relational-style databases (where you can define objects and relationships) give you the most long-term control, even if the AI builds it for you. Look for a backend that lets you evolve the model over time without locking you into rigid categories.
What different types of database relationships can I use in my vibe coded app?
It’s critical. AI tools can generate a schema quickly, but they don’t understand your business rules. If the underlying model is wrong, you’ll face duplication, scaling problems, or broken logic when you extend the app. Spending a little time upfront to model your data makes your vibe coding sessions far more effective and ensures the app you build today won’t fall apart tomorrow.