Master these terms & you can read the architecture of almost any serious data –  including the kind that turns a messy pile of citations into a verified, trustworthy bibliography.

INGOAMPT · Learn

SQLite, Transactions & Record Matching: A Developer’s Vocabulary Guide

Two questions sit underneath almost every serious data application: “how do I store millions of records without ever losing or corrupting one, even if the power cuts out?” and “how do I match a messy, typo-filled record against the right one out of millions?” This guide answers both, term by term, with figures, tables and real code — for complete beginners.

The running example. Picture a service where someone uploads a messy, typo-filled list of book and article references — like a student’s badly-formatted bibliography — and the system must find the correct, verified record for each one from a library of millions, flag anything it isn’t sure about, and never simply invent an answer. That’s the example we’ll use throughout.

Part 1 · Storing Data So It Survives Anything

Before you can match anything, you need a database that never quietly loses or corrupts a record — not even if someone trips over the power cable mid-write. These twelve terms are how that promise is kept.

1. SQLite

The database in one file
Plain English: SQLite is a full relational database that lives inside a single ordinary file on disk — no separate server, no installation, no login. Your program just opens the file.

Big databases like PostgreSQL or MySQL run as a separate background program that your app talks to over a network connection, even if that network is just localhost. SQLite skips all of that: the database is the file.

PostgreSQL / MySQLSQLite
Where it runsa separate server processinside your own program
Setupinstall, configure, start a servicenone — it’s just a file
Storagemanaged data directoryone file, e.g. catalog.sqlite3
Best formany simultaneous app serversone machine, local-first apps, research pipelines
<span class="c"># That's really it — no server to start</span>
<span class="k">import</span> sqlite3
conn = sqlite3.connect(<span class="k">"catalog.sqlite3"</span>)
conn.execute(<span class="k">"SELECT COUNT(*) FROM records"</span>)
Remember it as: SQLite = a database you can email as an attachment. Perfect for research projects, desktop apps, and one-machine data pipelines.

2. Schema, Table, Row & Column

The vocabulary of structure
Plain English: A schema is the floor plan of a database. A table is one labeled shelf on that floor plan — like a spreadsheet with strict rules. A row is one item on the shelf. A column is one property every item must have.

Picture our reference-matching database. One table, records, might look like this once populated:

record_id ↓ (column)title (column)year (column)doi (column)
1Attention Is All You Need201710.5555/…
2Deep Learning201510.1038/…

↑ Each horizontal line is a row. Each vertical field is a column. The whole table’s shape (which columns exist, what type each holds) is defined by the schema.

<span class="c">-- The schema: the rules for this one table</span>
<span class="k">CREATE TABLE</span> records (
    record_id INTEGER <span class="k">PRIMARY KEY</span>,
    title     TEXT    <span class="k">NOT NULL</span>,
    year      INTEGER,
    doi       TEXT
);
Remember it as: schema = floor plan · table = shelf · row = one item · column = one property every item shares.

3. Primary Key & Foreign Key

Identity and connection
Plain English: A primary key is a value that uniquely names one row — no two rows may share it. A foreign key is a rule that says “this value must point to a row that actually exists in another table.”

Say each reference can have several authors. You’d naturally split that into two tables — one row per reference, one row per author-of-a-reference:

records record_id 🔑 (primary key) 1 — Attention Is All You Need 2 — Deep Learning authors author_id 🔑 record_id 🔗 (foreign key) 1, record_id=1, “Vaswani” 2, record_id=1, “Shazeer” 3, record_id=2, “LeCun” A foreign key that points to record_id = 999 is REJECTED — no such record exists.
Fig. 1 — The primary key names a row; the foreign key guarantees every reference to it is real.
<span class="k">CREATE TABLE</span> authors (
    author_id INTEGER <span class="k">PRIMARY KEY</span>,
    record_id INTEGER <span class="k">NOT NULL</span>,
    name      TEXT,
    <span class="k">FOREIGN KEY</span> (record_id) <span class="k">REFERENCES</span> records(record_id)
);
Remember it as: primary key = a row’s unique name tag; foreign key = a promise that a pointer leads somewhere real.

4. Transactions, Commit & Rollback

Grouping writes safely
Plain English: A transaction bundles several database writes into one all-or-nothing group. Commit means “save the whole group permanently.” Rollback means “undo the whole group as if it never started.”

Storing one reference actually means writing to several tables — the record itself, its authors, its identifiers. If you save them one at a time and the program crashes halfway, you get a broken half-record. A transaction prevents that:

<span class="k">BEGIN</span>;                                   <span class="c">-- open the transaction</span>
  <span class="k">INSERT INTO</span> records VALUES (3, <span class="k">'BERT: Pre-training...'</span>, 2018, <span class="k">NULL</span>);
  <span class="k">INSERT INTO</span> authors VALUES (4, 3, <span class="k">'Devlin'</span>);
  <span class="k">INSERT INTO</span> authors VALUES (5, 3, <span class="k">'Chang'</span>);
<span class="k">COMMIT</span>;                                  <span class="c">-- ✅ all 3 writes saved together</span>

<span class="c">-- If something fails before COMMIT:</span>
<span class="k">ROLLBACK</span>;                                <span class="c">-- ❌ all 3 writes are undone, none remain</span>
✅ succeeds → COMMIT insert record insert author 1 insert author 2 COMMIT → all 3 saved ❌ fails → ROLLBACK insert record insert author 1 💥 insert author 2 fails ROLLBACK → 0 rows remain
Fig. 2 — Either the whole group lands, or none of it does. No broken half-records, ever.
Remember it as: transaction = a group hug for related writes. Commit = keep them all. Rollback = as if none of it happened.

5. Atomicity

All or nothing, guaranteed
Plain English: Atomicity is the guarantee behind commit/rollback: an operation either completes entirely, or leaves no trace at all. There is no in-between state where it “half happened.”

It’s the first letter of the classic ACID guarantees every serious database offers:

LetterGuaranteeIn one sentence
Atomicityall-or-nothingA transaction never leaves a partial result.
Consistencyvalid state → valid stateRules (like foreign keys) are never violated.
Isolationtransactions don’t see each other’s messTwo writers never step on each other mid-write.
Durabilityonce committed, it survivesA crash right after commit doesn’t undo it.

Atomicity, Consistency, and Isolation hold true in SQLite under essentially every setting. As you’ll see in section 9, the Durability guarantee is the one knob you can deliberately loosen for speed.

Remember it as: atomicity = no such thing as “partly done.” Either the transaction fully happened, or it fully didn’t.

6. PRAGMA

Talking to the database engine itself
Plain English: A PRAGMA is a special SQLite command that reads or changes the database engine’s own behavior — not your data, but the rules the engine follows while handling your data.

Normal SQL (SELECT, INSERT) works with your rows. A PRAGMA works with the engine’s settings:

<span class="k">PRAGMA</span> foreign_keys = <span class="k">ON</span>;       <span class="c">-- turn on foreign-key enforcement</span>
<span class="k">PRAGMA</span> journal_mode;             <span class="c">-- ask: "what journal mode is actually active?"</span>
<span class="k">PRAGMA</span> integrity_check;          <span class="c">-- ask: "is this database file healthy?"</span>
<span class="k">PRAGMA</span> busy_timeout = 5000;      <span class="c">-- wait up to 5000ms if the database is locked</span>

Two of these — journal_mode and synchronous — control how safely and how fast your data survives a crash. They’re the subject of the next three sections.

Remember it as: PRAGMA = the control panel behind the database, separate from the data itself.

7. Journal & Journal Modes

How SQLite survives a crash mid-write
Plain English: A journal is scratch information SQLite keeps on the side so that if the program is interrupted mid-write, it can figure out how to recover a clean, uncorrupted database. Journal mode is which strategy it uses to keep that scratch information.

Three common modes, each a different strategy for the same goal:

ModeStrategyRecovery approach
DELETE (the default)Before changing a page, copy the old version into a side file (-journal). Delete that file when the transaction commits.Undo: on crash, replay the saved old pages to undo the incomplete write.
TRUNCATESame idea as DELETE, but instead of deleting the journal file, it’s shrunk to zero length — faster on some filesystems.Same undo approach as DELETE.
WALInstead of saving old pages, new committed pages are appended to a separate -wal file.Redo: on crash, replay committed WAL entries forward.
DELETE / TRUNCATE — save OLD, undo on crash main database file -journal file(the OLD page, saved just in case) Crash? → copy the saved old page back → undone WAL — append NEW, redo on crash main database file -wal file(NEW committed pages, appended) Crash? → replay committed WAL entries forward
Fig. 3 — Two different philosophies for the same goal: never leave the database in a broken state.
<span class="k">PRAGMA</span> journal_mode = <span class="k">WAL</span>;
<span class="c">-- SQLite may not grant exactly what you asked — always check what it actually gave you:</span>
<span class="k">PRAGMA</span> journal_mode;   <span class="c">-- → "wal"  ✅ confirmed</span>
Remember it as: DELETE/TRUNCATE = “save the old, undo if needed.” WAL = “append the new, redo if needed.”

8. WAL Mode (Write-Ahead Logging)

Why modern apps prefer it
Plain English: WAL mode lets people read the database at the same time someone else is writing to it, without either one blocking the other. It’s the setting almost every modern SQLite-based app turns on.

In the default DELETE mode, a writer briefly locks out all readers. Under WAL, readers see a consistent snapshot built from the main file plus the WAL’s committed entries, while a writer keeps appending in the background:

DELETE / TRUNCATE (default)WAL
Readers vs. writerwriter blocks readersreaders never block the writer, and vice versa
Concurrent writersone at a timestill one at a time (WAL doesn’t change this)
Extra filestemporary -journal during writespersistent -wal and -shm files
Network filesystemsworks❌ not supported (needs shared memory on one host)
Typical usesimple scripts, single-writer batch jobsweb apps, concurrent readers, ingestion pipelines

WAL entries eventually get folded back into the main file — a process called a checkpoint (covered in section 11). Unlike other modes, WAL is “sticky”: once set, it stays active even after you close and reopen the database.

Remember it as: WAL = readers and the writer stop stepping on each other’s toes. The go-to mode for anything with concurrent access.

9. Synchronous & the Durability Trade-off

Speed vs. surviving a power loss
Plain English: synchronous controls how often SQLite pauses to make absolutely sure your data has physically reached the disk (not just the operating system’s cache) before saying “done.” More pausing = safer but slower.

Here’s the layered reality most beginners miss: a “saved” write can actually be sitting at three different depths.

1. Your app“write done” 2. OS page cachesurvives app crash 3. Physical disksurvives POWER LOSS fsync() is the call that forces data from layer 2 down to layer 3. `synchronous` decides how often it’s called.
Fig. 4 — Only reaching layer 3 (the physical disk) survives a real power loss, not just an app crash.
LevelBehaviorSurvives app crash?Survives power loss?
OFFnever forces disk sync✅ yes❌ no — can corrupt
NORMALsyncs at key moments (default in WAL mode)✅ yes⚠️ last transaction(s) may roll back — but never corrupts
FULLsyncs on every commit✅ yes✅ yes
EXTRAFULL, plus an extra sync in DELETE mode✅ yes✅ yes (strongest)
The honest trade-off, in plain words: With WAL + synchronous=NORMAL — the combination most production apps use — killing your program, or even the whole operating system, is fine: no committed data is lost, and the file is never corrupted. Only an actual power failure at the exact wrong instant can roll back the very last committed transaction. For that reason, WAL + NORMAL is a widely recommended default (used by frameworks like Django’s SQLite backend), reserving FULL for cases where losing even the last transaction on power loss is unacceptable.
Remember it as: OFF = fastest, riskiest · NORMAL = fast, safe against crashes, tiny risk on power loss · FULL/EXTRA = slowest, safest against everything.

10. Busy Timeout

What happens when the database is briefly locked
Plain English: Only one writer can touch an SQLite database at a time. Busy timeout tells SQLite how long a second writer should politely wait its turn before giving up with an error.
<span class="k">PRAGMA</span> busy_timeout = 5000;   <span class="c">-- wait up to 5 seconds for the lock to clear</span>
<span class="c">-- Without this, a second writer fails INSTANTLY with "database is locked"</span>

Picture two parts of your program both wanting to write at nearly the same moment. Without a busy timeout, the second one crashes immediately. With a reasonable timeout, it simply waits — usually a fraction of a second — and then proceeds normally.

Remember it as: busy timeout = “please hold” instead of “connection refused.”

11. Checkpoints — Two Related Meanings

Marking safe progress
Plain English: A checkpoint is a marker of safely-saved progress. The word shows up in two related but distinct places in a data pipeline.

a) WAL checkpoint (inside SQLite)

Remember that WAL appends new pages to a side file rather than writing the main file directly. A WAL checkpoint is the process of folding those appended pages back into the main database file, so the side file doesn’t grow forever.

b) Ingestion checkpoint (inside your own pipeline)

When importing millions of records, you don’t want a crash at record 8,000,000 to force you back to record 1. So your own code records, inside the same transaction as the data itself, exactly how far it got:

FieldExample value
last committed record position4,527,000
last committed record’s unique keyjournals/ml/Vaswani17
timestamp2026-07-17 14:02:11
batch statusrunning / completed / failed
records 1–1,000 1,001–2,000 2,001–3,000 ✅ checkpoint here 💥 crash mid-group Resume starts safely from record 3,001 — nothing is redone, nothing is lost.
Fig. 5 — The checkpoint is the trustworthy “you are here” marker your pipeline reads on restart.

The crucial rule: the data rows and the checkpoint marker must be saved in the very same transaction. Otherwise a crash could leave them disagreeing — for instance, rows committed through 3,000 but the checkpoint still saying 2,000, or worse, the reverse.

Remember it as: WAL checkpoint = folding the side file back in. Ingestion checkpoint = your pipeline’s own “last safe position” bookmark. Different layers, same idea: durable progress markers.

12. Benchmark & Median

Measuring instead of guessing
Plain English: A benchmark is a controlled, repeated measurement — you run the same task under different settings and record what actually happens. The median is the middle value once your results are sorted; it resists being thrown off by one freak slow or fast run.

Suppose you time importing 10,000 records under four different SQLite settings, three runs each, in rotated order (to cancel out disk-cache warm-up bias):

ProfileRun 1 (s)Run 2 (s)Run 3 (s)Median (s)
delete + full18.217.931.4 (disk hiccup)18.2
truncate + full17.117.517.317.3
wal + full12.412.612.212.4
wal + normal6.86.56.96.8

Notice run 3 of delete+full: a one-off disk hiccup pushed it to 31.4s. The average of that row would be dragged up to ~22.5s, giving a misleading picture. The median (18.2s) ignores that outlier — which is exactly why engineers report medians for performance benchmarks.

Remember it as: benchmark = don’t guess, measure, repeatedly. Median = the sturdy middle value that ignores one-off flukes.

Part 2 · Matching Messy Records to the Truth

The data is now safely stored. The next challenge is different: someone hands you a messy, incomplete, typo-ridden reference, and you must find — and trust — the correct record out of millions. These eight terms describe that matching pipeline end to end.

13. Canonical Record

One tidy, standard shape for search
Plain English: A canonical record is a standardized, search-friendly version of a source record — built from the original, kept clearly separate from it, and always traceable back to it.

Source data is often messy or inconsistent in ways that are fine for humans but painful for a matching algorithm: extra whitespace, mixed capitalization, markup left inside a title. The canonical layer smooths that out for searching, while the original stays untouched as the source of truth.

Source record (untouched)Canonical record (for search)
Title"An <i>Important</i> Result""an important result"
Author"Müller, Jörg""muller jorg"
Year"2017" (text)2017 (number)

This follows the same rule as protecting source data anywhere in a pipeline: normalize a copy, never overwrite the original. The canonical fields exist purely to make comparison and search fast and consistent.

Remember it as: canonical record = the tidy search-ready twin of the original, always pointing back to where it came from.

14. Exact Identifier Matching

The strongest kind of evidence
Plain English: Before doing any “fuzzy” text comparison, check whether the input already contains a rock-solid identifier — a DOI, an ISBN, a unique database key — and if so, look that up directly. It beats any amount of fuzzy title matching.
<span class="c"># Pipeline order: cheapest, strongest evidence FIRST</span>
<span class="k">if</span> input_has_doi(reference):
    <span class="k">return</span> exact_lookup_by_doi(reference.doi)     <span class="c"># done — near-certain</span>
<span class="k">elif</span> input_has_isbn(reference):
    <span class="k">return</span> exact_lookup_by_isbn(reference.isbn)
<span class="k">else</span>:
    <span class="k">return</span> fuzzy_search_pipeline(reference)         <span class="c"># fall back to sections 15-17</span>
IdentifierExampleUniqueness
DOI10.5555/3295222.3295349globally unique, assigned once
ISBN978-0-13-468599-1unique per book edition
Database keyjournals/ml/Vaswani17unique inside that one database
Remember it as: if a solid ID is sitting right there, use it — don’t guess your way to an answer you already have.

15. Candidate Retrieval & Recall-First Thinking

Cast a wide net first
Plain English: When there’s no exact identifier, the first stage’s only job is to pull a shortlist of maybe 50–200 candidates out of millions of records — and to almost never leave the true answer off that list. Ranking them perfectly comes later.

This stage deliberately favors recall (don’t miss the answer) over precision (don’t worry yet about perfect ordering) — the same recall concept from classic search evaluation. Typical retrieval methods combined here: keyword search (BM25), normalized-title matching, prefix matching, trigram/fuzzy matching, and rough author+year filtering.

CANDIDATE RETRIEVAL millions of records → ~50–200 candidates true answer MUST be in here
Fig. 6 — If retrieval misses the true record, no later stage can rescue it — so this stage optimizes for not losing it.
Remember it as: candidate retrieval = a wide, forgiving net. Miss nothing important; refine later.

16. Field-Level Matching Evidence

Show your work
Plain English: Instead of producing one mysterious overall score, break the comparison down field by field — title, authors, year, venue — so a human can see exactly why the system believes this is (or isn’t) the right match.

For each input-reference and candidate pair, compute separate signals:

FieldInput saidCandidate hasSignal
Title“Attention all need”“Attention Is All You Need”0.94 similarity
First author“Vaswani A”“Ashish Vaswani”✅ match
Year“2017”2017✅ exact
Venue“NIPS”“NeurIPS”0.72 similarity (known alias)

This turns “trust me, it’s 94% confident” into an inspectable, explainable decision — which matters enormously when the answer feeds into something a person will rely on, like a corrected bibliography.

Remember it as: field-level evidence = a receipt, not a black box. Every score should be explainable in one sentence.

17. Reranking

The expensive second look
Plain English: Once you have a short, trustworthy candidate list, a slower but smarter method examines just those few and puts them in the best possible order. This is the same funnel idea from candidate generation — expensive judgment, applied only where it’s affordable.
candidates = [<span class="k">"Attention Is All You Need"</span>, <span class="k">"Attention Networks for..."</span>, <span class="k">"..."</span>]  <span class="c"># ~100 items</span>

<span class="c"># A cheap score got them this far. Now a stronger model re-scores just these few:</span>
<span class="k">for</span> candidate <span class="k">in</span> candidates:
    score = expensive_reranker(input_reference, candidate)   <span class="c"># title+author+year model, or a small LLM</span>

ranked = sort_by_score(candidates)   <span class="c"># the top of this list is the proposed answer</span>

Reranking approaches range from a simple weighted combination of the field-level evidence scores, up through learned classifiers, to a constrained model that compares candidates without being allowed to invent new bibliographic facts.

Remember it as: reranking = the careful final judge, working only with the shortlist the earlier stage already trusts.

18. Calibration

Does “90% sure” actually mean 90%?
Plain English: Calibration checks whether a confidence number is honest. If your system labels a batch of results “90% confident,” roughly 90 out of 100 of them should actually turn out to be correct — not 60, not 99.

A raw similarity score is not automatically a trustworthy probability. Calibration is the process of testing and adjusting that mapping using data where you already know the right answer:

System says confidence ≈How many were actually correct (measured on test data)Verdict
90%88 / 100 correct✅ well-calibrated
70%45 / 100 correct❌ overconfident — needs recalibrating
50%51 / 100 correct✅ well-calibrated
predicted confidence → actual correct → ideal (perfectly honest) actual system (overconfident in the middle)
Fig. 7 — A calibrated system’s curve hugs the diagonal; drifting above or below it means the confidence number is lying.
Remember it as: calibration = fact-checking your own confidence number against reality, not just trusting it.

19. Abstention

The courage to say “I don’t know”
Plain English: Abstention means the system is allowed to return “no reliable match found” instead of being forced to pick a best guess when the evidence is weak.

Compare two outcomes for a vague input like "Smith AI systems 2019":

ApproachOutputRisk
❌ Always answer“Best match: some unrelated 2019 paper by a different Smith — 46%”a wrong answer presented with false authority
✅ Abstention allowed“Unresolved — confidence too low (46%), manual review required”none — the human is correctly warned

Abstention thresholds are usually tiered, so the system’s honesty scales with its actual certainty:

98–100%  <span class="c">→ near-certain</span>
90–97%   <span class="c">→ strong match</span>
70–89%   <span class="c">→ probable, but flagged for review</span>
50–69%   <span class="c">→ uncertain</span>
< 50%    <span class="c">→ abstain: "no reliable match found"</span>

For anything a person will rely on — citations, medical records, legal documents — a confidently wrong answer is far more damaging than an honest “I’m not sure.” (These exact thresholds should always come from measuring calibration on real data, not from guessing.)

Remember it as: abstention = a system mature enough to say “I don’t know” instead of bluffing.

20. Batch Processing Pipeline

Handling many inputs independently
Plain English: A batch pipeline processes a whole uploaded file of inputs by running each one through the same steps independently — so one bad or malformed input can’t derail the rest.

Put every term from Part 2 together, and this is the shape of the whole matching product:

upload file split into refs for each ref… exact ID? (§14) candidates (§15) evidence + rerank (§16-17) calibrated confidence match, or abstain (§18-19) Result: one row per input reference in the downloaded report — errors don’t stop the batch.
Fig. 8 — Every uploaded reference runs the full pipeline independently and lands in the final report — matched, or honestly flagged.

The output a user downloads typically looks like a spreadsheet: one row per input reference, the best verified match, its confidence, its status (strong / review / unresolved), and a link back to the authoritative source record.

Remember it as: batch pipeline = the same trustworthy process, run independently, once per row — so the whole file never fails because of one bad line.

Part 3 · The Engineering Discipline Around the Code

Storing data safely and matching it intelligently are the heart of the system. But no serious project runs on code and a database alone — a handful of everyday engineering terms hold the whole thing together and prove, to you and to anyone else, that it actually works. Here are the rest.

21. Record

The basic unit of data
Plain English: A record is one stored item — one row, one entity, one “thing” your database knows about. It’s the word people use when they mean “row” but are talking about the real-world object it represents, not the table mechanics.

“Row” is a database word; “record” is what that row means. One record might be one book, one customer, one sensor reading — in our running example, one bibliographic reference:

Record (real-world meaning)Row (database mechanics)
“Attention Is All You Need,” a 2017 paperrecord_id=1, title="Attention...", year=2017
Remember it as: record = the real-world thing; row = the database’s way of storing it. Usually interchangeable, but “record” is the human-facing word.

22. Streaming Parser

Reading huge files without running out of memory
Plain English: A streaming parser reads a large file piece by piece — one record at a time — instead of loading the whole thing into memory first. It’s how you process a multi-gigabyte file on an ordinary laptop.
<span class="c"># ❌ Loads the ENTIRE file into memory before doing anything</span>
tree = parse_entire_file(<span class="k">"huge_dataset.xml"</span>)

<span class="c"># ✅ Streaming: reads, converts, and releases ONE record at a time</span>
<span class="k">for</span> record <span class="k">in</span> stream_records(<span class="k">"huge_dataset.xml"</span>):
    save(record)
    <span class="c"># memory for this record is freed before the next one is read</span>

If a source file is several gigabytes — larger than comfortably fits in RAM alongside everything else your program needs — a streaming parser is what makes processing it on a normal machine possible at all, with memory usage staying flat no matter how big the file grows.

Remember it as: streaming parser = read it like a river, not a lake. Constant memory, any file size.

23. Reconciliation

Proving your counts actually agree
Plain English: Reconciliation means calculating the same fact two independent ways and checking they agree exactly. It’s how you prove — with arithmetic, not a feeling — that nothing was silently lost during a big import.

“It looks about right” is not proof. A reconciliation check is:

Independent count #1Independent count #2Must match?
Records read from the source fileRecords stored + records deliberately skippedexactly, always
Unique keys seenRows with a key valueexactly, always
<span class="k">assert</span> records_stored + records_skipped == records_read, \
    f<span class="k">"LEAK! {records_read - records_stored - records_skipped} records unaccounted for"</span>

If even one record is unaccounted for, you stop and investigate before trusting anything built on top of that data.

Remember it as: reconciliation = balancing the books for data. Zero tolerance for an unexplained difference.

24. Provenance

A value’s paper trail
Plain English: Provenance is the recorded trail showing exactly where a stored value came from — which source, which record, which field — so any result can be traced back to its origin.
shown to user source record ID field path transform Ask “where did this come from?” and there’s always a real answer.
Fig. 10 — Provenance turns “trust me” into “here’s exactly where this came from.”

Provenance lets you answer questions like: Which source produced this title? Was it copied exactly, or cleaned up? Can I show the original? Combined with canonical records and field-level evidence from Part 2, it’s what makes a matching system’s output auditable rather than a black box.

Remember it as: provenance = a receipt for every stored value.

25. BM25 & Embedding

Two ways to search text
Plain English: BM25 ranks records by matching words — rare shared words count more than common ones. An embedding turns text into numbers that capture meaning, so related ideas can be found even without shared words. Serious search systems use both.
BM25Embedding
Matches byshared, especially rare, wordssimilarity of meaning
Catches“Vaswani” matching “Vaswani”“heart attack” matching “myocardial infarction”
Missesparaphrased text with no shared wordscan confuse similar-but-different topics
Speedvery fast, index-basedslower, needs a vector search
<span class="c"># A minimal BM25-style intuition: score = sum of rarity-weighted shared words</span>
query = <span class="k">"attention vaswani"</span>
<span class="c"># "attention" appears in 12,000 records → moderate weight</span>
<span class="c"># "vaswani"   appears in 45 records     → high weight (rare = strong evidence)</span>

In a real matching pipeline, both feed into candidate retrieval from Part 2 — BM25 catching exact wording, embeddings catching paraphrases and typo-heavy input that shares almost no literal words with the true title.

Remember it as: BM25 = “rare shared words are strong evidence.” Embedding = “search by meaning, not just spelling.”

26. The Two Meanings of “Commit”

A word that means two different things
Plain English: The word commit shows up in two completely different places in a software project, and beginners often mix them up. They share a name but do unrelated jobs.
Database commit (SQL)Git commit (source control)
What it savesrows of dataa snapshot of source code
When you’d use itafter inserting/updating records in a transactionafter finishing a piece of code you want to remember
CommandCOMMIT;git commit -m "message"
Undo equivalentROLLBACK;git revert / git reset
<span class="c">-- Database commit: saves DATA changes</span>
<span class="k">BEGIN</span>;
  <span class="k">INSERT INTO</span> records VALUES (...);
<span class="k">COMMIT</span>;

# Git commit: saves a CODE snapshot
git add ingestion_runner.py
git commit -m "Add checkpointed DBLP ingestion runner"
Remember it as: database commit saves data; Git commit saves code history. Same word, two unrelated jobs — always check which one a sentence means.

27. Git, GitHub & Push

Tracking and backing up your code
Plain English: Git is a tool that records every version of your code on your own machine. GitHub is a website that stores a copy of that history remotely. Push is the act of sending your local Git history up to GitHub.
your laptop (Git) ● commit A ● commit B ● commit C (latest) git push GitHub (remote backup + history) ● commit A ● commit B ● commit C ✅ backed up
Fig. 11 — Git tracks history locally; pushing sends that history to a durable, shareable remote copy.
git add ingestion_runner.py           <span class="c"># stage the changed file</span>
git commit -m <span class="k">"Add checkpointed DBLP ingestion runner"</span>   <span class="c"># snapshot it locally</span>
git push origin main                  <span class="c"># send that snapshot to GitHub</span>

Until you push, your commits exist only on your own machine — a hard-drive failure would lose them. GitHub is what turns “recorded” into “durably backed up and shareable.”

Remember it as: Git = your local diary of every code change. GitHub = the shared, backed-up copy of that diary. Push = mailing the latest pages there.

28. pytest, Ruff & mypy

Three different kinds of “is this code okay?”
Plain English: Three tools that each check your code for a different kind of problem. Running all three catches far more than any one alone.
ToolWhat it checksExample it catches
pytestDoes the code actually behave correctly? (automated tests)“I expected 100 records stored, but got 99.”
RuffStyle & common mistakes (a linter)An unused import, or a variable that’s never used.
mypyDo the declared types actually agree? (a type checker)“This function promises to return an int, but sometimes returns None.”
<span class="c"># pytest: does the behavior work?</span>
<span class="k">def</span> test_all_records_stored():
    <span class="k">assert</span> stored_count == 100    <span class="c"># fails loudly if the real count is 99</span>

<span class="c"># Ruff: style / suspicious patterns (run from the terminal)</span>
$ ruff check .

<span class="c"># mypy: do the types add up? (run from the terminal)</span>
$ mypy src/
<span class="c"># error: Function is declared to return 'int', but returns 'int | None'</span>

These three catch genuinely different bug categories: pytest proves behavior against real expectations, Ruff flags sloppy or risky patterns before they cause trouble, and mypy catches internal inconsistencies that tests might never happen to exercise. A project reporting “all tests pass” alongside “Ruff and mypy also pass” is reporting three separate, complementary kinds of confidence.

Remember it as: pytest asks “does it work?” · Ruff asks “is it clean?” · mypy asks “are the types honest?”

Real-World Numbers: How Big Are These Bibliography Databases?

All the ideas above become more concrete once you see them applied to a real dataset. DBLP is a well-known, freely available computer-science bibliography — a good example of exactly the kind of dataset this article’s techniques are built for.

FactValue
Maintained bySchloss Dagstuhl – Leibniz Center for Informatics (originally University of Trier, since 1993)
Records~8.5 million publications (passed 2²³ = 8,388,608 in Sept. 2025)
Growth rate500,000+ new records added per year
Download formatone XML file + a DTD grammar file
Compressed size≈ 1.0 GB (.xml.gz)
Update cadencedaily (unversioned) + monthly DOI-tagged snapshot releases
LicenseCC0 1.0 — public domain dedication

DBLP’s official guidance is a textbook case for the streaming concept: the dataset is too large to load fully into memory, so their own documentation recommends event-based streaming parsers rather than loading the whole tree at once — exactly the “process one record at a time” idea this article’s companion piece covers.

DBLP is far from the largest bibliography source in existence. Here’s how a few major ones compare in scale (figures change constantly — treat these as an “as of” snapshot):

DatabaseApprox. sizeFocusLicense / operator
DBLP~8.5 millionComputer science publicationsCC0 · Schloss Dagstuhl
Crossref~180 millionDOI registration across all disciplinesOpen metadata · nonprofit
OpenAlex260 million+All disciplines: works, authors, institutionsCC0 · OurResearch (nonprofit)
Semantic Scholar200 million+All fields, strong in CS & biomedicineAllen Institute for AI
DBLP8.5M Crossref180M Semantic S.200M+ OpenAlex260M+
Fig. 9 — DBLP is a focused, high-quality CS bibliography; general-purpose sources like OpenAlex are more than 25× larger.
Why this matters for matching: the bigger the reference database, the more names, titles and venues will look almost-but-not-quite alike — which is exactly why the candidate retrieval, field-level evidence, and calibration steps from Part 2 matter so much more at real-world scale than they would on a small personal list.

Quick-Reference Glossary

TermOne-line definition
SQLiteA full relational database that lives inside one ordinary file.
Schema / table / row / columnThe floor plan, the shelf, one item, one property.
Primary keyThe value that uniquely names one row.
Foreign keyA rule that a value must point to a row that really exists elsewhere.
TransactionA group of writes treated as one all-or-nothing unit.
Commit / rollbackSave the group permanently / undo the whole group.
AtomicityThe guarantee that a transaction never leaves a half-done result.
PRAGMAA command that reads or changes the database engine’s own settings.
Journal / journal modeScratch info for crash recovery; the strategy used to keep it (DELETE, TRUNCATE, WAL).
WAL modeJournal mode that lets readers and one writer work without blocking each other.
SynchronousHow often SQLite forces data physically onto disk before continuing.
Busy timeoutHow long a second writer waits before giving up when the database is locked.
Checkpoint (WAL)Folding the WAL side file’s changes back into the main database file.
Checkpoint (ingestion)Your pipeline’s own bookmark of the last safely-saved record.
Benchmark / medianA controlled repeated measurement; its outlier-resistant middle value.
Canonical recordA tidy, search-ready copy of a source record, always traceable back to it.
Exact identifier matchingLooking a record up directly by a solid ID (DOI, ISBN) instead of guessing.
Candidate retrievalCheaply narrowing millions of records to a shortlist that must contain the answer.
Field-level evidenceBreaking a match’s score down field by field so it’s explainable.
RerankingA slower, smarter method that orders only the short candidate list.
CalibrationTesting whether a “90% confident” score is actually right ~90% of the time.
AbstentionReturning “no reliable match” instead of a forced, possibly wrong, best guess.
Batch pipelineRunning every uploaded input through the same steps independently.
RecordThe real-world thing a database row represents.
Streaming parserReads a huge file one record at a time instead of loading it all into memory.
ReconciliationProving two independently calculated counts agree exactly.
ProvenanceThe recorded trail showing exactly where a value came from.
BM25Ranks records by matching words, weighting rare shared words highest.
EmbeddingText turned into numbers that capture meaning, for search beyond exact wording.
Commit (database)Permanently saves the current data transaction.
Commit (Git)Saves a snapshot of source code history — unrelated to a database commit.
Git / GitHub / PushLocal code history · its remote backup · sending local history to that remote.
pytest / Ruff / mypyAutomated behavior tests · style & mistake linter · type-consistency checker.

Putting It All Together

These twenty-eight terms split into three acts. Act one keeps your data safe no matter what fails: transactions bundle writes atomically, journal modes and WAL decide how recovery works, the synchronous setting is the one honest knob that trades speed for surviving a real power loss, and checkpoints — at both the SQLite level and your own pipeline’s level — mark exactly how far you can trust your progress. Act two turns that safely-stored data into something genuinely useful: exact identifiers first, a wide candidate net second, explainable field-by-field evidence third, a careful reranking pass, an honestly calibrated confidence score, and — when the evidence just isn’t there — the maturity to abstain rather than guess. Act three is the discipline around all of it: proving your counts reconcile, keeping a provenance trail, knowing your two “commits” apart, and using Git, GitHub, and a testing toolchain to make sure the whole system is reproducible by someone who wasn’t in the room when you built it.

Master these terms and you can read the architecture of almost any serious data pipeline or record-matching system — including the kind that turns a messy pile of citations into a verified, trustworthy bibliography.

Published by INGOAMPT · A free learning resource. Share it freely.

Leave a reply

Your email address will not be published. Required fields are marked *