這是一系列關於構建“即時訊息”應用的新貼文。你應該對這類應用並不陌生。有了它們的幫助,我們才可以與朋友暢聊無忌。Facebook Messenger、WhatsApp 和 Skype 就是其中的幾個例子。正如你所看到的那樣,這些應用允許我們傳送圖片、傳輸視訊、錄製音訊、以及和一大幫子人聊天等等。當然,我們的教學應用將會盡量保持簡單,只在兩個使用者之間傳送文字訊息。
我們將會用 CockroachDB 作為 SQL 資料庫,用 Go 作為後端語言,並且用 JavaScript 來製作 web 應用。
這是第一篇貼文,我們將會講述資料庫的設計。
CREATE TABLE users ( id SERIAL NOT NULL PRIMARY KEY, username STRING NOT NULL UNIQUE, avatar_url STRING, github_id INT NOT NULL UNIQUE);
顯然,這個應用需要一些使用者。我們這裡採用社交登入的形式。由於我選用了 GitHub,所以這裡需要儲存一個對 GitHub 使用者 ID 的參照。
CREATE TABLE conversations ( id SERIAL NOT NULL PRIMARY KEY, last_message_id INT, INDEX (last_message_id DESC));
每個對話都會參照最近一條訊息。每當我們輸入一條新訊息時,我們都會更新這個欄位。我會在後面新增外來鍵約束。
… 你可能會想,我們可以先對對話進行分組,然後再通過這樣的方式獲取最近一條訊息。但這樣做會使查詢變得更加複雜。
CREATE TABLE participants ( user_id INT NOT NULL REFERENCES users ON DELETE CASCADE, conversation_id INT NOT NULL REFERENCES conversations ON DELETE CASCADE, messages_read_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (user_id, conversation_id));
儘管之前我提到過對話只會在兩個使用者之間進行,但我們還是採用了允許向對話中新增多個參與者的設計。因此,在對話和使用者之間有一個參與者表。
為了知道使用者是否有未讀訊息,我們在訊息表中新增了“讀取時間”(messages_read_at
)欄位。每當使用者在對話中讀取訊息時,我們都會更新它的值,這樣一來,我們就可以將它與對話中最後一條訊息的“建立時間”(created_at
)欄位進行比較。
CREATE TABLE messages ( id SERIAL NOT NULL PRIMARY KEY, content STRING NOT NULL, user_id INT NOT NULL REFERENCES users ON DELETE CASCADE, conversation_id INT NOT NULL REFERENCES conversations ON DELETE CASCADE, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), INDEX(created_at DESC));
儘管我們將訊息表放在最後,但它在應用中相當重要。我們用它來儲存對建立它的使用者以及它所出現的對話的參照。而且還可以根據“建立時間”(created_at
)來建立索引以完成對訊息的排序。
ALTER TABLE conversationsADD CONSTRAINT fk_last_message_id_ref_messagesFOREIGN KEY (last_message_id) REFERENCES messages ON DELETE SET NULL;
我在前面已經提到過這個外來鍵約束了,不是嗎:D
有這四張表就足夠了。你也可以將這些查詢儲存到一個檔案中,並將其通過管道傳送到 Cockroach CLI。
首先,我們需要啟動一個新節點:
cockroach start --insecure --host 127.0.0.1
然後建立資料庫和這些表:
cockroach sql --insecure -e "CREATE DATABASE messenger"cat schema.sql | cockroach sql --insecure -d messenger
這篇貼文就到這裡。在接下來的部分中,我們將會介紹「登入」,敬請期待。