Contact support

We reply by e-mail, usually within two days.

Google reCAPTCHA checks this submission against abuse; data is sent to Google. The script loads only once you open this form.

← All posts

The columns nothing writes

The main counter table here has 166,436 rows and a number of columns that look like they matter. Three of them are lastdomain, firstdomain and userdomain. They hold data:

lastdomainnot empty in 15,525 rows
firstdomainnot empty in 15,457 rows
userdomainnot empty in 2,982 rows

Nothing writes them. No statement anywhere in the codebase sets any of the three. The values are from the previous generation of this service, frozen at whatever they were when it stopped running, and every row created since is empty.

Why this is worse than an empty column

An entirely empty column is obviously dead. Nobody builds on it, nobody reports from it, nobody spends an afternoon wondering what it means.

A column that is populated for 9 % of rows is a trap. It looks like a field that is sometimes filled and sometimes not — which is a completely ordinary thing for a column to be. Anyone finding it reasonably concludes there is a rule deciding when it gets set, and starts looking for the rule. There isn't one.

And the stale values are not tucked away on dormant rows where they could do no harm. Of the rows carrying a lastdomain, 1,613 belong to counters that were still being updated this year. A live counter with a domain recorded a decade ago looks exactly like a live counter with a current one.

Worse, the data is plausible. These are domains, they look like the domains of counters, and a query joining on them returns rows. It would answer a question about a web that has moved on.

How to tell, quickly

Grep for writes, not for the name. A column name appears in SELECT lists, in schema dumps, in old migrations, in comments — all of which prove nothing. What settles it is whether any INSERT or UPDATE mentions it. That search takes a minute and it is conclusive in a way that reading around the code is not.

The second check is the data itself: if the newest row holding a value is years old, the column is a fossil regardless of what the code appears to say.

Why they are still there

Dropping a column is cheap and it is not free. Every one of these rows belongs to somebody's counter, some of them running continuously since 2006, and the safe operation before a schema change on a table like that is a dump you have actually restored once rather than merely produced. Until that is worth doing for its own sake, three unused columns cost nothing but confusion.

So they are documented instead. There is nowhere obvious to put that note — the schema of this database exists only in the running database, not in any file in the repository — so it went where somebody would actually trip over it: in the class that reads a counter row, right where the columns come past. A note in a file nobody opens is not documentation. It converts a trap into a footnote only if it sits on the path.

Advertisement