Soroush Neyestani

Application Developer

Software Developer

Data Scientist

Project Manager

Senior Project Manager

IT Administrator

Fullstack Developer

Android Developer

iOS Developer

Iran National Divisions

Iran National Divisions

A versioned, relational and temporal dataset for Iran's administrative and statistical divisions

Originally developed: 2021
Re-engineered: 2026
Current version: v2.0.0
Category: Data Engineering / Database Design / Open Data
Data formats: CSV, JSON, SQLite, MySQL, PostgreSQL


Project Overview

Iran National Divisions is a structured dataset and database model representing the administrative and statistical hierarchy of Iran.

I originally developed the project in 2021 to solve a practical problem: administrative location data was available in raw form, but using it reliably inside software applications required much more than simply having a list of provinces and cities.

Applications frequently need to answer questions such as:

  • Which province does a county belong to?
  • Which district belongs to a specific county?
  • Which rural district contains a particular village?
  • What is the official statistical identifier of a location?
  • How can locations be referenced consistently across different applications?
  • How should historical administrative changes be represented without destroying previous data?

The original project transformed the available raw information into a relational structure that could be directly consumed by software systems.

In 2026, approximately five years after the original implementation, I returned to the project and re-engineered it as a significantly more robust data platform.

The goal was not to replace the 2021 dataset.

The goal was to preserve it completely while building a cleaner, validated, versioned and historically aware architecture around it.


The Data Model

Iran's administrative structure cannot be accurately represented by a simple province → city relationship.

The hierarchy extends through several administrative and statistical levels.

Conceptually, the dataset represents structures such as:

Country → Province → County → District → Rural District → City / Village / Settlement / Statistical Place

Each entity can therefore be connected to its administrative parent while retaining its own identity and statistical metadata.

This makes hierarchical traversal possible without relying on duplicated textual location names.

Instead of treating geographic names as independent strings, the project models them as structured entities with explicit relationships.


Why This Matters

A flat location table may be sufficient for a dropdown menu.

It becomes insufficient when the same dataset is used for:

  • enterprise applications
  • customer databases
  • address systems
  • logistics
  • statistical analysis
  • reporting
  • geographic filtering
  • historical datasets
  • data integration
  • administrative research

Once a dataset becomes part of multiple systems, several additional requirements appear:

Referential integrity

A district should not reference a county that does not exist.

Stable identifiers

Applications should not depend exclusively on names that may change.

Historical preservation

A renamed or transferred location should not cause historical records to become incorrect.

Normalization

Different Unicode representations of the same Persian character should not silently create different values.

Portability

The dataset should not be tied to one specific database engine.

These requirements became central to the 2026 redesign.


Official Statistical Codes

One of the important properties preserved by the project is the official statistical code associated with individual locations.

For example:

0916050002166247

This value should not be treated as an arbitrary application-generated primary key.

The code contains structured information associated with different levels of the statistical and administrative hierarchy.

This distinction is important.

A database can generate its own internal primary keys for relational integrity, while the original statistical identifier remains preserved as domain data.

Separating these two concepts makes the database architecture more flexible without losing the semantics of the source dataset.


The Original 2021 Version

The first version of Iran National Divisions was intentionally simple.

The repository primarily contained:

  • README.md
  • full_state.sql

The SQL dataset already represented a significant amount of structured information and contained more than 108,000 legacy rows.

Among them were:

104,120 statistical records

Despite the simplicity of the repository, one thing became particularly interesting when I revisited the project five years later:

Much of the original relational thinking was still valid.

The hierarchy itself did not require a complete conceptual replacement.

What needed improvement was everything around it:

  • data preservation
  • normalization
  • integrity constraints
  • validation
  • versioning
  • historical modeling
  • portability
  • automated testing

That observation influenced the entire modernization strategy.


Re-engineering Strategy

The most important rule of the 2026 modernization was:

Never destroy the original dataset in order to make the new dataset cleaner.

Instead of overwriting the original information, the architecture separates historical source data from its normalized representation.

This provides two distinct layers.

Raw Dataset

The raw layer preserves the original 2021 information as faithfully as possible.

Its purpose is provenance and reproducibility.

If normalization rules change in the future, the canonical dataset can be regenerated without losing the original source representation.

Canonical Dataset

The canonical layer provides the normalized and application-friendly representation.

This is where transformations, normalized naming conventions, relational constraints and additional validation can be applied.

The result is a system where modernization does not require sacrificing historical fidelity.


Persian Unicode Normalization

Persian datasets frequently contain characters that appear visually identical but have different Unicode code points.

Two common examples are:

ي → ی

and

ك → ک

The first characters are commonly introduced through Arabic keyboard layouts or historical source systems, while the second forms are the expected Persian characters.

Visually, these differences can be extremely difficult to notice.

Computationally, however, they matter.

Without normalization they can affect:

  • equality comparisons
  • search
  • indexing
  • unique constraints
  • joins
  • grouping
  • duplicate detection
  • API results

The modernized project therefore performs explicit Persian text normalization while retaining the original raw representation separately.

This provides consistent application behavior without modifying the historical source dataset.


Referential Integrity

The original data was transformed into a more strictly validated relational model.

The modern version introduces explicit relationships and database-level constraints where appropriate.

Foreign keys help guarantee that hierarchical relationships remain valid.

For example, the system can enforce that:

  • a county references an existing province
  • a district references an existing county
  • a rural district references an existing district
  • child entities cannot silently reference nonexistent parents

This moves important integrity rules from application assumptions into enforceable data constraints.


Dataset Versioning

Administrative datasets are not static.

Borders change.

Names change.

New administrative entities are created.

Existing entities may be divided, merged or transferred.

Therefore, treating one database snapshot as the permanent representation of reality creates a long-term modeling problem.

The 2026 architecture introduces explicit dataset versioning.

Instead of assuming that one dataset represents all time periods, different published states of the administrative structure can coexist.

Conceptually:

Dataset 2021

Dataset 2026

Dataset Future-N

This allows applications and analyses to identify exactly which administrative dataset they are using.

It also creates the foundation for reproducible historical queries.


Temporal Administrative Model

Versioning solves the snapshot problem, but it does not fully describe why a location changed.

For that reason, the redesign also introduces a temporal model for administrative events.

The model can represent events such as:

  • rename
  • creation
  • split
  • merge
  • transfer

This distinction is important.

Consider a village whose name changes.

Deleting the old record and inserting a new one loses continuity.

Similarly, if an administrative entity moves from one parent jurisdiction to another, overwriting the parent relationship destroys historical information.

A temporal model allows the system to preserve both states and explicitly describe the transition between them.

This turns the dataset from a static location directory into a foundation for historically aware administrative data.


Data Preservation

One of the strongest requirements of the modernization was backward preservation.

The original 2021 dataset was treated as immutable source material.

The modernization process therefore follows a simple principle:

Normalize by addition, not by destruction.

The project preserves:

108,408 legacy rows

while maintaining:

104,120 statistical records

in the structured dataset.

No original information needs to disappear simply because the modern architecture represents it differently.


Validation and Automated Testing

Data modernization without validation can easily produce a cleaner-looking but less trustworthy dataset.

For that reason, automated validation became part of the project itself.

The current release passes:

31 / 31 automated tests

The tests are designed to verify important invariants around the dataset and transformation process.

Depending on the validation layer, these include areas such as:

  • expected record preservation
  • hierarchy consistency
  • transformation correctness
  • normalization behavior
  • schema integrity
  • parent-child relationships
  • export consistency
  • regression protection

The purpose of these tests is not simply to test code.

They establish confidence that modernization has not silently damaged the historical dataset.


Multi-Database Support

The modern version is designed to avoid unnecessary dependence on a single database engine.

The project supports several representations:

  • CSV
  • JSON
  • SQLite
  • MySQL
  • PostgreSQL

Each serves a different use case.

CSV

Useful for interoperability, analysis and simple data exchange.

JSON

Useful for APIs, application integration and hierarchical data consumption.

SQLite

Useful for embedded applications, local tools, prototypes and environments where running a database server would be unnecessary.

MySQL

Suitable for traditional web applications and existing application infrastructures.

PostgreSQL

Suitable for applications requiring a robust relational platform and more advanced database capabilities.

Providing multiple representations makes the dataset usable independently of the technology stack consuming it.


Architecture Principles

The 2026 redesign follows several principles that were not explicit requirements of the original 2021 repository.

Preserve Source Truth

Raw historical information should remain available even after normalization.

Separate Identity from Presentation

Names can change.

Stable identifiers and relationships should not depend exclusively on display names.

Enforce Integrity

Relationships that can be guaranteed by the database should not exist merely as undocumented assumptions.

Make Transformations Reproducible

Canonical data should be derivable through defined transformation rules rather than manual modification.

Model Time Explicitly

Administrative geography changes over time, so history should be represented rather than overwritten.

Remain Portable

The usefulness of the dataset should not depend on one programming language or database engine.

Test the Data

Data integrity deserves automated regression testing just as application logic does.


2021 vs. 2026

The difference between the two versions is therefore not simply that the new repository contains more files or supports more databases.

The fundamental change is architectural.

2021

The primary objective was:

Transform raw administrative data into a usable relational dataset.

2026

The objective became:

Preserve the original dataset while making its structure normalized, validated, versioned, portable, testable and historically aware.

That distinction represents the main engineering evolution of the project.


Key Metrics

Metric Value
Original implementation 2021
Re-engineered version 2026
Current release v2.0.0
Legacy rows preserved 108,408
Statistical records 104,120
Automated tests 31 / 31 passed
Raw dataset preservation 100%
Supported representations CSV, JSON, SQLite, MySQL, PostgreSQL

Technical Highlights

  • Hierarchical administrative data modeling
  • Relational database architecture
  • Raw and canonical dataset separation
  • Persian Unicode normalization
  • Official statistical code preservation
  • Referential integrity through explicit relationships
  • Dataset versioning
  • Temporal administrative-event modeling
  • Historical data preservation
  • Automated regression and integrity testing
  • Multi-database support
  • Portable data exports

Engineering Challenges

The technically interesting part of this project was not importing more than one hundred thousand records into a database.

That is relatively straightforward.

The real challenge was deciding how to modernize a historical dataset without rewriting its history.

Cleaning data is easy if the original values can simply be replaced.

It becomes a different engineering problem when the requirements are:

  • preserve the original source
  • normalize the usable representation
  • maintain stable identity
  • enforce hierarchical integrity
  • support multiple snapshots
  • describe changes over time
  • prevent regressions
  • remain portable across database technologies

Those constraints shaped the architecture much more than the raw number of records.


What I Learned Rebuilding It

Returning to software several years after writing it provides a useful perspective that is difficult to obtain during initial development.

Some decisions that once seemed reasonable become obvious technical debt.

Others survive surprisingly well.

In this project, the fundamental relational hierarchy designed in 2021 remained largely defensible.

What changed substantially was my approach to the lifecycle of the data around that model.

The 2026 version treats provenance, normalization, integrity, versioning, temporal changes and automated verification as first-class architectural concerns.

For me, that is the most valuable part of revisiting this project.

It is not simply a comparison between older and newer technologies.

It is a comparison between two stages of engineering thinking.


Result

Iran National Divisions v2.0.0 is no longer simply an SQL file containing administrative locations.

It is a versioned and validated data architecture designed to preserve the original dataset while providing a cleaner foundation for modern applications.

The original 2021 data remains intact.

The modern representation can evolve independently.

Administrative changes can be modeled rather than overwritten.

Multiple database ecosystems can consume the data.

And automated tests provide protection against regressions during future development.

Originally built in 2021. Re-engineered in 2026.

The raw data was not discarded. The architecture around it evolved.