This deliverable provides comprehensive, detailed, and production-ready code examples for designing and managing database schemas. We focus on a common application scenario – a simplified E-commerce platform – to illustrate best practices in schema design, utilizing both direct SQL DDL (Data Definition Language) and a programmatic approach using Python for schema definition.
A well-designed database schema is fundamental to the performance, scalability, maintainability, and data integrity of any application. This output aims to provide you with a robust foundation, covering:
Before diving into the code, it's crucial to understand the underlying principles that guide good database schema design:
VARCHAR for text, INTEGER for numbers, TIMESTAMP for dates) to optimize storage and performance.NOT NULL, UNIQUE, CHECK).This section provides a complete SQL DDL script for a simplified E-commerce platform. It demonstrates a practical application of the design principles discussed above.
Schema Overview:
users: Stores customer information.products: Contains details about items available for sale.categories: Organizes products into different groups.addresses: Stores physical addresses, linked to users and potentially orders.orders: Records customer orders.order_items: Details individual products within an order.carts: Represents a user's shopping cart.cart_items: Details individual products within a cart.-- professional_ecommerce_schema.sql
-- Database Schema Designer: E-commerce Platform Example (PostgreSQL DDL)
-- This script creates a database schema for a simplified E-commerce application.
-- It includes tables for users, products, categories, addresses, orders, and cart functionality.
-- Best practices like primary keys, foreign keys, indexes, and constraints are applied.
-- Set a standard for text data (UTF-8 for international characters)
-- This is typically configured at the database/cluster level, but good to keep in mind.
-- For a specific session, you might use: SET client_encoding TO 'UTF8';
-- -----------------------------------------------------------------------------
-- Table: users
-- Description: Stores information about registered users/customers.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS users (
user_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the user, using UUID for distributed systems compatibility
username VARCHAR(50) UNIQUE NOT NULL, -- Unique username for login
email VARCHAR(100) UNIQUE NOT NULL, -- Unique email address, used for communication and login
password_hash VARCHAR(255) NOT NULL, -- Hashed password for security
first_name VARCHAR(50),
last_name VARCHAR(50),
phone_number VARCHAR(20),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- Timestamp of user creation
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- Timestamp of last update
);
-- Index for faster lookups on email and username
CREATE INDEX IF NOT EXISTS idx_users_email ON users (email);
CREATE INDEX IF NOT EXISTS idx_users_username ON users (username);
-- -----------------------------------------------------------------------------
-- Table: categories
-- Description: Organizes products into different categories.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS categories (
category_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the category
name VARCHAR(100) UNIQUE NOT NULL, -- Name of the category (e.g., "Electronics", "Books")
description TEXT, -- Optional description for the category
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- -----------------------------------------------------------------------------
-- Table: products
-- Description: Stores details about products available for sale.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS products (
product_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the product
name VARCHAR(255) NOT NULL, -- Name of the product
description TEXT, -- Detailed description of the product
price DECIMAL(10, 2) NOT NULL CHECK (price >= 0), -- Price of the product, cannot be negative
stock_quantity INTEGER NOT NULL CHECK (stock_quantity >= 0), -- Current stock level, cannot be negative
category_id UUID REFERENCES categories(category_id) ON DELETE SET NULL, -- Foreign key to categories table
image_url VARCHAR(255), -- URL to the product image
sku VARCHAR(100) UNIQUE, -- Stock Keeping Unit, unique product code
is_active BOOLEAN DEFAULT TRUE, -- Whether the product is currently active/available
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Index for faster lookups on product name and category
CREATE INDEX IF NOT EXISTS idx_products_name ON products (name);
CREATE INDEX IF NOT EXISTS idx_products_category_id ON products (category_id);
CREATE INDEX IF NOT EXISTS idx_products_sku ON products (sku);
-- -----------------------------------------------------------------------------
-- Table: addresses
-- Description: Stores physical addresses, linked to users.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS addresses (
address_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the address
user_id UUID NOT NULL REFERENCES users(user_id) ON DELETE CASCADE, -- Foreign key to users table
address_line1 VARCHAR(255) NOT NULL,
address_line2 VARCHAR(255),
city VARCHAR(100) NOT NULL,
state VARCHAR(100),
postal_code VARCHAR(20) NOT NULL,
country VARCHAR(100) NOT NULL,
is_default BOOLEAN DEFAULT FALSE, -- Whether this is the user's default address
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Index for faster lookups on user_id for addresses
CREATE INDEX IF NOT EXISTS idx_addresses_user_id ON addresses (user_id);
-- Enforce that a user can have at most one default address
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_default_address ON addresses (user_id) WHERE is_default = TRUE;
-- -----------------------------------------------------------------------------
-- Table: orders
-- Description: Records customer orders.
-- -----------------------------------------------------------------------------
CREATE TYPE order_status AS ENUM ('pending', 'processing', 'shipped', 'delivered', 'cancelled');
CREATE TABLE IF NOT EXISTS orders (
order_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the order
user_id UUID NOT NULL REFERENCES users(user_id) ON DELETE CASCADE, -- Foreign key to users table
shipping_address_id UUID REFERENCES addresses(address_id) ON DELETE SET NULL, -- Shipping address for the order
billing_address_id UUID REFERENCES addresses(address_id) ON DELETE SET NULL, -- Billing address for the order
order_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
status order_status DEFAULT 'pending', -- Current status of the order (e.g., pending, shipped)
total_amount DECIMAL(10, 2) NOT NULL CHECK (total_amount >= 0), -- Total amount of the order
payment_method VARCHAR(50), -- e.g., "Credit Card", "PayPal"
transaction_id VARCHAR(255), -- Reference to payment gateway transaction
notes TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Index for faster lookups on user_id and order_date
CREATE INDEX IF NOT EXISTS idx_orders_user_id ON orders (user_id);
CREATE INDEX IF NOT EXISTS idx_orders_order_date ON orders (order_date);
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders (status);
-- -----------------------------------------------------------------------------
-- Table: order_items
-- Description: Details individual products within an order.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS order_items (
order_item_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the order item
order_id UUID NOT NULL REFERENCES orders(order_id) ON DELETE CASCADE, -- Foreign key to orders table
product_id UUID NOT NULL REFERENCES products(product_id) ON DELETE RESTRICT, -- Foreign key to products table
quantity INTEGER NOT NULL CHECK (quantity > 0), -- Quantity of the product in the order
price_at_purchase DECIMAL(10, 2) NOT NULL CHECK (price_at_purchase >= 0), -- Price of the product at the time of purchase
-- Denormalization: Store price at purchase to handle product price changes over time
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Composite index for efficient querying of items within an order and product details
CREATE UNIQUE INDEX IF NOT EXISTS idx_order_items_order_product ON order_items (order_id, product_id);
CREATE INDEX IF NOT EXISTS idx_order_items_product_id ON order_items (product_id);
-- -----------------------------------------------------------------------------
-- Table: carts
-- Description: Represents a user's shopping cart. Each user has one cart.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS carts (
cart_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the cart
user_id UUID NOT NULL UNIQUE REFERENCES users(user_id) ON DELETE CASCADE, -- Foreign key to users table, unique per user
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- -----------------------------------------------------------------------------
-- Table: cart_items
-- Description: Details individual products within a user's cart.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS cart_items (
cart_item_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Unique identifier for the cart item
cart_id UUID NOT NULL REFERENCES carts(cart_id) ON DELETE CASCADE, -- Foreign key to carts table
product_id UUID NOT NULL REFERENCES products(product_id) ON DELETE CASCADE, -- Foreign key to products table
quantity INTEGER NOT NULL CHECK (quantity > 0), -- Quantity of the product in the cart
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Composite unique index to ensure a product appears only once in a given cart
CREATE UNIQUE INDEX IF NOT EXISTS idx_cart_items_cart_product ON cart_items (cart_id, product_id);
CREATE INDEX IF NOT EXISTS idx_cart_items_product_id ON cart_items (product_id);
-- -----------------------------------------------------------------------------
-- Functions for automatically updating 'updated_at' columns
-- This is a common pattern in PostgreSQL for audit trails
-- -----------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Apply the trigger to all tables that have an 'updated_at' column
DO $$
DECLARE
t record;
BEGIN
FOR t IN
SELECT table_name
FROM information_schema.columns
WHERE column_name = 'updated_at'
AND table_schema = current_schema() -- Adjust schema if necessary
LOOP
EXECUTE format('
CREATE OR REPLACE TRIGGER set_updated_at
BEFORE UPDATE ON %I
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
', t.table_name);
END LOOP;
END;
$$ LANGUAGE plpgsql;
-- End of professional_ecommerce_schema.sql
This document outlines a comprehensive, 8-week study plan designed to equip individuals with the foundational knowledge and practical skills required to excel as a Database Schema Designer. This plan focuses on theoretical concepts, practical application, and best practices, culminating in the ability to design robust, efficient, and scalable database schemas.
The role of a Database Schema Designer is critical in ensuring data integrity, application performance, and long-term system maintainability. This study plan is structured to provide a deep dive into relational database design principles, SQL DDL implementation, performance optimization, and an introduction to NoSQL schema considerations.
Overall Goal: To develop a strong understanding of database design principles, master the creation of effective and efficient database schemas, and gain practical experience in translating business requirements into technical database designs.
Upon successful completion of this 8-week study plan, participants will be able to:
This 8-week schedule balances theoretical learning with hands-on practical exercises and project work. Each week focuses on a core set of topics, building progressively towards a comprehensive understanding.
| Week | Theme | Key Topics | Practical Exercises / Activities |
| :--- | :---- | :--------- | :------------------------------- |
| Week 1 | Foundations of Database Systems & Relational Model | - Introduction to Databases (RDBMS vs. NoSQL)<br>- Data Models & Schema Concepts<br>- Relational Model Fundamentals (Tables, Rows, Columns)<br>- Keys: Primary, Foreign, Candidate, Composite, Super Keys<br>- Relationships: One-to-One, One-to-Many, Many-to-Many | - Define key terms.<br>- Identify keys and relationships in simple scenarios.<br>- Sketch basic table structures for given data. |
| Week 2 | Entity-Relationship (ER) Modeling | - Purpose and Components of ERDs<br>- Entities, Attributes (Simple, Composite, Multi-valued, Derived)<br>- Relationships: Cardinality (1, N) & Modality (0, 1)<br>- Drawing Conceptual and Logical ERDs<br>- Introduction to ERD Tools (e.g., draw.io, Lucidchart) | - Create ERDs for 2-3 small case studies (e.g., Library System, Online Store).<br>- Practice identifying entities, attributes, and relationships. |
| Week 3 | Normalization & Denormalization | - Data Redundancy and Anomalies<br>- Functional Dependencies<br>- Normal Forms: 1NF, 2NF, 3NF, BCNF<br>- Introduction to 4NF, 5NF<br>- When and Why to Denormalize (Performance vs. Integrity) | - Normalize a given unnormalized table to 3NF/BCNF.<br>- Analyze scenarios for potential denormalization.<br>- Write justifications for chosen normalization levels. |
| Week 4 | SQL DDL & Schema Implementation | - Translating Logical Design to Physical Schema<br>- CREATE TABLE statement: Data Types, Constraints (PK, FK, UNIQUE, NOT NULL, CHECK, DEFAULT)<br>- ALTER TABLE statement: Adding/Modifying Columns & Constraints<br>- DROP TABLE<br>- Indexing Basics (Clustered vs. Non-Clustered) | - Implement a normalized schema (from Week 3 or new case study) using SQL DDL.<br>- Practice adding/modifying constraints and columns.<br>- Create basic indexes on relevant columns. |
| Week 5 | Indexing, Views, and Performance Optimization | - Advanced Indexing Strategies (covering indexes, index selection)<br>- Understanding Query Execution Plans<br>- CREATE VIEW, ALTER VIEW, DROP VIEW<br>- Materialized Views (basics)<br>- Partitioning (introduction) | - Analyze sample query plans and identify bottlenecks.<br>- Create views for common data access patterns.<br>- Experiment with different indexing strategies and benchmark query performance. |
| Week 6 | Advanced Schema Objects & Security Considerations | - Stored Procedures and Functions: Design & Implementation<br>- Triggers: Use Cases and Best Practices<br>- User Management: GRANT and REVOKE Permissions<br>- Role-Based Access Control (RBAC) in Schema Design<br>- Schema Evolution and Versioning | - Write simple stored procedures and functions.<br>- Implement a trigger for data auditing or integrity.<br>- Define roles and assign permissions for a sample application. |
| Week 7 | NoSQL Schema Design & Data Warehousing Basics | - Introduction to NoSQL Databases (Document, Key-Value, Column-Family, Graph)<br>- Schema-less vs. Schema-on-Read<br>- Design Patterns for NoSQL (embedding, linking)<br>- Introduction to Data Warehousing Concepts<br>- Star Schema and Snowflake Schema Basics | - Analyze a use case and suggest an appropriate NoSQL database type.<br>- Design a simple document schema for a given scenario.<br>- Understand the differences between OLTP and OLAP schemas. |
| Week 8 | Project Application & Best Practices | - Comprehensive Database Schema Design Project (from requirements to DDL)<br>- Documentation Best Practices (Data Dictionary, Schema Diagrams)<br>- Schema Review and Refactoring Techniques<br>- Common Design Anti-Patterns and How to Avoid Them<br>- Future Trends in Database Design | - Final Project: Design a complete database schema for a complex application, including ERDs, DDL, indexing strategy, and security considerations.<br>- Present and justify design choices. |
A diverse set of resources will enhance learning and provide different perspectives.
* "Database System Concepts" by Abraham Silberschatz, Henry F. Korth, S. Sudarshan (Classic textbook for theoretical foundations).
"SQL Antipatterns: Avoiding the Pitfalls of Database Programming" by Bill Karwin (Excellent for understanding what not* to do and why).
* "Refactoring Databases: Evolutionary Design" by Scott W. Ambler and Pramod Sadalage (Focuses on adapting existing schemas).
* "Learning SQL" by Alan Beaulieu (Practical guide to SQL, including DDL).
* "Designing Data-Intensive Applications" by Martin Kleppmann (Advanced, covers distributed systems and NoSQL deeply).
* Coursera:
* "Relational Database Design" (University of Michigan)
* "Database Systems Concepts & Design" (Georgia Institute of Technology)
* Udemy/edX: Search for "Database Design," "SQL DDL," "Advanced Database Concepts."
* Khan Academy: "SQL Tutorial" (Good for absolute beginners).
* YouTube Channels: The Code Guy, Tech with Tim (often have database design series).
* PostgreSQL Documentation: Comprehensive and high quality.
* MySQL Documentation: User-friendly and detailed.
* Microsoft SQL Server Documentation: Extensive resources for SQL Server.
* NoSQL Docs: MongoDB, Cassandra, Redis official documentation for specific design patterns.
* ERD Tools:
* draw.io (Diagrams.net): Free, web-based, versatile.
* Lucidchart: User-friendly, professional ERD creation.
* dbdiagram.io: Simple, code-first ERD generation.
* Visual Studio Code Extensions: For ERD generation from DDL or vice-versa.
* SQL Clients/IDEs:
* DBeaver: Free, universal database tool.
* pgAdmin (for PostgreSQL): Feature-rich.
* MySQL Workbench (for MySQL): Comprehensive.
* SQL Server Management Studio (SSMS): For SQL Server.
* Stack Overflow / Database Administrators Stack Exchange: For specific questions and troubleshooting.
* SQLBlog.com, Redgate Blog: Industry insights and best practices.
* Medium.com: Search for "database design," "schema design."
Achieving these milestones will mark significant progress and validate understanding at key stages of the study plan.
A multi-faceted approach to assessment will ensure a thorough understanding of concepts and practical application skills.
* Short online quizzes (multiple-choice, true/false) to test theoretical knowledge.
* Practical exercises (e.g., normalizing a dataset, writing DDL for a specific table) to reinforce concepts.
* ERD Submission: Regular submission of ERDs for various case studies, reviewed for correctness and adherence to best practices.
* SQL DDL Scripting: Submission of SQL scripts to create and modify database schemas, evaluated for syntax, logical correctness, and efficiency.
UUID for user_id, product_id, order_id, etc., provides several benefits:* Uniqueness: Globally unique identifiers, reducing collision risk in distributed systems or merged databases.
* Scalability: Allows for generation in application layer without
Project: Database Schema Designer
Step: Review and Document
Date: October 26, 2023
This document presents the comprehensive review and detailed documentation of the proposed database schema. The schema has been meticulously designed and reviewed to meet the identified business requirements, ensuring data integrity, optimal performance, scalability, and maintainability.
The proposed schema provides a robust foundation for your application, promoting efficient data storage, retrieval, and management. It incorporates best practices in database design, including appropriate normalization, clear relationship definitions, and thoughtful consideration of data types and constraints. This deliverable includes a conceptual overview, detailed DDL scripts, a comprehensive data dictionary, and actionable implementation guidelines.
Our review process focused on validating the schema against key design principles and anticipated system requirements.
The schema underwent an iterative design and review process, incorporating:
WHERE, JOIN, and ORDER BY clauses have been identified for indexing to enhance query performance. Unique constraints implicitly create indexes.VARCHAR with length limits, INTEGER, DECIMAL for monetary values, TIMESTAMP WITH TIME ZONE for date/time) have been selected to optimize storage and ensure data accuracy.snake_case naming has been applied for tables and columns, prefixed with pk_ for primary keys and fk_ for foreign keys for clarity.Below is the detailed proposed database schema, including an overview of the Entity-Relationship Diagram (ERD) and the Data Definition Language (DDL) scripts for creating the tables and relationships.
(Note: A graphical ERD would be provided as a separate attachment or integrated visually in a live presentation.)
The ERD visually represents the entities (tables) in the system and the relationships between them.
Users, Products, Orders, Categories, Order_Items).username for Users, price for Products).User can place multiple Orders (One-to-Many), an Order contains multiple Order_Items (One-to-Many)).Key Entities and Relationships (Example: E-commerce System):
The following DDL script is provided for a PostgreSQL-compatible database. Adjustments may be necessary for other database systems (e.g., MySQL, SQL Server, Oracle).
-- Schema: public
-- Table: Categories
CREATE TABLE Categories (
pk_category_id SERIAL PRIMARY KEY,
category_name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Table: Products
CREATE TABLE Products (
pk_product_id SERIAL PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL CHECK (price >= 0),
stock_quantity INTEGER NOT NULL CHECK (stock_quantity >= 0),
fk_category_id INTEGER,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_category
FOREIGN KEY (fk_category_id)
REFERENCES Categories (pk_category_id)
ON UPDATE CASCADE
ON DELETE SET NULL
);
-- Table: Users
CREATE TABLE Users (
pk_user_id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
first_name VARCHAR(100),
last_name VARCHAR(100),
address TEXT,
phone_number VARCHAR(20),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Table: Orders
CREATE TABLE Orders (
pk_order_id SERIAL PRIMARY KEY,
fk_user_id INTEGER NOT NULL,
order_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
total_amount DECIMAL(10, 2) NOT NULL CHECK (total_amount >= 0),
status VARCHAR(50) DEFAULT 'Pending' CHECK (status IN ('Pending', 'Processing', 'Shipped', 'Delivered', 'Cancelled')),
shipping_address TEXT,
billing_address TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_user
FOREIGN KEY (fk_user_id)
REFERENCES Users (pk_user_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
-- Table: Order_Items
CREATE TABLE Order_Items (
pk_order_item_id SERIAL PRIMARY KEY,
fk_order_id INTEGER NOT NULL,
fk_product_id INTEGER NOT NULL,
quantity INTEGER NOT NULL CHECK (quantity > 0),
price_at_purchase DECIMAL(10, 2) NOT NULL CHECK (price_at_purchase >= 0),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_order
FOREIGN KEY (fk_order_id)
REFERENCES Orders (pk_order_id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT fk_product
FOREIGN KEY (fk_product_id)
REFERENCES Products (pk_product_id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
UNIQUE (fk_order_id, fk_product_id) -- Ensures a product appears only once per order item
);
-- Table: Reviews
CREATE TABLE Reviews (
pk_review_id SERIAL PRIMARY KEY,
fk_user_id INTEGER NOT NULL,
fk_product_id INTEGER NOT NULL,
rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
comment TEXT,
review_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_user_review
FOREIGN KEY (fk_user_id)
REFERENCES Users (pk_user_id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT fk_product_review
FOREIGN KEY (fk_product_id)
REFERENCES Products (pk_product_id)
ON UPDATE CASCADE
ON DELETE CASCADE,
UNIQUE (fk_user_id, fk_product_id) -- Ensures a user can review a product only once
);
-- Indexes for performance optimization
CREATE INDEX idx_products_category_id ON Products (fk_category_id);
CREATE INDEX idx_orders_user_id ON Orders (fk_user_id);
CREATE INDEX idx_order_items_order_id ON Order_Items (fk_order_id);
CREATE INDEX idx_order_items_product_id ON Order_Items (fk_product_id);
CREATE INDEX idx_reviews_user_id ON Reviews (fk_user_id);
CREATE INDEX idx_reviews_product_id ON Reviews (fk_product_id);
-- Optional: Full-text search index for product names and descriptions
-- CREATE EXTENSION IF NOT EXISTS pg_trgm; -- For trigram-based search
-- CREATE INDEX idx_products_name_description_tsv ON Products USING GIN (to_tsvector('english', product_name || ' ' || description));
This section provides detailed documentation for each table and its columns, along with established naming conventions.
| Table Name | Column Name | Data Type | Nullable | Default Value | Constraints | Description | Example Data |
| :------------- | :----------------------- | :---------------------------- | :------- | :------------------- | :---------------------------------------- | :------------------------------------------------------------------------ | :----------------------- |
| Categories | pk_category_id | SERIAL | NO | Auto-increment | PRIMARY KEY | Unique identifier for the category. | 1, 2, 3 |
| | category_name | VARCHAR(100) | NO | | UNIQUE | Name of the product category. | 'Electronics', 'Books' |
| | description | TEXT | YES | | | Detailed description of the category. | 'Gadgets and appliances' |
| | created_at | TIMESTAMP WITH TIME ZONE | NO | CURRENT_TIMESTAMP | | Timestamp when the category was created. | '2023-01-15 10:00:00+00' |
| | updated_at | TIMESTAMP WITH TIME ZONE | NO | CURRENT_TIMESTAMP | | Timestamp of the last update to the category. | '2023-02-20 14:30:00+00' |
| Products | pk_product_id | SERIAL | NO | Auto-increment | PRIMARY KEY | Unique identifier for the product. | 101, 102 |
|