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.mdfull_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:
renamecreationsplitmergetransfer
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.