Flat File Database: What It Is and When to Move Beyond One

Summary

  • A flat file database keeps all records in one plain file, such as a CSV, with no links, keys or indexes.
  • Flat files still fit data exchange, exports, archives, logs and small single-owner lists.
  • In our test on 1 million orders, a CSV lookup took about 1.5 seconds and SQLite about 0.03 milliseconds.
  • The CSV was smaller on disk, but it accepted a duplicate order ID that SQLite's primary key rejected
  • Move to a database when several people edit the data, rows get updated, or the file outgrows a spreadsheet.

The customer list lives in a CSV. So does last quarter’s order history, and the export somebody pulls from the CRM every Monday. It works until two people edit the same file, a report counts one order twice, or a single lookup takes longer than the meeting it was for.

A flat file database is the simplest way to keep records: one file, one row per record, no links between them. That simplicity is why it’s everywhere, and also why it breaks once the data grows or more people touch it.

We put a number on that by loading the same 1 million orders into CSV files and into SQLite on one laptop. Below you’ll find what a flat file database is, how it compares with a relational one, what our test showed, and a checklist for knowing when to move your data out of files.

What Is a Flat File Database?

A flat file database stores all its records in one plain text file, usually one record per line, with fields split by a delimiter such as a comma or a tab. Each line holds the same fields in the same columns, and there are no relationships between records: no linked tables, no indexes and no rules that stop bad data. Whatever reads the file has to know its layout.

The most common format is CSV. RFC 4180 documents it: each record sits on its own line, fields are separated by commas, and an optional first line holds the column names. Here’s a small orders file:

order_id,customer_email,customer_name,country,order_date,amount,status
1001,ana@example.com,Ana Lee,US,2026-09-02,120.00,paid
1002,ana@example.com,Ana Lee,US,2026-09-15,45.50,shipped
1003,raj@example.com,Raj Patel,UK,2026-09-20,300.00,pending

Notice that Ana’s name and country appear twice. A flat file can’t point one order at one customer record, so it repeats the customer on every order. That repetition is the root of most flat file problems. Microsoft’s guide to database normalization makes the same point: data that exists in more than one place must be changed in exactly the same way in all locations.

CSV isn’t the only format. Tab-separated files and JSON files with one object per line work the same way. Other everyday examples include a spreadsheet tab used as a customer list, a log file, an export from a CRM, and the Linux file /etc/passwd, which holds one line per user account with seven fields separated by colons.

Flat File Database vs Relational Database

AspectFlat file (CSV, spreadsheet)Relational database (SQLite, PostgreSQL, SQL Server)
StructureOne table in one fileSeveral tables linked by keys
Repeated dataThe same customer copied onto every orderStored once, referenced by ID
Duplicate IDsAccepted silentlyRejected by a primary key
Finding one recordRead the file from the topJump to it through an index
Changing one recordRewrite the whole fileUpdate the row in place
Several people editingLast save winsTransactions and locking
Access controlWhoever can open the file sees everythingServer databases add users, roles and permissions; SQLite relies on file access
Size on diskSmallerLarger, because of indexes
Tools neededA text editor or a spreadsheetA database engine and SQL
A flat file with repeated customer data next to relational Customers and Orders tables linked by customer ID

Most comparison tables stop there. We wanted to see what those rows mean in seconds, so we measured them.

We Tested It: 1 Million Orders as a CSV File and in SQLite

The setup. We generated 1,000,000 synthetic orders and 50,000 customers (random values, fixed seed, no real data). The same rows went into two CSV files and into one SQLite database with primary keys and an index on customer_id. Everything ran on one Windows 11 laptop with Python 3.14.7 and SQLite 3.50.4, standard library only. Each timing is the median of five runs (three for the update and the join).

TaskCSV fileSQLite
Size on disk37.1 MB orders + 1.2 MB customers49.4 MB for both tables and the index
Write all rows1.23 s1.43 s, keys and index included
Find one order by ID1.47 s0.03 ms
Find all orders of one customer (26 orders)1.40 s0.03 ms
Change one order’s status1.60 s0.1 ms
Add an order with an existing IDAccepted: two rows now share the IDRejected: “UNIQUE constraint failed”
Revenue by country (orders joined to customers)1.94 s0.53 s

The write times cover different operations: the CSV figure measures writing the orders file, while SQLite’s load includes both tables, primary keys and the customer index. They show the setup cost in this test, rather than a like-for-like comparison of writing identical files.

What the numbers say. Every lookup in the CSV meant reading the file from the top, so one order took about as long as one customer’s 26 orders: roughly a second and a half either way. SQLite answered both through its primary key and index in a fraction of a millisecond. Updating a single status was worse for the CSV, because a text file has no in-place update: the script read a million rows and wrote them all back to change one word.

The duplicate test is the one that bites in real life. The CSV accepted a second order with ID 999,993 without complaint, and any report built on it would count that order twice. SQLite refused it.

Where the CSV won. It was about a fifth smaller on disk and slightly faster to write, because there are no indexes to build. For a file you write once and read once, such as an export, those are real advantages.

Synthetic data on one laptop isn’t a benchmark of your system, so treat the ratios as the lesson rather than the exact times.

One detail about the join test: it ran after we tried adding a duplicate order. CSV accepted the extra row, while SQLite rejected it, so the two datasets differed by one order at that point.

Where Flat Files Still Make Sense

Flat files aren’t going anywhere, and they shouldn’t. They fit jobs where data is written in one place and read in another, or appended and rarely changed, or kept by one person.

  • Moving data between systems. CSV is a format most apps, databases and spreadsheets can read and write, which is why exports and imports run on it. Bakewell Cookshop is one example. The retailer uses CSV files stored in Dropbox to transfer inventory updates into BigCommerce. Skyvia picks up the files and imports the data automatically every hour, removing the need for manual uploads. The customer case study shows how CSV can remain useful as an exchange format without becoming the system where the data is managed.
  • Exports, snapshots and archives. A dated CSV of last month’s orders is easy to keep and opens in any spreadsheet.
  • Configuration and logs. Files like /etc/passwd and application logs are flat by design.
  • Small, single-owner lists. A few hundred rows that one person maintains don’t need a database server.
  • Staging before a load. Many pipelines land data as files first and load them into a database or warehouse after.

Flat files and relational databases also work well together: the file carries the data in, the database stores and serves it. The trouble starts when a flat file becomes the system of record: the one place the business trusts for current data that several people change.

When to Move Beyond a Flat File: A Checklist

SignalWhat it meansWhat to do
The data no longer fits a spreadsheetExcel stops at 1,048,576 rows per worksheet; Google Sheets at 20 million cellsMove it to a database before rows get cut off
More than one person edits itSaves overwrite each otherUse a database with transactions
You change existing rows, not just add new onesEvery change rewrites the fileUse a table you can update in place
The same entity repeats on many rowsCustomer, product or account data drifts out of syncSplit it into related tables
Duplicate IDs would break a reportNothing in the file stops themAdd a primary key
Lookups take secondsEvery search reads the whole fileAdd an index
Reports combine several filesJoins happen in scripts or formulasQuery with SQL, or load into a warehouse

Two or more of these signals usually mean the flat file has become a liability.

What to Move To

The next step doesn’t have to be a big one.

  • An embedded database such as SQLite for one application or one analyst. SQLite’s own documentation says it doesn’t compete with client/server databases at all: it “competes with fopen()”. It’s still a single file, but with keys, indexes and SQL.
  • A server database (PostgreSQL, MySQL, SQL Server) when several people or applications read and write the same data at once.
  • A data warehouse (BigQuery, Snowflake, Redshift) when the goal is reporting across sources, such as CRM, billing and marketing data together.

How to Move a Flat File Into a Database

  1. Clean the header row. One name per column, no spaces or special characters, no merged cells if the file came from a spreadsheet.
  2. Decide the types and the keys. Which column is unique (order_id), which ones are dates and amounts, which repeating group becomes its own table (customers).
  3. Create a staging table and load the file into it as it is. Make a table that mirrors the file’s columns (orders_flat below) and load every row, so nothing is lost before you split it. In SQL Server’s Import and Export Wizard, for example, you set each column’s type before the load.
SQL Server Import and Export Wizard showing Advanced column settings with the id field assigned an integer data type
  1. Split the staging table into related tables.

This SQL splits the orders file above into two related tables after it has been loaded as orders_flat. We ran it on the three sample rows: it created two customers and three orders, and when we then tried to insert order 1002 a second time, the primary key rejected it.

CREATE TABLE customers (
  customer_id INTEGER PRIMARY KEY,
  email       TEXT NOT NULL UNIQUE,
  name        TEXT,
  country     TEXT
);

CREATE TABLE orders (
  order_id    INTEGER PRIMARY KEY,
  customer_id INTEGER NOT NULL REFERENCES customers(customer_id),
  order_date  TEXT NOT NULL,
  amount      REAL NOT NULL,
  status      TEXT NOT NULL
);

INSERT INTO customers (email, name, country)
SELECT DISTINCT customer_email, customer_name, country FROM orders_flat;

INSERT INTO orders (order_id, customer_id, order_date, amount, status)
SELECT f.order_id, c.customer_id, f.order_date, f.amount, f.status
FROM orders_flat AS f JOIN customers AS c ON c.email = f.customer_email;

If the same email appears with two spellings of a name, the insert into customers fails on the UNIQUE constraint on email. That failure is useful: it shows the inconsistency the flat file was hiding.

  1. Check the counts. Rows in, rows out, and the duplicates the keys rejected.

When the File Keeps Arriving: the Same Load in Skyvia Import

For a one-off move, a database’s own import tool is enough; see our guides to importing CSV into MySQL, PostgreSQL and SQL Server. When the CSV keeps arriving every day or week, Skyvia Import can pick it up from your computer or from storage such as SFTP, Amazon S3, Google Drive or SharePoint, match files by a date-based mask, and insert, update, upsert or delete records in the target database on a schedule.

  1. Create an Import integration. As the source type, choose “CSV from storage service” (or “CSV upload manually” for a file on your computer), then pick the storage connection and the target database connection.
Skyvia Import integration showing a CSV file from Google Drive mapped to a SQL Server database table
  1. Add a task and pick the file. Choose the file in the storage folder, or set a date-based mask such as Contact_{yyyyMMdd}.csv so that each run takes that day’s file (masks need the Standard plan or higher). Click “Check file and load columns”, check the column types Skyvia detected, and choose orders_flat as the target table.
Skyvia Import configuration showing a date-based CSV file mask, source folder, and timezone settings
  1. Run it and check the counts. The Monitor tab lists the last five runs with Success rows and Error rows for each table. Click an error count to download a CSV with every rejected record and the reason it failed; older runs are on the Log tab.
  2. Schedule it. Click Schedule, choose Recurring and set how often it runs.
Skyvia Import schedule set to a recurring daily run at a fixed time in the chosen time zone

Note: you can start on the Free plan, and signing up needs no credit card.

FAQ for Flat File Databases

Loader image

In SQL work, a flat file usually means a CSV or other delimited text file that you import into a table or export from one. The file has no keys or indexes of its own, so the database adds them once the data is loaded. 

A CSV export of orders is the classic one: one order per line, fields separated by commas, a header row with column names. The Linux file /etc/passwd is another, with one line per user account and seven fields separated by colons. 

A single worksheet used as a list behaves like one: one table, rows of records, no enforced keys. Excel also has a hard ceiling of 1,048,576 rows per worksheet, which is one of the signals that data has outgrown it. 

A CSV file stores data, but it isn’t a database engine. It can’t index records, reject duplicate IDs or let several people update it safely. In our test, a CSV accepted a duplicate order ID that SQLite rejected. 

There’s no fixed threshold. Every search reads the file from the top, so search time grows with file size. With 1 million orders, finding one order took about 1.5 seconds in our CSV test and 0.03 milliseconds in SQLite. 

Ready to stop rewriting CSV files by hand? Sign up for Skyvia free and set up a scheduled import that loads each new file into a database table whose keys catch duplicates. 

Share

Nata Kuznetsova

Nata Kuznetsova is a seasoned writer with nearly two decades of experience in technical documentation and user support. With a strong background in IT, she offers valuable insights into data integration, backup solutions, software, and technology trends.

One platform for all your data work

One platform for all your data work

Integration, automation, live data access, and backup. No code, 200+ connectors.

Start free