Cassandra

聊天存檔的 Cassandra 架構設計建議

  • June 17, 2014

我已經閱讀了這篇文章,這是我從中得到的架構。這對我維護使用者狀態的應用程序很有幫助,但是如何擴展它以維護一對一的聊天存檔和使用者之間的關係,關係意味著人們屬於我的特定組。我對此很陌生,需要一種方法。

要求 :

我想將使用者-使用者之間的消息儲存在一個表中,每當使用者想要載入使用者的消息時,我想檢索它們並將其發送給使用者。當使用者請求時,我想檢索來自不同使用者的所有消息給使用者。並且還想儲存使用者類。我的意思是,例如 user1 和 user2 屬於“家庭” user3、user4、user1 屬於朋友等……這個組可以是使用者給定的自定義名稱。

這是我嘗試過的

CREATE TABLE chatarchive (
  chat_id uuid PRIMARY KEY,
  username text,
  body text
)

CREATE TABLE chatseries (
username text,
   time timeuuid,
   chat_id uuid,
   PRIMARY KEY (username, time)
) WITH CLUSTERING ORDER BY (time ASC)

CREATE TABLE chattimeline (
   to text,
username text,
   time timeuuid,
   chat_id uuid,
   PRIMARY KEY (username, time)
) WITH CLUSTERING ORDER BY (time ASC)

以下是我目前擁有的架構,

CREATE TABLE users (
  username text PRIMARY KEY,
  password text
)    

CREATE TABLE friends (
   username text,
   friend text,
   since timestamp,
   PRIMARY KEY (username, friend)
)

CREATE TABLE followers (
   username text,
   follower text,
   since timestamp,
   PRIMARY KEY (username, follower)
)

CREATE TABLE tweets (
   tweet_id uuid PRIMARY KEY,
   username text,
   body text
)
CREATE TABLE userline (
   username text,
   time timeuuid,
   tweet_id uuid,
   PRIMARY KEY (username, time)
) WITH CLUSTERING ORDER BY (time DESC)

CREATE TABLE timeline (
   username text,
   time timeuuid,
   tweet_id uuid,
   PRIMARY KEY (username, time)
) WITH CLUSTERING ORDER BY (time DESC)

不久前我創建了一個聊天程序,可以在 github 上找到

https://github.com/akc42/MBChat

它具有您正在談論的一些特徵。特別是它提供了人們可以以開放方式進入和討論的房間,以及幾個人可以聚在一起討論事情的耳語框。

當人們進入房間或加入耳語時,他們可以看到一些過去的對話。

在進一步解釋模式之前,值得指出的是我有兩種驗證使用者的方法。這是因為正常使用是 smf 論壇的聊天擴展 - 因此使用者已經登錄到論壇,並且他們攜帶相同的身份進行聊天(並且具有來自論壇中成員組的一些特徵)。然而,因此聊天可以在沒有論壇的情況下單獨使用,有一個單獨的使用者數據庫,可以在登錄階段查詢,辨識使用者及其能力。

因此,首先該數據庫位於儲存庫中的 inc/user.sql 中。

BEGIN;

CREATE TABLE users (
 uid integer primary key autoincrement NOT NULL,
 time bigint DEFAULT (strftime('%s','now')) NOT NULL,
 name character varying NOT NULL,
 role text NOT NULL DEFAULT 'R', -- A (CEO), L (DIRECTOR), G (DEPT HEAD), H (SPONSOR) R(REGULAR)
 cap integer DEFAULT 0 NOT NULL, -- 1 = blind, 2 = committee secretary, 4 = admin, 8 = mod, 16 = speaker 32 = can't whisper( OR of capabilities).
 password character varying NOT NULL, --raw password
 rooms character varying, -- a ":" separated list of rooms nos which define which rooms the user can go in
 isguest boolean DEFAULT 0 NOT NULL
);
CREATE INDEX userindex ON users(name);
-- Below here you can add the specific users for your set up in the form of INSERT Statements


-- This list is test users to cover the complete range of functions. Note names are converted to lowercase, so only put lowercase names in here
INSERT INTO users(uid,name,role,cap,password,rooms,isguest) VALUES
(1,'alice','A',4,'password','7',0),
(2,'bob','L',3,'password','8',0),
(3,'carol','G',2,'password','7:8:9',0),
(4,'dave','H',0,'password','10',0),
(5,'eileen','R',8,'password','',0),
(6,'fred','R',16,'password','',0),
(7,'gail','R',0,'password','',0),
(8,'harry','R',0,'password','',1),
(9,'irene','R',32,'password','',0);




COMMIT;
VACUUM;
-- set it all up as Write Ahead Log for max performance and minimum contention with other users.
PRAGMA journal_mode=WAL;

但是,一旦他們登錄,這些憑據就會被複製到正在使用的實際聊天數據庫中

以下是可能對您有所幫助的架構元素(取自該儲存庫的 data/chat.sql 文件)。

首先是開放的房間(實際上並非所有房間都是平等的,有一些限制 - 見評論)

CREATE TABLE rooms (
 rid integer primary key NOT NULL,
 name varchar(30) NOT NULL,
 type integer NOT NULL -- 0 = Open, 1 = meeting, 2 = guests can't speak, 3 moderated, 4 members(adult) only, 5 guests(child) only, 6 creaky door
) ;

INSERT INTO rooms (rid, name, type) VALUES 
(1, 'The Forum', 0),
(2, 'Operations Gallery', 2), --Guests Can't Speak
(3, 'Dungeon Club', 6), --creaky door
(4, 'Auditorium', 3), -- Moderated Room
(5, 'Blue Room', 4), -- Members Only (in Melinda's Backups this is Adults)
(6, 'Green Room', 5), -- Guest Only (in Melinda's Backups this is Juveniles AKA Baby Backups)
(7, 'The Board Room', 1), --various meeting rooms - need to be on users room list
(8, 'Marketing', 1),
(9, 'Engineering',1),
(10, 'IT Dept', 1),
(11, 'Finance', 1);

現在使用者本身是從以前的數據庫(或從論壇並有一個匹配表)結轉過來的

CREATE TABLE users (
 uid integer primary key NOT NULL,
 time bigint DEFAULT (strftime('%s','now')) NOT NULL,
 name character varying NOT NULL,
 role char(1) NOT NULL default 'R',
 rid integer NOT NULL default 0,
 mod char(1) NOT NULL default 'N',
 question character varying,
 private integer NOT NULL default 0,
 cap integer NOT NULL default 0,
 rooms character_varying 
);

但這還不是全部——我還有另一個概念——即對話中的參與者——對話只是一個 ID。

CREATE table wid_sequence ( value integer);
INSERT INTO wid_sequence (value) VALUES (1);

CREATE TABLE participant (
 uid integer NOT NULL REFERENCES users (uid) ON DELETE CASCADE ON UPDATE CASCADE,
 wid integer NOT NULL,
 primary key (uid,wid)
);

沒有一個wid_sequence 表,當有人創建新對話時,我的程式碼會手動增加它 - (我稱之為耳語框,但有時它會變成我所謂的私人房間),然後在對話時在參與者表中記錄到位。

最後,我有一個消息存檔 - 我可以參考並在以後播放(有人進入房間時的最近消息的簡短列表,或者俱有秘書能力的人可以進入房間並獲得列印輸出整個對話——例如會議記錄)。

我認為這張表是您在問題中提到的存檔

架構是

CREATE TABLE log (
 lid integer primary key,
 time bigint DEFAULT (strftime('%s','now')) NOT NULL,
 uid integer NOT NULL,
 name character varying NOT NULL,
 role char(1) NOT NULL,
 rid integer NOT NULL,
 type char(2) NOT NULL,
 text character varying
);

這裡重要的項目是類型欄位。它本質上是對動作和對話的重播,因此我們還可以重播開始的新對話(其中rid然後映射到從 wid_sequence 創建的wid),以及人們進出房間等。

我相信這會讓你知道如何進行。隨意檢查我在 github 上的程式碼,並提出您可能有的任何問題。

作為附言,有一個我沒有提到的名為“參數”的表,它控制著很多事情的工作方式。其中之一是是否需要使用加密。這超出了這個答案的範圍 - 因為它相當複雜 - 但您可能需要考慮您希望私人對話的私密性以及是否應該將它們加密儲存在您的檔案中。

引用自:https://dba.stackexchange.com/questions/68100