skip to content

Why can the old store's row count be the new store's row count only when the remapping between them is a bijection?

level: middleimportance: should knowfreq 40%

answer

  1. compare sets by pairing, not by counting
  2. one-sided maps give one-sided bounds
  3. injection bounds above, surjection bounds below
  4. equality needs both directions at once
  5. a merge makes the old count an upper bound

basics

~20 s

A one-sided map gives only an inequality. An injection from old rows into new ones proves the old count is at most the new; a surjection proves it is at least. Only a bijection, both at once, gives equality.

solid answer

~50 s

Counting one set by counting another is an argument about maps, not about arithmetic. If a mapping from old rows to new rows is **injective**, distinct old rows occupy distinct new rows, so `old <= new`. If it is **surjective**, every new row is claimed by at least one old row, so `old >= new`. A **bijection** asserts both and therefore gives `old = new` — you may count either side and quote the other. That is why the reconciliation step of a migration is really a check of two properties, and the two ways it fails are different: a merging remap loses injectivity, so the old count becomes an upper bound and the new store legitimately holds fewer rows; rows minted in the new store during the cutover break surjectivity from the old side, so the new count runs ahead. The technique generalises: when a set is awkward to count, exhibit an exact pairing with one that is easy, and count that instead.

go deeper

for a junior

Hold on to the shape: pairing things off one for one is what makes two collections the same size. If some pair up but others are left over, you only learn which side is bigger.

for a middle

State both inequalities with their directions and say which property gives each. Then apply it to a reconciliation: what a shortfall in the new store means versus a surplus.

for a senior

Use the direction of the gap as a diagnostic, insist on a consistent snapshot, and explain why matching totals are weak evidence when a merge and an insert can cancel out.

for a principal

Decide what the platform actually promises about row parity across a migration, what reconciliation the organisation will pay to run at scale, and which discrepancies are accepted as designed rather than investigated.

## Sizes are compared by maps, not by counting For small finite sets you can count both sides and compare. The general tool, and the one an interviewer is probing, is the map between them. Three statements carry all of it. | What you can exhibit from A to B | What it proves | Reading it in the migration | |---|---|---| | An injection | size of A is at most size of B | Distinct old rows land on distinct new rows, so the new store holds at least as many | | A surjection | size of A is at least size of B | Every new row has at least one old source, so the old store holds at least as many | | A bijection | the two sizes are equal | Each old row pairs with exactly one new row and vice versa; either count answers for both | The inequalities point in opposite directions because they constrain opposite ends. Injectivity forbids two inputs from sharing an output, so outputs cannot run short. Surjectivity forbids an output from going unclaimed, so inputs cannot run short. Neither alone gives you equality, and asserting equality from one of them is the defect this question is built to catch. ## The reconciliation step, restated Comparing row counts after a migration is not a sanity check bolted on at the end; it is the test of exactly these two properties. When the counts disagree, the direction of the disagreement tells you which property failed: 1. **The new store holds fewer rows.** Injectivity is gone somewhere: two or more old rows collapsed onto one. The old count is now an upper bound, and the gap is the number of collisions. 2. **The new store holds more rows.** Some new rows have no old source — records created after the cutover, a backfill, or a row split into several. The remap is not surjective onto the live set, and the old count is a lower bound. 3. **The counts match but the contents do not.** Two errors in opposite directions cancelled: a merge and a stray insert of equal size. This is why matching totals are weak evidence on their own, and why a comparison keyed on the identifiers beats a comparison of cardinalities. ## Counting by bijection as a technique The same idea works far outside migrations. When a set is awkward to enumerate, pair it exactly with one that is easy and count the easy one. Two conditions make the argument sound, and both are routinely fudged: - The pairing must be **defined on every element** of the hard set, not just the ones you looked at. - It must be **exact in both directions** — one partner each way. A correspondence that is merely "roughly one to one" proves nothing, and a correspondence that is one-to-one but leaves partners spare proves an inequality only. A common variant that is genuinely useful in review: to show a de-duplicated export has exactly as many rows as there are accounts, do not count both and compare. Exhibit the pairing — each exported row names one account, each account appears exactly once — and the equality follows without either count being trusted. ## Why the pairing, not the counting, is the definition For finite sets a bijection is a convenience. For infinite ones it is the **definition** of having the same size, and that is where intuition breaks in a way worth knowing about. Under this definition a proper subset can have the same size as the whole: the even positive integers pair off with all the positive integers (double each one), so the two sets are the same size even though one sits strictly inside the other. Nothing is wrong; it is simply that "strictly contains" and "is bigger than" stop coinciding once the sets are infinite, and the pairing is the notion that survives. That is also the bridge to the next question in this material: if a pairing with the positive integers is what "countable" means, then a set for which no such pairing can exist is genuinely, structurally larger — not merely large. ## Where the argument silently fails in practice - **Claiming equality from an injection.** The most common error. You have an upper bound; say so. - **Counting against a moving target.** A live store changes under the query, so both counts must come from a consistent snapshot or the comparison is noise. - **Pairing the wrong sets.** Comparing all old rows against non-deleted new rows, or including soft-deleted records on one side only, produces an honest count of the wrong thing. - **Trusting equal totals.** Equal cardinalities are consistent with a merge and an unrelated insert of the same size, so where the stakes justify it, reconcile on identifiers rather than on totals.

  • After a merging migration the new store has fewer rows. Which bound does the old count give you?
    An upper bound. A merge is a non-injective map, so several old rows can share one new row and the new count can only be smaller or equal. The size of the gap is the number of rows lost to collisions, which makes it a usable measurement rather than just a failed check: if the merge was intended, the gap should equal the number of duplicate groups you expected, and any excess is an unplanned collision worth chasing.
  • The counts match exactly. Does that prove the remapping is a bijection?
    No. Equal totals are consistent with errors that cancel — a merge that lost two rows plus a backfill that added two. Equal cardinalities follow from a bijection but do not imply one, since the argument only runs in one direction. To get the stronger claim, reconcile on identifiers: check that every old identifier has a distinct partner and that every new row is claimed, which is the pairing itself rather than a consequence of it.
  • Why can a proper subset of an infinite set have the same size as the whole set?
    Because for infinite sets, same size is defined as the existence of a bijection, and one exists here: pair each positive integer with its double, and the evens match all the positive integers exactly. Containment and size stop coinciding once the sets are infinite. For finite sets no such pairing can exist, which is why the subset intuition works there and only there.

saying these in an interview costs you the question

  • Claims equal sizes from a one-to-one map alone
  • Gets the bound backwards, calling the merged count a lower bound
  • Treats matching row totals as proof the mapping is a bijection
  • Counts two live stores without a consistent snapshot
  • Says a proper subset must always be strictly smaller
  • Compares counts over sets defined differently on each side