Overview
Sistema de Productos uses PostgreSQL as its relational database. The schema consists of three main tables (Productos, Categorias, Usuarios) with corresponding views for formatted data presentation.Database Structure
Tables
Categorias Table
Stores product categories with visual attributes (icon and color) for UI rendering.server/config/bd.sql
Column Details
id (Primary Key)
id (Primary Key)
- Type: SERIAL (auto-incrementing integer)
- Description: Unique identifier for each category
- Auto-generated: Yes
nombre (Unique)
nombre (Unique)
- Type: VARCHAR(50)
- Constraints: NOT NULL, UNIQUE
- Description: Category name (e.g., “Computadores”, “Celulares”)
- Validation: Must be unique across all categories
icono
icono
- Type: VARCHAR(50)
- Constraints: NOT NULL
- Description: Icon identifier for UI display (e.g., “Computador”, “Celular”)
- Usage: Referenced by frontend components for icon rendering
color
color
- Type: VARCHAR(50)
- Constraints: NOT NULL
- Description: Color name for category badges (e.g., “Índigo”, “Azul Cielo”)
- Usage: Used for visual categorization in the UI
descripcion
descripcion
- Type: TEXT
- Constraints: NULL allowed
- Description: Detailed description of the category
creado / actualizado
creado / actualizado
- Type: TIMESTAMP
- Description: Creation and last update timestamps
- creado: Required (NOT NULL)
- actualizado: Optional (NULL allowed)
Sample Data
Productos Table
Stores product information with pricing, inventory, and category relationship.server/config/bd.sql
Column Details
id (Primary Key)
id (Primary Key)
- Type: SERIAL
- Description: Unique identifier for each product
- Auto-generated: Yes
nombre (Unique)
nombre (Unique)
- Type: VARCHAR(100)
- Constraints: NOT NULL, UNIQUE
- Description: Product name
- Validation: Must be unique - no duplicate product names allowed
precio
precio
- Type: DECIMAL(10, 2)
- Constraints: NOT NULL
- Description: Product price with up to 10 digits total and 2 decimal places
- Example: 999.99, 1299.99
- Max value: 99,999,999.99
stock
stock
- Type: INT
- Constraints: NOT NULL
- Default: 0
- Description: Current inventory quantity
- Usage: Tracked for inventory management
descripcion
descripcion
- Type: TEXT
- Constraints: NULL allowed
- Description: Detailed product description
idCategoria (Foreign Key)
idCategoria (Foreign Key)
- Type: INT
- Constraints: NOT NULL, REFERENCES Categorias(id)
- Description: Links product to its category
- Relationship: Many products to one category
- Referential Integrity: Enforced by PostgreSQL
Sample Data
The foreign key constraint ensures that every product must belong to an existing category. Attempting to delete a category with associated products will fail unless cascading deletes are configured.
Usuarios Table
Stores user accounts with authentication credentials and role-based access control.server/config/bd.sql
Column Details
id (Primary Key)
id (Primary Key)
- Type: SERIAL
- Description: Unique identifier for each user
- Usage: Referenced in JWT tokens for authentication
nombre (Unique)
nombre (Unique)
- Type: VARCHAR(20)
- Constraints: NOT NULL, UNIQUE
- Description: Username for login
- Max Length: 20 characters
- Validation: Must be unique - no duplicate usernames
contrasena
contrasena
- Type: TEXT
- Constraints: NOT NULL
- Description: Hashed password (bcrypt or pgcrypto)
- Storage: Never store plain-text passwords
- Hashing: bcrypt with 10 salt rounds (application layer) or pgcrypto (database layer)
correo
correo
- Type: VARCHAR(50)
- Constraints: NOT NULL
- Description: User email address
- Usage: Used for password recovery and notifications
rol
rol
- Type: VARCHAR(20)
- Constraints: NOT NULL
- Description: User role for access control
- Values: “Administrador” or other role names
- Usage: Checked by authorization middleware
Sample Data
Views
Views provide formatted data with joined relationships and human-readable timestamps.ProductosView
Combines product data with category information and formats timestamps.server/config/bd.sql
View Benefits
Joined Data
Automatically includes category name, icon, and color with each product.
Formatted Dates
Timestamps split into separate date (DD/MM/YYYY) and time (HH24:MI:SS) fields.
Simplified Queries
Models can query the view instead of writing complex JOINs.
Consistent Formatting
Ensures consistent date/time formatting across the application.
Usage in Models
Fromserver/models/productos.model.js:
The view is read-only for SELECT queries. INSERT, UPDATE, and DELETE operations must target the base
Productos table.CategoriasView
Formats category timestamps for display.server/config/bd.sql
View Fields
- creado_fecha: Creation date in DD/MM/YYYY format
- creado_hora: Creation time in 24-hour format (HH24:MI:SS)
- actualizado_fecha: Last update date (NULL if never updated)
- actualizado_hora: Last update time (NULL if never updated)
UsuariosView
Provides user data WITHOUT the password hash for safe querying.server/config/bd.sql
Relationships
One-to-Many: Categorias → Productos
- Type: One-to-Many
- Description: Each category can have multiple products, but each product belongs to exactly one category
- Foreign Key:
Productos.idCategoriareferencesCategorias.id - Constraint:
REFERENCES Categorias(id) NOT NULL
Relationship Rules
Data Types
Common Types Used
SERIAL
SERIAL
- Description: Auto-incrementing integer
- Usage: Primary keys (id columns)
- Range: 1 to 2,147,483,647
- Behavior: Automatically increments on each INSERT
VARCHAR(n)
VARCHAR(n)
- Description: Variable-length string with maximum length
- Usage: Names, emails, short text fields
- Example: VARCHAR(50) allows up to 50 characters
- Storage: Only uses space for actual content + 1-2 bytes overhead
TEXT
TEXT
- Description: Variable-length string with no specific length limit
- Usage: Descriptions, passwords (hashed), long content
- Limit: Up to 1GB per value
- Performance: Slightly slower than VARCHAR for very short strings
DECIMAL(10, 2)
DECIMAL(10, 2)
- Description: Fixed-point decimal number
- Usage: Prices, monetary values
- Format: DECIMAL(precision, scale)
- Example: 999.99 (10 total digits, 2 after decimal)
- Advantage: Exact arithmetic (no floating-point errors)
INT / INTEGER
INT / INTEGER
- Description: 4-byte integer
- Range: -2,147,483,648 to 2,147,483,647
- Usage: Stock quantities, counts, foreign keys
TIMESTAMP
TIMESTAMP
- Description: Date and time (no timezone)
- Format: YYYY-MM-DD HH:MI:SS
- Usage: Created/updated timestamps
- Functions: CURRENT_TIMESTAMP, CURRENT_DATE
Constraints
Primary Keys
All tables use SERIAL primary keys:- Ensures unique identification for each record
- Auto-increments on INSERT
- Indexed automatically for fast lookups
Unique Constraints
Prevent duplicate values in specific columns:Categorias.nombre- Unique category namesProductos.nombre- Unique product namesUsuarios.nombre- Unique usernames
Foreign Key Constraints
Enforce referential integrity:- Ensures
idCategoriaexists inCategoriastable - Prevents orphaned records
- Blocks deletion of referenced categories
NOT NULL Constraints
Require values for critical fields:- All
id,nombre,creadofields are NOT NULL - Prices, stock, and category relationships are required
actualizadotimestamps allow NULL (not yet updated)
Default Values
Productos.stockdefaults to 0 if not specified- Ensures stock is never undefined
Common Queries
Get All Products with Category Info
Get Products by Category
Get Low Stock Products
Count Products per Category
Find Users by Role
Get Recently Added Products
Database Initialization
To set up the database, execute the SQL file:bd.sql file contains:
- Table creation statements
- pgcrypto extension installation
- View creation
- Sample data insertion (categories, products, admin user)
The script includes sample data for testing. Review and modify the INSERT statements before running in production.
Connection Configuration
Database connection is configured via environment variables:server/config/database.js
Environment Variables
.env
Best Practices
Use Views for Queries
Query views (ProductosView, etc.) instead of base tables for formatted data.
Modify Base Tables
INSERT, UPDATE, DELETE operations must target base tables, not views.
Parameterized Queries
Always use parameterized queries (2) to prevent SQL injection.
Index Foreign Keys
PostgreSQL automatically indexes PKs but consider indexing FKs for performance.
Hash Passwords
Never store plain-text passwords. Use bcrypt or pgcrypto.
Timestamp Updates
Set
actualizado = CURRENT_TIMESTAMP in UPDATE queries.Next Steps
Architecture
Learn how the database integrates with the application architecture
Authentication
Understand how user credentials and roles are managed
