Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
17 Sep 2025 · 5 min read ·Article 79 / 125
Go

79 Schema Optimization and Modularization Techniques

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

79 Schema Optimization and Modularization Techniques: A Practical Guide for Modern Engineers

In today’s era of complex software systems, two fundamental aspects often overlooked during initial design are data schema optimization and code modularization. Yet both have a direct impact on application performance, scalability, and maintainability. In this article, I have compiled 79 practical schema optimization and modularization techniques that you can apply right away, complete with code examples, simulations, tables, and Mermaid flow diagrams to illustrate the key concepts.


Why Are Schema Optimization and Modularization Important?

1. Optimal Data Schema

Schema optimization speeds up queries, reduces storage, and minimizes data redundancy. For example, a poorly optimized database schema can lead to slow queries, inconsistent data, and difficult scaling.

2. Modularization

Modularization organizes code by its function, making it easier to develop, test, and maintain. With good modularization, a system becomes extensible and robust.


Data Schema Optimization Techniques (1–40)

Table 1. Summary of Schema Optimization Techniques

NoTechniqueBrief Explanation
1Normalization up to 3NFMinimize redundancy
2Indexing on search columnsSpeed up SELECT operations
3Limited denormalizationFor reporting queries
4Table partitioningSplitting tables by range
5Proper data typesChoose the optimal data type
40Schema documentationEase onboarding/maintenance

Techniques 6–39 can be found in this article’s appendix (or downloaded from the author’s GitHub repo). Below are several key techniques along with implementation examples:

1. Normalization

For example, a users table with a redundant structure:

sql
1CREATE TABLE users (
2    id SERIAL PRIMARY KEY,
3    name VARCHAR(50),
4    city VARCHAR(100),
5    province VARCHAR(100)
6    -- city and province are frequently duplicated
7);
Solution: Normalize into two separate tables:
sql
 1CREATE TABLE provinces (
 2    id SERIAL PRIMARY KEY,
 3    name VARCHAR(100)
 4);
 5
 6CREATE TABLE cities (
 7    id SERIAL PRIMARY KEY,
 8    name VARCHAR(100),
 9    province_id INT REFERENCES provinces(id)
10);
11
12CREATE TABLE users (
13    id SERIAL PRIMARY KEY,
14    name VARCHAR(50),
15    city_id INT REFERENCES cities(id)
16);

2. Indexing

Add an index on columns that are frequently used for searching/sorting.

sql
1CREATE INDEX idx_users_city_id ON users(city_id);

3. Use Enumerations or Lookup Tables

sql
1CREATE TABLE user_status (
2    id INT PRIMARY KEY,
3    status VARCHAR(20)
4);
5
6-- Then use it in the main table
7ALTER TABLE users
8ADD COLUMN status_id INT REFERENCES user_status(id);

4. Limiting Data Length

Use data types according to your needs, for example VARCHAR(15) for a phone number.

5. System Denormalization (Read-heavy Table)

For analytics or reporting cases, you can store a summary of join results so that queries run faster.

6. Optimizing Foreign Key Constraints

To prevent insert performance from slowing down, indexing the foreign key columns is highly recommended.

sql
1CREATE INDEX idx_foreign_key ON child_table(parent_id);

7. Partitioning Tables by Range or List

sql
1CREATE TABLE sales_2024 PARTITION OF sales
2    FOR VALUES FROM ('2024-01-01') TO ('2024-12-31');

8. Gradual Schema Migration (Zero-Downtime Migration)

Implement schema migration using a feature flag or a shadow table.


Modularization Techniques (41–79)

Table 2. Summary of Modularization Techniques

NoTechniqueBenefit
41Single Responsibility PrincipleOne module = one responsibility
42Dependency InjectionEasy to test/unit test
43Separating domain & infra layerOrganized codebase
44Hierarchical module structureMore maintainable structure
79Consistent namingEasy for the team to read & understand

1. Applying the Single Responsibility Principle (SRP)

For example: In a payment service, don’t combine validation logic with third-party API integration.

python
1# payment_validation.py
2def validate_payment_data(data):
3    # validate payment data
4    ...
5
6# payment_gateway.py
7def charge_credit_card(data):
8    # interact with the payment gateway
9    ...

2. Dependency Injection

So that a module can be tested independently without relying on the real implementation.

python
1class OrderService:
2    def __init__(self, payment_gateway):
3        self.payment_gateway = payment_gateway
4    def process_order(self, order):
5        return self.payment_gateway.charge(order)

3. Domain Layer vs Infrastructure Layer (Clean Architecture)

Separate domain (business) objects from infrastructure adapters.

plaintext
1/domain
2    /order.py  # business logic
3/infrastructure
4    /payment_gateway_api.py
5/app.py   # glue

4. Modularization Flow Diagram with Mermaid

MERMAID
graph TD
    A[User Request] --> B[Controller]
    B --> C[Domain Service]
    C --> D[Repository/Infra Adapter]
    D --> E[Database/API]

5. Feature-based Modularization

For large-scale applications, use a folder per feature:

plaintext
1/app
2    /user
3        routes.py
4        services.py
5        models.py
6    /orders
7    /products

6. Isolating Side Effects

Wrap IO operations in their own module so that the core logic stays pure.

python
1# core.py
2def calculate_invoice(amount, tax):
3    return amount + (amount * tax)
4
5# io_layer.py
6def save_invoice_to_db(invoice):
7    ...

Simulation: The Impact of Modularization on Codebase Scale

For example, without modularization:

  • A single file containing 2,000+ lines of code
  • Business functions calling one another with no clear pattern

After modularization:

  • Each module/function is < 300 lines
  • An organized folder structure, making onboarding new engineers much faster

Best Practices and Antipatterns to Avoid

Do:

  • Separate domain logic from infrastructure.
  • Choose schema techniques according to your needs (normalization vs denormalization).
  • Refactor for modularization regularly, not only during emergencies.

Don’t:

  • “God Object”: A single module doing everything.
  • Hard-coded dependencies: Hard to test/mock.
  • Arbitrarily duplicating tables for “optimization”: The result is actually inconsistent data.

Conclusion

Schema optimization and modularization are not merely a matter of codesmithing style; they are the engine behind your application’s performance and resilience in meeting long-term requirements. Applying the 79 techniques I have compiled above can speed up queries, ease scaling, and cut down future technical debt.

Check out the supporting repository on GitHub for details on all 79 techniques, along with a checklist and implementation templates.

Let’s start schema optimization and modularization today. Solid code and architecture are your best investment!

Related Articles

💬 Comments