고객 지원 문의

이메일로 답장드리며, 보통 이틀 안에 회신합니다.

Google reCAPTCHA가 이 제출을 악용 여부에 대해 확인하며, 이 과정에서 데이터가 Google로 전송됩니다. 스크립트는 이 양식을 열 때만 불러옵니다.

← 전체 글

Three columns left over from Stats4U 2

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
counter rows: 166,436lastdomain15,525firstdomain15,457userdomain2,982166,436

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 a half-filled column reads harder than an empty one

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 step before a schema change on a table like that is a dump that has actually been restored once rather than merely produced. That drill has since been run. Until dropping them is worth doing for its own sake, three unused columns cost nothing but a moment of confusion, and the note described below removes even that.

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.

광고