Data Modeling Basics
Introduction
Data modeling is the process of deciding what data an application needs, how that data should be structured, and how different pieces of data relate to each other. Before creating tables, columns, primary keys, foreign keys, indexes, and constraints, we first need to understand the business information that the database must represent. A good data model converts real-world business concepts into a database design that is understandable, reliable, and maintainable.
Many beginners start database design by immediately writing CREATE TABLE statements. That can work for small practice exercises, but it is risky in real applications. If the business rules are unclear, tables may be created in the wrong shape. Important relationships may be missed. The same data may be stored repeatedly. Queries may become difficult. Future changes may require painful redesign. Data modeling helps prevent these problems by slowing down the design process before implementation begins.
Business Requirements
|
Identify Entities
|
Identify Attributes
|
Define Relationships
|
Choose Keys
|
Apply Constraints
|
Create Database Tables
The goal of data modeling is not to draw diagrams for documentation only. The goal is to understand the business clearly enough to design tables that protect data integrity and support application behavior. For example, an online shopping system has customers, products, orders, order items, payments, shipments, addresses, and refunds. These are business concepts first. Only after understanding them should we decide table names, column names, data types, keys, and constraints.
This tutorial explains the basics of data modeling in SQL database design. It covers conceptual, logical, and physical models; entities and attributes; strong and weak entities; relationships and cardinality; primary keys, natural keys, surrogate keys, and foreign keys; business rules and constraints; normalization and denormalization; ER diagrams; common modeling mistakes; and practical examples from e-commerce, library, banking, HR, and testing applications.
Why Data Modeling Is Important
Without proper data modeling, databases can become difficult to maintain. A poor model may store duplicate data, miss important relationships, allow inconsistent values, make queries hard to write, create performance problems, and force difficult application changes. The database may work at the beginning, but as data grows and requirements change, weaknesses become visible.
Consider an e-commerce application that stores order data in one flat table:
| order_id | customer_name | customer_email | product1 | product2 | product3 |
|---|---|---|---|---|---|
| 1001 | John | john@test.com | Laptop | Mouse | Keyboard |
This structure may look simple, but it has serious limitations. What if an order contains four products? What if an order contains twenty products? What if John changes his email address? What if two customers have the same name? What if the application needs to search all orders that include Mouse? The flat structure makes these tasks awkward.
A better model separates customers, orders, products, and order items. Customer details are stored once. Product details are stored once. Orders reference customers. Order items connect orders to products and store quantity and price at the time of purchase. This design better matches the business reality and supports flexible queries.
Customers
Orders
Products
Order_Items
Good data modeling reduces confusion. It makes the database easier for developers, testers, analysts, and administrators to understand. It also creates a foundation for reliable application behavior because the database structure expresses important business rules.
What Does a Data Model Represent?
A data model represents entities, attributes, relationships, keys, constraints, and business rules. An entity is something important about which the business wants to store data. An attribute describes an entity. A relationship describes how entities are connected. Keys identify rows and connect tables. Constraints protect data rules.
Customer
|
Places
|
Order
|
Contains
|
Product
This simple model says that customers place orders and orders contain products. It is not yet a complete database design, but it captures important business meaning. From this model, we can later create customer, order, product, and order item tables.
Data modeling is the bridge between business language and database implementation. The business may talk about customers, subscriptions, invoices, refunds, branches, accounts, employees, projects, courses, defects, or test runs. A data model organizes those ideas and prepares them for SQL implementation.
Real-World Object to Database Structure
Real-world objects and business concepts often become database entities. If the business talks about customers, products, orders, and payments, those concepts are candidates for entities. In a relational database, those entities often become tables.
Customer -> customers table
Product -> products table
Order -> orders table
Payment -> payments table
This conversion is not always one-to-one. Sometimes one business concept becomes multiple tables. For example, an order may become an orders table and an order_items table because one order can contain many products. Sometimes multiple small concepts stay as columns in one table because creating separate tables would add unnecessary complexity. Modeling requires judgment.
The important point is that database structure should come from business meaning, not from a single screen or a temporary report. A web page may display customer name, order number, product name, payment status, and shipping status together, but that does not mean all those values belong in one table. The UI combines data for presentation. The database model should represent the underlying business entities.
Main Levels of Data Modeling
Data modeling is commonly discussed at three levels: conceptual model, logical model, and physical model. Each level adds more detail. The conceptual model is closest to business language. The logical model defines structure more clearly. The physical model turns the design into database-specific implementation.
Conceptual Model
|
Logical Model
|
Physical Model
A useful memory trick is: conceptual asks what exists, logical asks how it is organized, and physical asks how the database will store it. These levels help teams separate business understanding from implementation details. If implementation decisions are made too early, the design may reflect technical guesses rather than real requirements.
| Model | Main Purpose | Typical Details |
|---|---|---|
| Conceptual | Understand the business | Entities and major relationships |
| Logical | Design data structure | Attributes, keys, relationships, cardinality |
| Physical | Implement in DBMS | Tables, data types, indexes, constraints |
Conceptual Data Model
The conceptual data model provides a high-level business view. It focuses on major entities, major relationships, and important business concepts. It usually avoids implementation details such as data types, indexes, exact table names, storage choices, and database-specific syntax.
For an online shopping system, the conceptual model may say that a customer places an order and an order contains products. That is enough to start discussing the business. At this stage, we do not need to decide whether customer ID is INT or BIGINT, whether product name is VARCHAR(150), or whether an index should exist.
Customer
|
| places
v
Order
|
| contains
v
Product
For a school system, the conceptual model may contain student, course, instructor, and department. The model may show that students enroll in courses and instructors teach courses. This helps business users, analysts, developers, and testers agree on core concepts before technical details are added.
Logical Data Model
The logical data model adds more structure. It usually includes entities, attributes, primary keys, foreign keys, relationships, cardinality, optionality, and business rules. It is still not fully tied to one database product, but it is specific enough to guide implementation.
CUSTOMER
--------
customer_id
name
email
ORDER
-----
order_id
customer_id
order_date
The relationship can be described as one customer can have many orders. This means customers.customer_id is the primary key in customers, and orders.customer_id is a foreign key that references it.
Customer
1
|
|
N
Orders
The logical model also considers whether relationships are mandatory or optional. Can a customer exist without an order? Usually yes. Can an order exist without a customer? Usually no. These rules later become nullable or not-null foreign keys and constraints.
Physical Data Model
The physical data model describes how the logical model will actually be implemented in a specific database system. It includes table names, column names, data types, indexes, constraints, partitioning, storage choices, naming conventions, and database-specific syntax.
CREATE TABLE customers (
customer_id BIGINT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) UNIQUE
);
This is now implementation-specific. We chose BIGINT for the customer ID, VARCHAR(100) for the name, VARCHAR(150) for the email, NOT NULL for required name, and UNIQUE for email. Different databases may use slightly different data types and syntax.
The physical model also considers performance and operations. For example, it may add an index on orders.customer_id because the application frequently finds orders for a customer. It may partition a huge transactions table by date. It may choose storage options for large historical tables. These decisions turn the logical design into a working database.
What Is an Entity?
An entity represents a real-world object, concept, person, place, event, or thing about which we want to store data. Examples include customer, employee, product, order, payment, department, student, course, branch, account, transaction, project, test case, and defect. In relational databases, entities often become tables.
Entity: Customer
|
Table: customers
Suppose we are building an HR application. Important entities may include employee, department, project, and manager. Each one represents something meaningful to the business. Employees work in departments. Employees may work on projects. Managers may supervise employees. These concepts can be modeled and later implemented through tables and relationships.
Not every noun automatically becomes an entity. Requirements may mention screens, buttons, reports, statuses, files, messages, and temporary values. Some become tables, some become columns, some become reference values, and some do not need database storage at all. The model should reflect business significance and persistence needs.
Strong and Weak Entities
A strong entity can usually be identified independently. A customer is a common example. A customer may have a customer ID, name, email, and phone number. The customer exists conceptually without needing another entity to identify it.
Customer
|-- customer_id
|-- name
|-- email
|-- phone
A weak entity depends on another entity for identification or existence. An order item is a common example. An order item usually makes sense only in the context of an order. It identifies a product and quantity inside a particular order. Without the order, the order item has no independent business meaning.
Order
|
Order Item
The exact implementation depends on the design. An order item table may use a composite key such as order_id plus product_id, or it may use a surrogate order_item_id. The modeling idea is that order item depends on order.
What Is an Attribute?
An attribute describes a property of an entity. For a customer entity, attributes may include customer ID, name, email, phone, city, registration date, and status. When implemented in a relational table, attributes commonly become columns.
Customer
|-- customer_id
|-- name
|-- email
|-- phone
|-- city
For an employee entity, attributes may include employee ID, first name, last name, salary, hire date, and department ID. The physical SQL implementation may look like this:
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
salary DECIMAL(10,2),
hire_date DATE
);
Attributes should belong to the correct entity. A customer email belongs to customer, not order. An order date belongs to order, not customer. A product price belongs to product, but the unit price charged for a specific order item may belong to order item because it captures the price at the time of purchase.
Types of Attributes
A simple attribute cannot meaningfully be divided further for the chosen model. Examples include salary, age, employee ID, order status, and product price. Whether an attribute is simple depends on the business need. A full name may be simple in one system and split into first name and last name in another.
A composite attribute can be divided into smaller components. Address is a common example. Instead of storing one large address string, a model may split it into street, city, state, postal code, and country.
Address
|-- street
|-- city
|-- state
|-- postal_code
A multi-valued attribute can have multiple values for one entity. A customer may have several phone numbers: home phone, mobile phone, and work phone. A poor design might use phone1, phone2, and phone3. A better design creates a separate customer phone table so any number of phone numbers can be stored.
customers
|
customer_phones
A derived attribute can be calculated from other data. Age can be calculated from date of birth. A line total can be calculated from quantity multiplied by unit price. Whether derived values should be stored depends on business and performance requirements. Storing derived values can improve reporting speed but creates consistency risks if source values change.
What Is a Relationship?
A relationship describes how entities are associated. Customers place orders. Employees belong to departments. Students enroll in courses. Orders contain products. Accounts have transactions. Test runs contain test results. Relationships are one of the most important parts of relational modeling because they show how separate tables connect.
A relationship is often implemented using foreign keys. If one customer can place many orders, the orders table can store customer_id as a foreign key that references the customers table. This allows SQL joins to combine customer and order data when needed.
customers.customer_id
|
orders.customer_id
Good relationship modeling prevents duplicate data. Instead of storing customer name and email repeatedly in every order row, the order references the customer. Customer details live in the customer table. Order details live in the order table. The relationship connects them.
One-to-One Relationships
A one-to-one relationship means one record in entity A relates to at most one relevant record in entity B, and vice versa under the business rule. A common conceptual example is person and passport, though real-world rules can vary by country and system.
Person
1
|
|
1
Passport
One-to-one relationships are less common than one-to-many relationships, but they appear in database design. They may be used to separate optional details, sensitive fields, large columns, or subtype information. For example, an employee table may store core employee data, while an employee_security table stores sensitive security details with stricter permissions.
Before creating a separate one-to-one table, ask whether the separation has a real purpose. If the data always exists together, has the same lifecycle, and has the same security rules, keeping it in one table may be simpler. If the data has different security, optionality, or lifecycle, separation may be justified.
One-to-Many Relationships
A one-to-many relationship is extremely common. One customer can have many orders. One department can have many employees. One project can have many tasks. One author can write many articles. The child table usually contains a foreign key pointing to the parent table.
Customer
1
|
|
N
Order
The implementation may look like this:
customers.customer_id
|
orders.customer_id
Example data makes the relationship clear:
| customer_id | name |
|---|---|
| 101 | John |
| 102 | Alice |
| order_id | customer_id |
|---|---|
| 5001 | 101 |
| 5002 | 101 |
| 5003 | 102 |
Customer 101 has two orders. Customer 102 has one order. This relationship is simple, flexible, and easy to query using joins.
Many-to-Many Relationships
A many-to-many relationship means many records in one entity can relate to many records in another entity. Students and courses are a classic example. One student can take many courses, and one course can contain many students.
Students
|
| many-to-many
|
Courses
Relational databases usually resolve many-to-many relationships using a junction table. For students and courses, the junction table may be called enrollments.
Students
|
Enrollments
|
Courses
Example tables may look like this:
| student_id | name |
|---|---|
| 1 | John |
| 2 | Alice |
| course_id | course_name |
|---|---|
| 100 | SQL |
| 200 | Java |
| student_id | course_id |
|---|---|
| 1 | 100 |
| 1 | 200 |
| 2 | 100 |
The enrollments table connects students and courses. It can also store relationship-specific attributes such as enrollment date, grade, and status. Those attributes belong to the relationship, not purely to student or course.
Cardinality and Optionality
Cardinality describes how many instances of one entity can relate to another. Common cardinalities are one-to-one, one-to-many, and many-to-many. These are often written as 1:1, 1:N, and N:M.
1:1 -> One-to-One
1:N -> One-to-Many
N:M -> Many-to-Many
Optionality describes whether participation in a relationship is required or optional. A customer might exist without ever placing an order, so a customer can have zero or many orders. But every order may require exactly one customer. That rule affects whether orders.customer_id is nullable or not null.
Customer -> 0..Many Orders
Order -> 1 Customer
More precise relationship notation may use 0..1, 1..1, 0..*, and 1..*. Zero or one means optional single participation. Exactly one means mandatory single participation. Zero or many means optional multiple participation. One or many means at least one related row is required.
Cardinality and optionality are not academic details. They become real database rules. They influence foreign keys, not-null constraints, unique constraints, junction tables, and application validation.
Primary Keys
A primary key uniquely identifies each row. Primary keys are fundamental because each entity instance should generally be uniquely identifiable. Without a key, it is difficult to update, delete, reference, or join a specific row safely.
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100)
);
Here customer_id uniquely identifies each customer. Two rows should not have the same primary key value, and the primary key should not be null. Primary keys are also commonly referenced by foreign keys in related tables.
A good primary key should be stable, unique, and simple to reference. In many application databases, primary keys are generated numeric or UUID values. The right choice depends on system requirements, database product, scale, replication, and integration needs.
Natural Keys and Surrogate Keys
A natural key comes from business data. Examples may include email address, Social Security Number, vehicle identification number, ISBN, employee number, or national ID, depending on business rules. Natural keys can be meaningful, but they must be chosen carefully.
Natural keys may change, be long, contain sensitive information, fail to be globally unique, or have exceptions. An email address may change. A government identifier may have privacy restrictions. A product code may be reused in some systems. A value that looks unique today may not remain unique after the business expands.
A surrogate key is an artificial identifier created specifically for the database. It has no business meaning beyond identifying the row.
customer_id BIGINT PRIMARY KEY
Surrogate keys are common because they are stable and simple. A customer can change email address without changing the row's primary identifier. However, natural business uniqueness may still need to be protected using unique constraints. For example, even with a surrogate customer ID, an application may still require email to be unique.
Foreign Keys
A foreign key connects related entities. It stores a value in one table that references a primary key or unique key in another table. Foreign keys protect referential integrity by preventing child rows from pointing to missing parent rows.
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT NOT NULL,
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
);
This model says every order must belong to an existing customer. The customer_id column in orders references customer_id in customers. If someone tries to insert an order for a customer that does not exist, the database can reject the row.
customers
customer_id
|
orders
customer_id
Foreign keys are part of the data model because relationships are not just visual lines in a diagram. They become enforceable database rules. They also make joins meaningful and predictable.
Business Rules and Constraints
A good data model should represent business rules. If every order must belong to a customer, then orders.customer_id should be NOT NULL and should reference the customers table. If every product SKU must be unique, the products table should have a unique constraint on SKU. If product price cannot be negative, a check constraint can enforce that rule.
CREATE TABLE products (
product_id INT PRIMARY KEY,
product_name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) CHECK (price >= 0)
);
Common constraints include primary key, foreign key, not null, unique, check, and default. Constraints protect the model by making invalid states harder to store. They are especially important because databases are often updated by multiple systems: web applications, background jobs, import scripts, admin tools, APIs, and reporting processes.
Application validation is still useful, but database constraints are the final guardrail. If a rule is truly important to the data, consider enforcing it in the database model.
Identifying Entities from Requirements
Data modeling begins with requirements. Suppose a requirement says: customers can place orders, each order contains products, and customers can make payments for their orders. Candidate entities include customer, order, product, and payment. Candidate relationships include customer to order, order to product, and order to payment.
Customer -> Order
Order -> Product
Order -> Payment
Nouns in requirements often suggest candidate entities. In the sentence "A student registers for courses taught by instructors," the nouns student, course, and instructor are likely entities. Verbs often suggest relationships. Student registers for course. Instructor teaches course.
Student
registers for
Course
Instructor
teaches
Course
This noun and verb technique is useful, but it is not automatic. Not every noun becomes a table, and not every verb becomes a relationship. Business meaning decides the final model. Ask what must be stored, identified, related, queried, protected, and retained over time.
Avoid Repeating Groups
Repeating groups are a common beginner modeling problem. A table that stores product1, product2, and product3 in an order row has a fixed number of products and repeated structure. It becomes difficult to search, update, validate, and expand.
| order_id | product1 | product2 | product3 |
|---|---|---|---|
| 1001 | Laptop | Mouse | Keyboard |
A better model separates orders, order items, and products. One order can then contain any number of products. Each product appears as a separate order item row.
ORDERS
------
order_id
customer_id
order_date
ORDER_ITEMS
-----------
order_id
product_id
quantity
unit_price
PRODUCTS
--------
product_id
product_name
This model supports one product, three products, or fifty products in an order without changing table structure. It also makes it easier to query all orders containing a product, calculate totals, and enforce relationships.
Avoid Duplicating Business Data
Another common problem is duplicating business data unnecessarily. Suppose an orders table stores customer name and email in every order row:
| order_id | customer_id | customer_name | customer_email |
|---|---|---|---|
| 1001 | 101 | John | john@test.com |
| 1002 | 101 | John | john@test.com |
| 1003 | 101 | John | john@test.com |
Customer information is repeated. If John's email changes and it appears in 1,000 order rows, all 1,000 rows must be updated. If one row is missed, the database contains inconsistent customer information. This is an update anomaly.
A better model stores customer information once and references it from orders:
customers
|
orders
This reduces redundancy. Redundancy means storing the same information unnecessarily in multiple places. Some duplication may be deliberate for reporting or history, but accidental duplication is a modeling problem.
Insert, Update, and Delete Anomalies
Poor modeling can create anomalies. An update anomaly occurs when the same fact must be updated in many places and some copies may be missed. For example, if a customer's email is repeated in every order, changing the email becomes risky.
An insert anomaly occurs when the design prevents storing one kind of information until another kind exists. If customer details exist only inside an order table, you may be unable to store a new customer until the customer places an order. A customer should be able to exist independently from orders if the business allows it.
A delete anomaly occurs when deleting one row accidentally removes information that should be preserved. If customer details exist only in order rows, deleting a customer's last order may remove the only copy of the customer information. A better model separates customers from orders and connects them through a foreign key.
Normalization and Denormalization
Normalization is a systematic technique for organizing relational data and reducing problematic redundancy. Common normal forms include 1NF, 2NF, 3NF, and BCNF. At the basic modeling stage, the key idea is simple: store each business fact in the appropriate place and avoid unnecessary repetition.
Normalization helps prevent repeating groups, duplicated facts, update anomalies, insert anomalies, and delete anomalies. It usually creates cleaner relationships and better integrity. For example, separating customers, orders, products, and order items is a normalizing design choice.
Denormalization is deliberate duplication or precomputation for performance, reporting, or operational reasons. For example, an analytics table may store precomputed totals so reports can run faster. Denormalization is not automatically bad, but it should be a conscious decision based on measured needs, not accidental poor modeling.
Correct Logical Model
|
Measure Workload
|
Add Indexes
|
Optimize Queries
|
Denormalize only if justified
Entity Relationship Diagrams
An Entity Relationship Diagram, often called an ERD, visually represents entities and relationships. ERDs help teams discuss data design before writing SQL. They can show entities, attributes, keys, relationship lines, and cardinality.
CUSTOMER
--------
customer_id
name
email
|
| 1
|
| N
v
ORDER
-----
order_id
customer_id
order_date
A basic e-commerce ER model may show customer to order, order to order item, and order item to product:
CUSTOMER
|
| 1
|
| N
v
ORDER
|
| 1
|
| N
v
ORDER_ITEM
|
| N
|
| 1
v
PRODUCT
This can be read as one customer can have many orders, one order can have many order items, and one product can appear in many order items. Order item is an associative entity because it connects order and product and stores relationship-specific attributes such as quantity, unit price, and discount.
Naming Entities and Attributes
Good names make a data model easier to understand. Good entity names include customer, order, product, payment, employee, and department. Poor names include data, info, thing, table1, and record. Entity names should clearly represent business concepts.
Teams may choose singular names such as customer, order, and product, or plural names such as customers, orders, and products. Both conventions can work. The important rule is consistency across the database.
Good attribute names include customer_id, first_name, order_date, total_amount, and created_at. Poor names include id1, data, value, field2, and x. Column names should communicate business meaning without requiring constant explanation.
Choosing Appropriate Data Types
Physical modeling requires correct data types. Data types affect validation, storage, sorting, calculation, indexing, and application behavior. Poor data types can cause invalid values, wasted storage, precision problems, slow queries, and confusing conversions.
customer_id -> BIGINT
name -> VARCHAR(100)
price -> DECIMAL(10,2)
order_date -> DATE
created_at -> TIMESTAMP
Dates should be modeled using date or timestamp types, not generic text fields. A column such as order_date VARCHAR(50) makes sorting, filtering, validation, and date arithmetic harder. A real DATE or TIMESTAMP type allows the database to understand the value properly.
Money should be modeled carefully. Avoid inappropriate floating-point types for exact currency calculations. A common approach is DECIMAL(10,2), though exact type choice depends on the database and business requirements. Boolean values should also be modeled clearly. If a customer is active or inactive, use a clear boolean or well-defined status representation rather than unclear codes such as 1, 2, 9, or X without documentation.
Lookup and Reference Data
Some models contain reference data. Order status is a common example. Possible values may include NEW, PAID, SHIPPED, DELIVERED, and CANCELLED. Depending on requirements, these values may be modeled using check constraints, lookup tables, enumerated types, or application-controlled reference data.
ORDER_STATUS
------------
status_id
status_name
| status_id | status_name |
|---|---|
| 1 | NEW |
| 2 | PAID |
| 3 | SHIPPED |
orders.status_id
|
order_status.status_id
A lookup table is useful when values have additional attributes, need permissions, are managed by business users, or are referenced by many tables. A check constraint may be enough when the allowed values are small and stable. The model should match how the business manages the data.
Historical Data Modeling
Some business information changes over time. If history matters, the data model must preserve it. For example, if an employee table stores only current salary, you know the current salary but not previous salaries. If the business needs salary history, a separate salary history table may be required.
salary_history
|-- employee_id
|-- salary
|-- effective_from
|-- effective_to
The same question applies to addresses, order statuses, product prices, account ownership, subscription plans, and compliance data. Always ask whether the system needs only the current value or historical values too. This question can significantly change the model.
Sometimes events deserve their own entities. Payment, shipment, login, transaction, and audit event are examples. Rather than overwriting the latest state, storing events can preserve business history and support auditing, reporting, and troubleshooting.
Modeling Status and Events
Status values often look simple at first. An order may move from NEW to PAID to SHIPPED to DELIVERED. If the table stores only current status, the database knows the latest state but not when each change happened.
NEW
|
PAID
|
SHIPPED
|
DELIVERED
If the business needs status history, a separate order status history table may be needed. It can store order ID, status, changed time, changed by, and reason. This supports auditability and reporting.
The same thinking applies to soft deletes. Some systems do not physically delete important records. Instead, they store is_deleted or deleted_at. Soft deletes can help with recovery and audit history, but they also add query complexity because normal queries must exclude deleted records where appropriate. Use the pattern deliberately.
Avoid Multiple Values in One Column
Storing multiple values in one column is a common modeling mistake. For example, a phone_numbers column containing 555-1111,555-2222,555-3333 makes searching, validation, formatting, and uniqueness difficult. It also prevents each phone number from having its own type or status.
Bad:
phone_numbers = '555-1111,555-2222,555-3333'
Better:
customer_phones
| customer_id | phone_number |
|---|---|
| 101 | 555-1111 |
| 101 | 555-2222 |
Comma-separated IDs are another version of the same problem. A column such as product_ids = '100,200,300' should usually become a related table such as order_items. Each relationship should be represented as a separate row so SQL can filter, join, validate, and index it properly.
Avoid Over-Modeling and One Giant Table
Good modeling balances normalization, simplicity, and business requirements. Not every field needs its own table. Creating separate tables for first name, last name, and city would normally be unnecessary. Over-modeling creates too many joins, too much complexity, and a database that is hard to use.
The opposite mistake is putting everything into one giant table such as customer_order_product_payment_shipping_everything. This leads to massive duplication, many nullable columns, difficult updates, poor maintainability, and unclear ownership. Independent business concepts should be separated into appropriate entities.
The right design sits between these extremes. Use separate tables when they represent independent entities, repeating groups, many-to-many relationships, history, or distinct ownership. Keep attributes in the same table when they naturally describe the same entity and share the same lifecycle.
Identify Ownership of Attributes
A useful modeling question is: which entity does this attribute belong to? Customer email belongs to customer, not order. Order date belongs to order, not customer. Product name belongs to product, not order item. Quantity belongs to order item because it describes how many units of a product were purchased in a specific order.
Some attributes belong to relationships. In a student and course relationship, enrollment date, grade, and enrollment status belong naturally to enrollment. They are not purely student attributes and not purely course attributes. This is why the enrollment table becomes more than a junction table; it becomes an associative entity.
Student
|
Enrollment
|
Course
Enrollment attributes:
enrollment_date
grade
status
Correct ownership reduces duplication and improves clarity. When an attribute feels hard to place, it often means a relationship or missing entity needs to be modeled.
Library, Banking, HR, and Testing Examples
A library data model may include member, book, author, and loan. A member borrows books. An author writes books. Because one book can have many authors and one author can write many books, a book_authors junction table may be needed.
members
books
authors
book_authors
loans
A banking model may include customer, account, transaction, and branch. A customer owns accounts. An account has transactions. Depending on the business, accounts may support multiple owners, requiring a junction table between customers and accounts.
An HR model may include employee, department, and project. One department can have many employees. Employees and projects may have a many-to-many relationship, which can become an employee_projects table.
A software testing application may include project, test case, test run, test result, defect, and tester. Projects contain test cases. Test runs contain test results. Defects may be linked to test cases or test results. Data modeling applies to every software domain, not just shopping or banking systems.
Model Before Writing SQL
A common mistake is creating tables before understanding the business. SQL implementation should follow the model. A practical workflow starts with requirements, then modeling, review, table creation, and SQL development.
Requirements
|
Model
|
Review
|
Create Tables
|
Write SQL
Before creating tables, ask what business objects exist, what attributes describe them, how they are related, which relationships are mandatory, which values must be unique, what data can be null, what history must be retained, what business rules must be enforced, what queries the application needs, and how much data is expected.
The same real-world concept can be modeled differently depending on requirements. One application may need only a customer's current address. Another may need multiple addresses, address types, and address history. There is rarely one universal model for every system. Requirements matter most.
Model for Integrity and Queryability
The model should make invalid states difficult to store. If every order must belong to a customer, use a not-null foreign key. If every product SKU must be unique, use a unique constraint. If price cannot be negative, use a check constraint. These rules protect data integrity.
customer_id INT NOT NULL,
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
The design should also support important queries. If a common requirement is to find all products ordered by a customer, the model should support a natural join path from customer to order to order item to product.
Customer
|
Order
|
Order_Item
|
Product
Performance matters, but avoid prematurely destroying a clean model. Start with correctness and maintainability. Then measure real workload, add indexes, optimize queries, and denormalize only when justified by evidence.
Data Modeling and Indexes
Indexes are usually part of the physical design. They do not change the logical relationship between entities, but they can make access faster. For example, if the application frequently finds orders for a customer, an index on orders.customer_id can help.
CREATE INDEX idx_orders_customer_id
ON orders(customer_id);
This index does not change the relationship that customers have orders. It changes how efficiently the database may find related order rows. Physical design choices such as indexes should be based on query patterns, data volume, and performance needs.
Indexing every column is not good modeling. Each index consumes storage and adds write overhead. Good index design supports important queries while keeping maintenance cost reasonable.
Data Modeling and Security
Some sensitive data needs special modeling. Password hashes, financial information, personal identifiers, medical data, audit logs, and payment-related information may require separation, encryption, access control, masking, retention rules, and careful auditing.
Security should be considered during design, not added only at the end. For example, highly sensitive columns may be placed in a separate table with stricter permissions. Audit events may be stored separately so changes can be traced. Personal data may require retention and deletion rules based on policy or regulation.
The right design depends on the sensitivity of the data and the database product's security features. Good modeling asks who should access the data, how long it should be stored, whether it must be encrypted, and how changes should be tracked.
Operational vs Analytical Modeling
Data modeling depends heavily on workload. Operational databases, often called OLTP systems, usually prioritize transactions, consistency, normalized structures, current data, and reliable updates. An e-commerce transactional model may contain customers, orders, order items, products, and payments. It supports placing orders, making payments, and updating inventory.
customers
orders
order_items
products
payments
Analytical systems often use different modeling patterns. A data warehouse may use fact tables and dimension tables. It may store historical data and precomputed values to support reporting.
fact_sales
dim_customer
dim_product
dim_date
dim_store
This kind of model is optimized for questions such as sales by year, sales by product, sales by region, and customer trends. It is different from a typical normalized OLTP design. The best model depends on whether the system is primarily processing transactions or analyzing data.
Common Data Modeling Mistakes
Common mistakes include creating tables before understanding requirements, missing primary keys, missing foreign keys, repeating the same information everywhere, storing comma-separated values, using too many nullable columns, choosing wrong data types, storing calculated values unnecessarily, ignoring history, using vague names, mixing unrelated entities, over-normalizing, prematurely denormalizing, ignoring important query patterns, and modeling only from UI screens.
Modeling based only on screens is especially risky. A page may display customer name, order number, product name, payment status, and shipping status together. That screen is a presentation layer. The database model should represent customer, order, product, payment, and shipment as business entities when those concepts have independent meaning.
Another common mistake is ignoring future data growth. A design that works for 100 records may not work for 100 million records. You do not need to over-engineer every small system, but you should understand expected volume, query needs, history requirements, and operational constraints before finalizing the model.
Complete E-Commerce Model Example
A practical e-commerce model may start with customer, order, order item, and product. One customer can place many orders. One order can contain many order items. One product can appear in many order items. Additional entities may include payment, shipment, address, inventory, refund, coupon, and return.
CUSTOMER
--------
customer_id
name
email
ORDER
-----
order_id
customer_id
order_date
status
ORDER_ITEM
----------
order_id
product_id
quantity
unit_price
PRODUCT
-------
product_id
product_name
price
The SQL implementation may look like this:
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) UNIQUE
);
CREATE TABLE products (
product_id INT PRIMARY KEY,
product_name VARCHAR(150) NOT NULL,
price DECIMAL(10,2) NOT NULL
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT NOT NULL,
order_date DATE NOT NULL,
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
);
CREATE TABLE order_items (
order_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id)
REFERENCES orders(order_id),
FOREIGN KEY (product_id)
REFERENCES products(product_id)
);
The SQL is the implementation of the model. The model came first: customers place orders, orders contain products, and order items store relationship-specific details such as quantity and unit price.
Practical Data Modeling Workflow
A practical workflow starts by understanding requirements. Then identify entities, identify attributes, define primary keys, identify relationships, define cardinality, add foreign keys, apply business constraints, normalize the design, review query needs, build the physical model, and implement with SQL.
1. Understand Requirements
|
2. Identify Entities
|
3. Identify Attributes
|
4. Define Primary Keys
|
5. Identify Relationships
|
6. Define Cardinality
|
7. Add Foreign Keys
|
8. Apply Business Constraints
|
9. Normalize
|
10. Review Query Needs
|
11. Build Physical Model
|
12. Implement with SQL
Before implementation, review entities, attributes, keys, relationships, cardinality, optionality, constraints, naming, business rules, security, and expected queries. This review can prevent expensive redesign later.
Simple Mental Model
Think of data modeling as answering six questions. What things do we store? What attributes do they have? What identifies them? How are they connected? What rules apply? How will we implement them?
WHAT?
-> What things do we store?
WHAT ABOUT THEM?
-> What attributes do they have?
WHO IDENTIFIES THEM?
-> What are their keys?
HOW ARE THEY CONNECTED?
-> What relationships exist?
WHAT RULES APPLY?
-> What constraints are required?
HOW WILL WE IMPLEMENT THEM?
-> What tables, columns, and data types are needed?
If you can answer these questions clearly, you are much closer to a strong database design. If the answers are vague, the model needs more discussion before tables are created.
Interview-Ready Explanation
A short interview answer is: data modeling is the process of converting business requirements into a structured database design by identifying entities, attributes, relationships, keys, cardinality, and constraints before creating tables.
A stronger answer is: data modeling happens at conceptual, logical, and physical levels. The conceptual model captures major business entities and relationships. The logical model adds attributes, keys, relationship rules, cardinality, and constraints. The physical model converts the design into database-specific tables, columns, data types, indexes, and constraints. Good modeling reduces redundancy, improves integrity, supports queries, and makes applications easier to maintain.
You can also mention that modeling should not simply copy the UI. A screen may combine customer, order, product, payment, and shipping data, but the database should model the underlying business entities and connect them with relationships. SQL joins can produce the screen output from a clean model.
Key Takeaway
Data modeling is the design process that turns business requirements into a structured database representation. It begins with real business concepts and ends with tables, columns, keys, relationships, constraints, and SQL implementation.
Business Requirements
|
Entities
|
Attributes
|
Keys
|
Relationships
|
Cardinality
|
Constraints
|
Tables
|
SQL
The three main modeling levels are conceptual, logical, and physical. The conceptual model gives a high-level business view. The logical model defines entities, attributes, keys, and relationships. The physical model defines tables, columns, data types, indexes, and DBMS-specific implementation.
A strong data model reduces redundancy, protects data integrity, makes SQL easier to write, and gives applications a structure that can grow as requirements evolve. Good SQL design does not begin with tables. It begins with understanding the business data well enough to model it correctly.