SQL, SQLite, modern database alternatives

SQL, SQLite, and Citation Databases in 2026
Developer & Data Scientist Guide · 2026 Edition

SQL, SQLite, and the Data Architecture Behind Citation Matching

How scholarly systems store hundreds of millions of works, how a database transforms a SQL statement into disk reads, and how SQL, full-text search, vector search, and graph data cooperate to repair noisy references.

SQLLanguage for structured data
SQLiteSQL engine inside one local file
Hybrid searchExact + lexical + semantic
Local-firstFrom laptop subsets to multi-TB snapshots

1. Executive summary

1
Relational backbone

Canonical works, authors, identifiers, venues, and relationships.

2
Search indexes

Full-text and fuzzy indexes generate candidate records rapidly.

3
ML ranking

A scoring model decides which candidate best matches the noisy input.

4
Evidence output

The system explains why the selected reference is trustworthy.

The central idea: a serious citation fixer normally does not choose one database technology. It uses a layered system. SQL stores reliable structure; a text-search index finds lexical candidates; a vector index catches semantic similarity; graph edges represent citations; and a ranking service combines the evidence.

SQL is not a database product. It is a declarative language: you describe the result you need, and a database engine decides how to obtain it. SQLite is one implementation of an SQL database. It runs inside the application and stores the database in a file, which makes it excellent for prototypes, desktop tools, mobile apps, local research subsets, and read-heavy citation indexes.

2. What SQL is

SQL means Structured Query Language. It lets a developer define tables, enforce constraints, insert data, connect related tables, aggregate results, and update records. The developer specifies what should be returned; the engine selects how to execute the request.

Human question

“Find computer-science papers from 2024 whose titles mention citation matching, and show their authors.”

SQL expression

SELECT p.title, a.name
FROM papers p
JOIN paper_authors pa ON pa.paper_id = p.id
JOIN authors a ON a.id = pa.author_id
WHERE p.year = 2024
  AND p.title_search MATCH 'citation matching';

Core relational concepts

ConceptMeaningCitation exampleWhy it matters
TableA named collection of rowspapers, authorsSeparates entities cleanly
RowOne recordOne scholarly workRepresents a canonical object
ColumnA typed attributeDOI, title, yearEnables filtering and validation
Primary keyUnique row identifierpaper_idStable internal identity
Foreign keyReference to another rowpaper_authors.paper_idPreserves relationships
IndexAuxiliary structure for faster lookupIndex on DOI or normalized titleAvoids scanning every row
TransactionAtomic group of operationsInsert work, authors, and references togetherPrevents partially imported records

Normalization: why data is separated

A paper may have five authors, and one author may have hundreds of papers. Repeating the full author record inside every paper wastes space and produces inconsistencies. A normalized schema stores each author once and represents authorship with a join table.

papers id PK title year doi paper_authors paper_id FK author_id FK position authors id PK display_name orcid 1 → many many → 1
A many-to-many relation becomes two one-to-many relations through a join table.

3. What SQLite is—and what “SQL light” actually means

The product is named SQLite, pronounced “S-Q-L-ite” or “sequel-lite.” It is not a simplified query language. It is a complete embedded relational database engine delivered as a library. The application calls SQLite directly; there is no separate database server process and no network round trip.

SQLite: embedded Your application Python · Swift · C · Java SQLite library Parser · planner · B-tree citation.db Tables + indexes + WAL PostgreSQL/MySQL: client–server Application client Network + authentication TCP/socket protocol Database server Shared multi-user service
QuestionSQLitePostgreSQL / server DB
Where does it run?Inside your processSeparate server process
StorageUsually one portable fileManaged directory of database files
SetupAlmost zero configurationInstallation, users, networking, maintenance
ConcurrencyMany readers, limited concurrent writingDesigned for many readers and writers
Best useLocal tools, mobile, desktop, prototypes, subsetsShared APIs, multi-user systems, large ingestion pipelines
Citation project roleLocal cache or compact research databaseCanonical central metadata store

Important 2025–2026 direction

SQLite continues to improve schema evolution, JSON manipulation, command-line formatting, indexing, and reliability. For citation systems, the enduringly useful features are its B-tree indexes, ACID transactions, JSON functions, FTS5 full-text search, generated columns, expression indexes, and write-ahead logging.

Use SQLite when: the database must travel with a desktop application, the system is read-heavy, the data fits comfortably on one machine, or you are building a reproducible local benchmark. Do not use it as the only central database for a high-write, multi-server service.

4. What happens behind a SQL query

A SQL query looks compact, but the database performs a pipeline of interpretation, planning, storage access, and result construction.

1. ParseCheck syntax and build an abstract syntax tree.
2. ResolveFind tables, columns, functions, and permissions.
3. RewriteSimplify expressions and expand views.
4. PlanEstimate costs and select indexes and join order.
5. ExecuteRead pages, traverse indexes, join rows.
6. Sort/AggregateRank, group, count, or deduplicate.
7. ReturnEncode result rows for the application.

Example: exact DOI lookup

SELECT id, title, year
FROM papers
WHERE doi = '10.1145/1234567.1234568';

Without an index, the engine may inspect every paper row. With a unique index on doi, it traverses a B-tree from the root to a small leaf page, finds the row pointer, and fetches the matching record.

Simplified B-tree lookup for a DOI Root page 10.10… | 10.50… | 10.90… Left branch DOIs below 10.50… Chosen branch 10.50… to 10.90… Right branch DOIs above 10.90… Leaf entry DOI → row location / primary key
The exact physical layout differs by database, but the central principle is logarithmic navigation through sorted keys.

How joins are chosen

Join algorithmHow it worksGood situationCitation example
Nested-loop joinFor each row on one side, probe the other sideSmall outer result and indexed inner tableTen candidate paper IDs joined to author rows
Hash joinBuild a hash table from one input, probe with the otherLarge unsorted equality joinsBulk linking imported works to identifiers
Merge joinWalk two sorted inputs togetherBoth sides already sorted or indexedComparing ordered DOI lists from two providers

5. How scholarly data looks before and after ingestion

Citation databases publish different data formats. An ingestion pipeline parses those formats, normalizes identifiers and text, and writes a query-friendly representation.

DBLP XML
<article key="journals/example/Smith24">
  <author>Alice Smith</author>
  <author>Bob Lee</author>
  <title>Fuzzy Citation Matching at Scale</title>
  <year>2024</year>
  <journal>Journal of Data Systems</journal>
  <ee>https://doi.org/10.1234/example.2024.7</ee>
</article>
PubMed XML
<PubmedArticle>
  <MedlineCitation PMID="40123456">
    <Article>
      <ArticleTitle>Reference Resolution in Biomedical Literature</ArticleTitle>
      <Abstract>...</Abstract>
      <Journal>...</Journal>
    </Article>
  </MedlineCitation>
</PubmedArticle>
OpenAlex JSONL
{
  "id": "https://openalex.org/W1234567890",
  "doi": "https://doi.org/10.1234/example.2024.7",
  "title": "Fuzzy Citation Matching at Scale",
  "publication_year": 2024,
  "authorships": [
    {"author": {"id": "A100", "display_name": "Alice Smith"}}
  ],
  "referenced_works": ["W99", "W105"]
}
Normalized SQL
papers
┌──────┬──────────────────────────────────┬──────┬────────────────────────┐
│ id   │ title                            │ year │ doi                    │
├──────┼──────────────────────────────────┼──────┼────────────────────────┤
│ 7821 │ Fuzzy Citation Matching at Scale │ 2024 │ 10.1234/example.2024.7│
└──────┴──────────────────────────────────┴──────┴────────────────────────┘

paper_authors
┌──────────┬───────────┬──────────┐
│ paper_id │ author_id │ position │
├──────────┼───────────┼──────────┤
│ 7821     │ 100       │ 1        │
│ 7821     │ 205       │ 2        │
└──────────┴───────────┴──────────┘
Search document
{
  "_id": "7821",
  "title": "Fuzzy Citation Matching at Scale",
  "title_normalized": "fuzzy citation matching at scale",
  "authors": ["Alice Smith", "Bob Lee"],
  "year": 2024,
  "venue": "Journal of Data Systems",
  "doi": "10.1234/example.2024.7"
}
Vector record
{
  "id": "7821",
  "vector": [0.021, -0.117, 0.308, ... 765 more values ...],
  "metadata": {
    "year": 2024,
    "source": "openalex"
  }
}
Citation graph
Node:  Work W7821
Edge:  W7821 --CITES--> W99
Edge:  W7821 --CITES--> W105
Node:  Author A100
Edge:  A100 --AUTHORED--> W7821

Row storage versus columnar storage

Row-oriented storage Column-oriented storage Paper 1id · title · year · DOI · venue Paper 2id · title · year · DOI · venue Paper 3id · title · year · DOI · venue Best for fetching or updating complete records. IDs: 1, 2, 3, … Years: 2024, 2021, 2024, … Venues: JDS, VLDB, JMLR, … DOIs: 10.1…, 10.2…, 10.3… Best for scanning a few columns across many rows.
PostgreSQL and SQLite are primarily row-oriented. Parquet, DuckDB, and ClickHouse are strong for analytical scans.

6. The index structures behind fast search

Index typeStoresBest queryCitation useTypical technologies
B-treeSorted keys and pointersEquality, range, ordered retrievalDOI, PMID, year, author IDSQLite, PostgreSQL, MySQL
Hash indexHash bucketsEquality onlyExact normalized identifier lookupPostgreSQL, in-memory caches
Inverted indexToken → document postings listKeyword, phrase, fuzzy text searchTitle, abstract, author stringFTS5, Elasticsearch, OpenSearch, Lucene
Trigram indexOverlapping character triplesTypo-tolerant similarity“Szeider” versus “Sezider”PostgreSQL pg_trgm
LSM treeSorted immutable runs plus memory tableHigh-throughput writesStreaming provider updatesRocksDB, Cassandra, ScyllaDB
HNSW / ANNGraph or partitioned vector structureNearest vectorsSemantic title/abstract retrievalpgvector, Qdrant, Milvus, FAISS
Graph adjacencyNode relationshipsNeighborhood and path traversalCitation and co-author networksNeo4j, graph extensions

How an inverted index looks

Documents

D1: "fuzzy citation matching"
D2: "citation graph search"
D3: "fuzzy author resolution"

Inverted index

citation → [D1, D2]
fuzzy    → [D1, D3]
matching → [D1]
graph    → [D2]
author   → [D3]

A keyword search for fuzzy AND citation intersects the postings lists and immediately identifies D1, rather than scanning every title.

Why one index is not enough

Exact

Input: correct DOI
Winner: B-tree unique index
Confidence: very high

Lexical fuzzy

Input: misspelled title
Winner: trigram or full-text index
Confidence: medium to high

Semantic

Input: remembered concept, not exact wording
Winner: vector index
Confidence: candidate-generation only

7. SQL databases and their alternatives in 2026

“Alternative to SQL” is often the wrong framing. Most specialized systems solve a different access pattern. The architectural question is: which storage and index should own each responsibility?

TechnologyData modelStrengthWeaknessBest role in citation systems
SQLiteRelational, embeddedPortable, simple, ACID, local FTSLimited concurrent writesDesktop/local index, prototype, filtered corpus
PostgreSQLRelational + JSON + extensionsStrong joins, constraints, text, vectorsOperational complexity versus SQLitePrimary metadata store and hybrid-search backbone
MySQLRelationalMature, widely hosted, strong OLTPLess rich extension ecosystem for this use caseConventional metadata service
DuckDBEmbedded columnar analyticsFast local Parquet/CSV analysisNot intended as a high-concurrency API storeExplore OpenAlex snapshots without full import
ClickHouseDistributed columnarHuge analytical scans and compressionLess natural for transactional graph updatesAggregate citation statistics at scale
Elasticsearch / OpenSearchSearch documentsFull-text, typo tolerance, scoring, facetsNot ideal as the sole system of recordCandidate generation from titles/authors/venues
Neo4jProperty graphRelationship traversal and path queriesExtra operational layerCitation networks, co-author paths, graph features
Qdrant / Milvus / WeaviateVectors + metadataApproximate nearest-neighbor searchSemantic similarity can return plausible but wrong recordsBroad semantic candidate generation
pgvectorVectors inside PostgreSQLSQL filters and vectors togetherDedicated systems may scale further for extreme vector loadsExcellent first production vector layer
RocksDB / LMDBEmbedded key-valueFast low-level lookup, compact storageNo rich SQL joins by defaultIdentifier maps, caches, precomputed features
Object storage + ParquetFiles, columnarCheap snapshots, partitioning, interoperabilityNeeds query engine or ingestion pipelineRaw provider lake and reproducible archives

Decision matrix

NeedRecommended first choiceWhy
Exact DOI/PMID lookupPostgreSQL or SQLite B-treeUnique indexed key lookup
Typo-tolerant title matchingPostgreSQL trigram or OpenSearchCharacter-level similarity and text ranking
Search by remembered meaningpgvector, Qdrant, Milvus, or FAISSEmbedding similarity
Analyze 200M+ works locallyParquet + DuckDBColumn pruning and no mandatory full import
Shared canonical servicePostgreSQLConstraints, joins, reliability, extension ecosystem
Explore citation pathsSQL recursive query first; graph DB if neededAvoid premature graph infrastructure
Mobile or desktop offline databaseSQLiteSingle-file embedded deployment

8. How DBLP, PubMed, and OpenAlex can be stored locally

DatasetPrimary scopeBulk formatTypical local strategyStrong identifier
DBLPComputer science bibliographyLarge XML dumpStream XML → normalized SQL and search indexDBLP keys, DOI when present
PubMed/MEDLINEBiomedical literatureAnnual XML baseline + update filesLoad baseline, apply updates in order, index PMID/DOI/title/MeSHPMID, DOI
OpenAlexCross-disciplinary scholarly graphJSONL/Parquet-style snapshots and APIsKeep raw snapshot in object/file storage; query with DuckDB or import selected tablesOpenAlex IDs, DOI
CrossrefDOI metadataAPI and bulk optionsCache canonical DOI metadata and update timestampsDOI
OpenCitationsOpen citation linksAPIs and bulk datasetsStore DOI-to-DOI edges in partitioned files or edge tableDOI pairs

Scale changes the architecture

Laptop subset • 10k–5M works • SQLite • FTS5 • Local vectors Workstation • Millions–100M • Parquet • DuckDB • FAISS/HNSW Single server • 100M+ records • PostgreSQL • OpenSearch • pgvector Distributed • Multi-TB / high QPS • Object storage • Search cluster • Batch pipelines Lower operational complexity Higher scale and concurrency

Do companies really keep all of this “locally”?

“Local” can mean a laptop, an on-premise server, or the company’s own cloud account. Production companies often download provider snapshots into their own object storage, transform them with batch jobs, load canonical records into PostgreSQL or another serving database, and build separate text and vector indexes. They may not load every raw field into the serving database.

A practical rule: preserve the raw source files, create a normalized canonical layer, and build disposable indexes from that canonical layer. Search indexes should be rebuildable; source history should not be lost.

9. How a citation-matching system finds the correct reference

A raw citation is noisy. It may have a missing DOI, misspelled author, abbreviated venue, incorrect year, broken page range, reordered fields, or copied punctuation. Matching therefore uses multiple signals.

Raw citationUnstructured user text
ParseTitle, authors, year, venue, pages, IDs
NormalizeCase, Unicode, punctuation, DOI, names
RetrieveExact, FTS, trigram, vector candidates
ScoreWeighted field similarities
VerifyCross-source agreement and constraints
ReturnCanonical citation + evidence

Example input

Smith A., Lee B. Fuzzy citaton maching scale.
J Data Syst, 2024, doi 10.1234/example.2024.?

Parsed representation

{
  "authors": ["Smith A", "Lee B"],
  "title": "Fuzzy citaton maching scale",
  "venue": "J Data Syst",
  "year": 2024,
  "doi_prefix": "10.1234",
  "doi_complete": false
}

Candidate-generation methods

SignalQuery methodExample contributionRisk
DOI exactUnique SQL indexImmediately resolves canonical workUser may provide malformed DOI
Title token overlapFull-text searchFinds documents sharing distinctive wordsCommon titles produce many candidates
Title edit similarityTrigram / LevenshteinHandles “citaton” and “maching”Can overvalue similar short strings
Author similarityNormalized names + aliasesConfirms candidate identityName collisions and transliteration
YearSQL filter or score featureStrongly narrows the spaceOnline-first and print years may differ
VenueAlias dictionary + fuzzy indexExpands “J Data Syst”Abbreviations can be ambiguous
Semantic embeddingANN vector searchFinds paraphrased or remembered conceptsSemantic closeness is not bibliographic identity
Citation graphGraph/edge featuresUses neighboring references or citing document contextUnavailable for isolated inputs

A transparent scoring formula

score =
  0.40 * title_similarity
+ 0.20 * author_similarity
+ 0.12 * venue_similarity
+ 0.10 * year_compatibility
+ 0.08 * page_similarity
+ 0.05 * identifier_prefix_match
+ 0.05 * source_agreement

A learned model can replace fixed weights, but the features should remain inspectable. For a citation-fixing product, confidence calibration matters: a system should abstain when top candidates are too close.

Critical safety rule for scholarly references: embeddings should retrieve candidates, not invent bibliographic facts. The final DOI, authors, venue, and year must come from verified provider records.

Illustrative ranked candidates

RankCandidateTitleAuthorsYearOverallDecision
1W78210.970.931.000.95Accept
2W44100.830.451.000.72Keep as fallback
3W99200.740.910.000.65Reject: year conflict

10. Efficient local querying of very large datasets

Strategy A: import a filtered subset into SQLite

Select the relevant subject area, years, fields, or providers, then create a compact database containing only the fields needed for matching. This is ideal for a prototype or a computer-science-only DBLP system.

CREATE TABLE papers (
  id INTEGER PRIMARY KEY,
  source TEXT NOT NULL,
  source_id TEXT NOT NULL,
  doi TEXT,
  title TEXT NOT NULL,
  title_norm TEXT NOT NULL,
  year INTEGER,
  venue_id INTEGER,
  raw_json TEXT
);

CREATE UNIQUE INDEX ux_papers_source
ON papers(source, source_id);

CREATE INDEX ix_papers_doi
ON papers(doi);

CREATE INDEX ix_papers_year
ON papers(year);

Strategy B: keep snapshots as Parquet and query with DuckDB

For a huge OpenAlex snapshot, importing everything into a row database may take substantial time and disk space. DuckDB can query partitioned Parquet directly and only read the required columns and partitions.

SELECT id, doi, title, publication_year
FROM read_parquet('openalex/works/**/*.parquet')
WHERE publication_year BETWEEN 2022 AND 2026
  AND lower(title) LIKE '%citation matching%';

Strategy C: central PostgreSQL plus specialized indexes

Store canonical entities in PostgreSQL; send denormalized search documents to OpenSearch; store embeddings in pgvector initially; keep provider snapshots in object storage; and build batch pipelines for updates.

Storage optimizations

TechniqueWhat it doesExampleBenefit
PartitioningDivides data by a predictable keyWorks by publication year or sourcePrunes irrelevant files or table partitions
CompressionEncodes repeated values compactlyParquet dictionary encoding for venue namesLess disk and I/O
Column pruningReads only required fieldsRead DOI/title/year, skip concepts and grantsFaster analytical queries
Batch insertWrites many rows per transaction10,000 works per commitFar faster ingestion
Materialized feature tablePrecomputes matching fieldsNormalized title tokens and author signaturesLow-latency ranking
CacheStores frequent answersDOI metadata and common citation stringsReduces repeated search work

11. Recommended architecture for a citation-fixing company

The following design is appropriate for a product that accepts malformed references, searches DBLP, PubMed, OpenAlex, Crossref, and OpenCitations, and returns ranked canonical matches with evidence.

Data ingestion and serving architecture DBLP XML Computer science PubMed XML Biomedical OpenAlex JSONL / Parquet Crossref DOI metadata OpenCitations Citation edges Ingestion & normalization pipeline Parse · validate · normalize DOI/title/names · deduplicate · preserve provenance Canonical PostgreSQL • Works, authors, venues, identifiers • Provenance and update history Search indexes • OpenSearch / trigram / FTS • Title, author, venue candidates Vector & graph layer • pgvector / Qdrant / FAISS • Citation-edge features Citation matching service Parse input → retrieve candidates → compute features → rank → calibrate confidence → explain result Verified citation + alternatives + evidence

What each layer owns

LayerOwnsShould not own
Raw snapshot storeImmutable provider files and update batchesLow-latency user queries
Canonical SQL storeTrusted entities, IDs, constraints, provenanceAll fuzzy search logic
Text searchLexical candidate retrieval and relevance featuresFinal bibliographic truth
Vector layerSemantic candidates and similarity featuresInventing missing identifiers
RankerCombining evidence and confidenceSilently accepting ambiguous cases
Formatting serviceAPA, IEEE, Chicago, BibTeX, RIS, CSL-JSONChanging canonical metadata without provenance
Recommended first production stack: PostgreSQL + pg_trgm + PostgreSQL full-text search + pgvector + object storage for raw snapshots. Add OpenSearch only when text-search scale, ranking, or operational requirements justify a separate cluster.

12. A practical canonical schema

CREATE TABLE works (
  work_id            BIGSERIAL PRIMARY KEY,
  canonical_title    TEXT NOT NULL,
  title_normalized   TEXT NOT NULL,
  publication_year   SMALLINT,
  work_type          TEXT,
  venue_id            BIGINT,
  created_at          TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at          TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE work_identifiers (
  work_id             BIGINT NOT NULL REFERENCES works(work_id),
  scheme              TEXT NOT NULL,  -- doi, pmid, openalex, dblp
  value               TEXT NOT NULL,
  source              TEXT NOT NULL,
  is_primary          BOOLEAN NOT NULL DEFAULT false,
  PRIMARY KEY (scheme, value)
);

CREATE TABLE authors (
  author_id            BIGSERIAL PRIMARY KEY,
  display_name         TEXT NOT NULL,
  name_normalized      TEXT NOT NULL,
  orcid                TEXT
);

CREATE TABLE work_authors (
  work_id              BIGINT NOT NULL REFERENCES works(work_id),
  author_id            BIGINT NOT NULL REFERENCES authors(author_id),
  author_position      SMALLINT,
  raw_name             TEXT,
  PRIMARY KEY (work_id, author_id)
);

CREATE TABLE citations (
  citing_work_id       BIGINT NOT NULL REFERENCES works(work_id),
  cited_work_id        BIGINT NOT NULL REFERENCES works(work_id),
  source               TEXT NOT NULL,
  confidence           REAL,
  PRIMARY KEY (citing_work_id, cited_work_id, source)
);

CREATE TABLE source_records (
  source               TEXT NOT NULL,
  source_record_id     TEXT NOT NULL,
  work_id              BIGINT REFERENCES works(work_id),
  payload              JSONB NOT NULL,
  source_updated_at    TIMESTAMPTZ,
  ingested_at          TIMESTAMPTZ NOT NULL DEFAULT now(),
  PRIMARY KEY (source, source_record_id)
);

Indexes for matching

CREATE UNIQUE INDEX ux_identifier
ON work_identifiers (scheme, value);

CREATE INDEX ix_work_year
ON works (publication_year);

CREATE INDEX ix_title_trgm
ON works USING gin (title_normalized gin_trgm_ops);

CREATE INDEX ix_author_name_trgm
ON authors USING gin (name_normalized gin_trgm_ops);

CREATE INDEX ix_citations_cited
ON citations (cited_work_id);

Why raw payloads are retained

The canonical tables make querying simple, but provider-specific fields can be lost during normalization. Keeping the original payload enables audits, reprocessing, new feature extraction, and resolution of disagreements between sources.

13. Practical query examples

Exact DOI resolution

SELECT w.work_id, w.canonical_title, w.publication_year
FROM work_identifiers i
JOIN works w ON w.work_id = i.work_id
WHERE i.scheme = 'doi'
  AND i.value = '10.1234/example.2024.7';

Typo-tolerant title candidates in PostgreSQL

SELECT
  work_id,
  canonical_title,
  similarity(title_normalized,
             'fuzzy citaton maching at scale') AS title_score
FROM works
WHERE title_normalized % 'fuzzy citaton maching at scale'
ORDER BY title_score DESC
LIMIT 25;

Combined title, author, and year ranking

WITH title_candidates AS (
  SELECT
    w.work_id,
    similarity(w.title_normalized, :title_norm) AS title_score
  FROM works w
  WHERE w.title_normalized % :title_norm
  LIMIT 100
)
SELECT
  w.work_id,
  w.canonical_title,
  w.publication_year,
  tc.title_score,
  MAX(similarity(a.name_normalized, :first_author_norm)) AS author_score,
  CASE WHEN w.publication_year = :year THEN 1.0 ELSE 0.0 END AS year_score
FROM title_candidates tc
JOIN works w ON w.work_id = tc.work_id
LEFT JOIN work_authors wa ON wa.work_id = w.work_id
LEFT JOIN authors a ON a.author_id = wa.author_id
GROUP BY w.work_id, w.canonical_title, w.publication_year, tc.title_score
ORDER BY
  0.65 * tc.title_score +
  0.25 * MAX(similarity(a.name_normalized, :first_author_norm)) +
  0.10 * CASE WHEN w.publication_year = :year THEN 1.0 ELSE 0.0 END
  DESC
LIMIT 10;

Find all works citing a DOI

SELECT citing.canonical_title, citing.publication_year
FROM work_identifiers target_id
JOIN citations c ON c.cited_work_id = target_id.work_id
JOIN works citing ON citing.work_id = c.citing_work_id
WHERE target_id.scheme = 'doi'
  AND target_id.value = '10.1234/example.2024.7'
ORDER BY citing.publication_year DESC;

SQLite FTS5 prototype

CREATE VIRTUAL TABLE work_search USING fts5(
  title,
  authors,
  venue,
  content='works_flat',
  content_rowid='work_id'
);

SELECT rowid, title, bm25(work_search) AS rank
FROM work_search
WHERE work_search MATCH '"citation matching" OR "reference resolution"'
ORDER BY rank
LIMIT 20;

Vector search with SQL filters

SELECT
  work_id,
  canonical_title,
  1 - (embedding <=> :query_embedding) AS semantic_score
FROM work_embeddings
WHERE publication_year BETWEEN 2020 AND 2026
ORDER BY embedding <=> :query_embedding
LIMIT 50;

14. Implementation roadmap for a real citation matcher

PhaseBuildOutputMain evaluation
1. BaselineDBLP subset + SQLite + normalizationExact and FTS candidate searchRecall@10 on corrupted citations
2. Fuzzy fieldsTitle trigrams, author aliases, venue dictionaryFeature-based rankerTop-1 accuracy and mean reciprocal rank
3. Multi-sourceOpenAlex, Crossref, PubMed adaptersCanonical entity resolutionDuplicate rate and source agreement
4. Semantic retrievalEmbeddings and ANN indexRecovery of weak lexical matchesIncremental recall versus false positives
5. ConfidenceCalibration and abstention policyAccept / review / unresolved resultPrecision at automatic-accept threshold
6. ProductAPI, browser UI, BibTeX/CSL export, provenanceUsable citation-fixing serviceLatency, user correction rate, trust

Recommended evaluation dataset

Start from known canonical references, then generate realistic corruption: delete fields, alter punctuation, introduce OCR-like substitutions, abbreviate venues, reorder authors, change initials, remove DOI suffixes, and perturb years. Keep the original work ID as ground truth.

Retrieval metrics

Recall@1, Recall@5, Recall@10, candidate-set size, retrieval latency.

Ranking metrics

Top-1 accuracy, mean reciprocal rank, precision at confidence threshold, calibration error.

Final recommendation

For the first serious version, use PostgreSQL as the canonical store, keep all raw provider files in compressed object/file storage, use trigram and full-text indexes for candidate generation, add pgvector only after the lexical baseline is measured, and design the ranker to produce transparent field-level evidence. Use SQLite as a downloadable local edition or benchmark package.

15. Research sources and further reading

This article consolidates the prior deep-research report and extends it with original explanatory diagrams, sample schemas, and architecture recommendations. Product versions and dataset sizes change, so verify operational details against current official documentation before deployment.

SQL, SQLite, and Citation Databases in 2026
Standalone HTML article with inline CSS and SVG figures. No external JavaScript or image files are required.

Leave a reply

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