---
title: "Nếu database chính là mạng thì sao?"
description: "Một ý nghĩ ập tới trên đường về nhà: Pinata, IPFS, và chuyện tôi bỏ cả một buổi tối để hỏi xem có dựng nổi một cái database mà không cần database không."
date: 2024-10-12
---

Thứ Ba tuần trước, trên đường đi làm về, tôi cứ nghĩ về Pinata, nghĩ trên xe máy thì cũng hơi lạ. Lâu rồi tôi không đụng tới Web3. Có một thời tôi mê nó, dựng vài thứ, pin một đống file lên Pinata, rồi chán, chán cái kiểu chán mọi thứ không còn là câu đố nữa. Chắc cũng khoảng một năm trước.

Pinata pin file lên IPFS. Sản phẩm chỉ có vậy. Bạn đưa nó một file, nó trả lại một CID, và nó giữ một bản trên một cái máy để file lúc nào cũng lấy được. Tôi xài đủ nhiều để biết nó gồ ghề chỗ nào, rồi thôi không để tâm nữa.

Rồi đúng chuyến về hôm đó, câu hỏi hiển nhiên mới ập tới, muộn: khoan đã. Nếu Pinata lưu file của mình rồi trả lại một địa chỉ, thì khác gì database? Database lưu row rồi trả lại key. Pinata lưu blob rồi trả lại CID. Hình dạng gần như y hệt.

Cả đoạn đường về tôi nghĩ mãi về nó. Tới lúc dựng xe, trong đầu đã có nguyên một ý tưởng, kiểu ý tưởng nguy hiểm, nên tôi làm chuyện hợp lý: cãi nhau với một con chatbot về nó suốt hai tiếng.

## Ý tưởng, lúc nó mới tới

Dựng một cái database Web3. Thay vì Postgres trên một server mình thuê, mỗi row nằm trên IPFS. CID là primary key. Đọc thì đụng gateway, ghi thì pin một object mới, còn mạng lo phần replication. Không có server để patch, không có một cái máy nào giữ hết dữ liệu, không có công ty nào tắt được database của mình.

Sức hút không khó thấy. Database bình thường là một cái máy mình sở hữu và phải giữ cho nó sống. Một cái store chống lưng bằng IPFS là một mạng mình gia nhập rồi gần như quên luôn. Nếu tất cả chỉ là địa chỉ trỏ tới nội dung, thì lớp storage không còn là vấn đề của mình nữa, mà chạy database thì thật ra phần lớn là vậy.

Rồi tôi phạm sai lầm: hỏi xem nó có chạy thật không.

## Con chatbot nói gì, và nó đúng ở đâu

Tôi mô tả ý tưởng rồi hỏi nó có vấn đề gì. Nó đưa một danh sách gọn. Bảo mật cá nhân, vì một database đọc được bằng địa chỉ là database ai cũng đọc được bằng địa chỉ. Hạ tầng, vì chính những thứ làm IPFS giỏi storage là những thứ làm nó dở khi làm database. Tốc độ, vì một mạng content-addressed không được dựng cho kiểu query mà database cần. Tôi cãi lại vài điểm, còn lại thì chịu.

Điểm tốc độ chính là điểm giết chết ý tưởng. Database làm nhiều hơn lưu. Nó đánh index, lọc, join, sắp xếp, và trả lời những câu hỏi mà lúc nạp dữ liệu không ai lường trước. IPFS không làm gì trong số đó. Nó lưu một blob dưới một địa chỉ rồi trả blob đó khi mình hỏi địa chỉ. Muốn tìm mọi row có status là pending, mình phải kéo hết blob về rồi dò, mà đó chính là việc database sinh ra để chặn.

Tôi ngồi với điều đó một lúc. Ý tưởng không sống nổi qua cú đó, ít nhất không phải cái hình dạng tôi có trên xe máy. Nhưng cuộc cãi có ích, vì nó biến một cảm giác mơ hồ thành một danh sách lý do cụ thể, mà lý do cụ thể thì làm được. Cảm giác mơ hồ thì không.

## Bài toán quyền riêng tư mới là chỗ thú vị

Bảo mật là điểm tôi cãi lại gay nhất, và đáng viết ra vì tôi sai, còn cái sửa lại mới quan trọng.

Tôi cãi rằng content addressing là bảo mật. Địa chỉ là hash của nội dung, nên ai đổi file thì địa chỉ đổi, và không ai đưa cho mình thứ giả danh thứ khác được. Đúng, và hay thật. Nhưng nó chẳng liên quan gì tới câu hỏi ai được phép đọc.

CID là hash. Biết hash là tôi kéo được file từ bất kỳ node nào giữ nó. Trong luồng đó không có login. Địa chỉ chống sửa đổi cho biết file còn nguyên. Nó không cho biết mình có nên có file đó không. Với một tấm ảnh công khai thì ổn, mà tốt nữa. Với database có bảng users thì thảm họa, và cách chữa không nằm trên mạng. Nó nằm ở mình.

Việc mình thật sự làm là encrypt trước khi pin. Mạng lưu ciphertext, key không bao giờ rời khỏi app, còn CID giờ trỏ tới một blob mà không có key thì không ai đọc được. Cách đó chạy. Nhưng nó cũng có nghĩa mạng không còn biết gì về dữ liệu của mình, cái đó vừa là mục đích vừa là cái giá thật, vì giờ mọi tính năng cần đọc, lọc hay tổng hợp đều phải xảy ra sau khi giải mã, trong code của mình, không có mạng giúp. Quyền riêng tư thì làm được. Có điều nó đẩy hết việc về phía mình, mà đó là một kiểu lặp lại.

## Database mới là phần dễ

Càng nhìn tôi càng thấy ý tưởng ban đầu bị ngược. Tôi coi storage là phần lớn của một cái database, vì storage là phần dễ thấy. Database là cái hộp mình bỏ dữ liệu vào, và một thứ giữ nó ở đó.

Nhưng storage là phần dễ. Cái đĩa nào chẳng lưu được. Thứ làm một cái database thành database là tất cả những gì mình dựng lên trên để khỏi phải đọc hết dữ liệu mỗi lần hỏi. Cái index. Cái query planner. Cái transaction hoặc ăn hoặc không. Cái join nối hai bảng lại mà mình không phải tự viết vòng lặp. Không thứ nào trong đó nằm trên mạng, và không thứ nào chuyển lên mạng được, vì nó chẳng liên quan gì tới việc byte nằm ở đâu. Nó liên quan tới việc mình tìm lại chúng thế nào.

Có thể dựng một thứ mang hình dạng database trên IPFS. Thêm một cái index, thêm một lớp query, thêm một lớp kiểm soát truy cập, thêm một cái cache để mấy lần đọc chậm không giết mình. Mảnh nào cũng dựng được. Nhưng dựng xong thì mình có một database bình thường với một cái mạng ở giữa và một đống bước phụ, còn cái mạng không bỏ đi được phần khó nào. Nó chỉ đổi chỗ mấy byte nằm.

Đó là câu trả lời thật cho câu hỏi từ trên xe máy. Câu hỏi là Pinata với database có cùng một hình dạng không. Chúng chung một hình dạng, cái mà mình bỏ thứ gì vào rồi nhận lại một key. Chúng không chung cái hình dạng quan trọng, cái mà mình hỏi một câu mà dữ liệu chưa bao giờ được thiết kế để trả lời. Pinata chưa bao giờ có hình dạng đó, và nó cũng không giấu. Chỉ là tôi muốn hai hình dạng khớp nhau tới mức thôi nhìn.

Ý tưởng chết rồi, và giờ tôi biết vì sao, đủ rõ để nói ra. Sai lầm là nghĩ storage là phần lớn của một cái database. Storage là phần dễ nhất của database. Phần khó là mọi thứ mình làm với dữ liệu để khỏi phải đọc hết, mà phần đó không chuyển lên mạng được. Có thể dựng một thứ mang hình dạng database trên IPFS nếu thêm một cái index, một lớp query, một lớp kiểm soát truy cập, và một cái cache. Tới đó thì mình đã dựng một database bình thường với thêm mấy bước và một cái mạng ở giữa, dựng thì cũng được mà không phải cái tôi tưởng mình đang dựng.

Nửa còn lại của buổi tối đó, phần thay AWS bằng một cái mạng, là một ý khác và hay hơn. Tôi sẽ viết riêng, vì nó đáng nhiều chỗ hơn tôi dành cho nó ở đây, và nó không đổ như ý này.

Chỗ tôi sai nhiều nhất là cái tâm trạng. Tôi có ý tưởng trên xe máy trong mười phút rồi tưởng mười phút đó có nghĩa gì. Mười phút đó nghĩa là tôi nhận ra hai thứ có chung một hình dạng. Không có nghĩa là hình dạng đó đứng vững, và phải mất một cuộc chat và một buổi tối đọc mới biết nó không đứng. Ý tưởng chỉ là một câu. Mấy lý do nó đổ mới là thứ tôi thật sự thu được, và khác với ý tưởng, chúng đúng.
