데이터베이스가 나를 속이고 있다는 사실을 깨닫기 전까지, 나는 비교 테이블을 만드는 데 수개월을 허비했다.

인터페이스는 괜찮아 보였다. 깔끔한 행, 정돈된 체크 표시, 도구가 부족한 부분에는 빨간색 X 표시. 방문자들은 테이블을 스크롤하며 가끔 클릭하기도 했다. 하지만 표면 아래에서는 스키마가 모든 결론을 조용히 왜곡하고 있었다. 나는 잘못된 데이터 위에 아름다운 UI를 구축한 셈이었다.

불리언(Boolean)의 함정

비교 페이지는 보통 뻔한 패턴으로 시작한다. 행은 기능, 열은 제품으로 구성된 그리드를 만들고, 모든 셀에 불리언(boolean) 값을 넣는다. True는 해당 기능이 있다는 뜻이고, False는 없다는 뜻이다. 한동안은 이것이 질서 정연하게 느껴진다. 하지만 두 개의 프로젝트 관리 도구, 세 개의 클라우드 데이터베이스, 혹은 네 개의 API 게이트웨이를 비교하려고 하면 그리드는 반란을 일으키기 시작한다.

불리언 셀은 뉘앙스를 담을 수 없다. 셀에 'false'라고 적혀 있다면, 그것은 완전히 다른 다섯 가지 의미를 가질 수 있다. 도구에 정말로 해당 기능이 없을 수도 있다. 혹은 다른 메커니즘을 통해 동일한 문제를 해결하고 있을 수도 있다. 기능은 존재하지만 엔터프라이즈 유료 플랜 뒤에 숨겨져 있을 수도 있다. 혹은 미처 발견하지 못한 플러그인이 필요할 수도 있다. 아니면 단순히 확인하는 것을 잊어버려서, 빨간색 X가 본인의 불확실성을 대신하는 자리 표시자(placeholder)일 뿐일 수도 있다.

이것이 중요한 이유는 사용자들이 값비싼 결정을 내리기 위해 비교 그리드를 신뢰하기 때문이다. CLI 기반 도구에 '실시간 협업 기능 없음'이라고 표시할 때, 당신은 '라이브 커서 공유 기능이 없다'는 뜻으로 말했을지 모른다. 하지만 그 도구는 아마도 브랜치 기반 워크플로우와 리뷰 큐를 사용하여 정확히 동일한 결과를 얻고 있을 것이다. 이를 'false'로 표시하는 것은 설계상의 선택을 결함으로 격하시키는 일이다. 이런 식으로 20개의 기능을 처리한다면, 당신은 두 도구를 비교한 것이 아니라 그중 하나가 고장 났다고 선언한 셈이다.

불리언 스키마는 또한 사용자의 니즈가 아닌 공급업체의 용어로 생각하도록 당신을 길들인다. 만약 행의 이름이 카테고리 선두 주자의 이름을 빌려온 것이라면, 결국 모든 경쟁사가 'Workspaces'를 가지고 있는지 묻게 된다. Notion이 그것을 'Workspaces'라고 부르기 때문이다. 다른 도구는 이를 'Projects'라고 부른다. 세 번째 도구는 전용 컨테이너가 아예 없지만, 동일한 격리 수준을 달성할 때까지 개별 파일에 권한을 부여할 수 있게 한다. 당신이 정한 행 이름은 모든 제품을 선두 주자의 사고 모델에 강제로 끼워 맞추게 되며, 이는 시장의 거물에게는 편리할지 몰라도 다른 모든 이들에게는 불공평하다.

상태를 나타내는 더 나은 어휘

해결책은 데이터 타입 자체에서 시작된다. 불리언을 저장하는 것을 멈춰라. 명확한 어휘를 가진 상태(status) 필드를 저장하라.

다음 여섯 가지 상태를 고려해 보라.

Full은 도구가 우회 방법이나 추가 구매 없이 작업을 처리할 수 있음을 의미한다.

Partial은 일부만 처리하거나, 복잡한 설정을 마친 후에야 처리할 수 있음을 의미한다. 대부분의 비교 테이블이 부정확함을 숨기는 지점이 바로 여기다. 암호화를 제공하지만 저장 시(at rest)에만 해당한다면, Full이 아니라 Partial로 분류해야 마땅하다.

Different Model은 문제가 해결되기는 하지만, 카테고리 선두 주자가 해결하는 방식과는 다름을 의미한다. 브랜치와 리뷰 기능을 갖춘 CLI 도구가 여기에 해당한다. 단일 풀링된 연결(single pooled connection) 대신 읽기 복제본(read replicas)을 사용하는 데이터베이스도 마찬가지다. 이 상태는 경쟁사를 모방하지 않았다고 해서 제품의 설계를 벌주는 대신, 그 설계의 지능을 보존해 준다.

Not Applicable은 개념 자체가 해당 유형의 도구에는 적용되지 않음을 의미한다. 서버리스 함수 플랫폼은 가상 머신처럼 지속적인 로컬 스토리지가 필요하지 않다. 여기에 억지로 'false'를 넣는 것은 카테고리를 혼동하는 것이다.

Absent는 확인해 보았으나 해당 기능이 정말로 없음을 의미한다. 우회 방법도, 플러그인도, 대안 워크플로우도 없다. 격차가 실재하는 것이다.

Unknown은 아직 확인하지 않았음을 의미한다.