自动增量 ID 在 Cassandra 或任何其他分布式数据库中并不真正起作用。
为什么?假设您有三个节点。两个节点同时收到对同一张表的写请求。一个检查表的最大 ID,并获得 2544 的(示例)响应。在写入新行之前,另一个节点执行相同的过程,也得到 2544。现在您有两行插入 2545,而在 Cassandra 中,最后一次写入“获胜”,因此您将输掉第一次写入。
因此,这也是为什么在 Cassandra 中将先读后写方法视为反模式的原因。正如 Stefan 建议的那样,TimeUUID 提供了解决此问题的方法。
在 Cassandra 中,您需要设计表以适应您的查询模式。我听到的是,您想要检索最近更新的 100 名员工。我会创建一个特定的表来提供服务:
CREATE TABLE employee_updates (
datebucket text,
record_id timeuuid,
name text,
address text,
PRIMARY KEY (datebucket,record_id))
WITH CLUSTERING ORDER BY (record_id DESC);
现在当您查询此表的最后 100 条记录时:
SELECT * FROM employee_udpates WHERE datebucket='20160309' LIMIT 100;
您可以获得当天最近的 100 条记录。
注意:如果“天”对于您的解决方案来说过于细化(每天只有少数员工记录会更新),那么请随意将其扩大到更适用的范围。
更新:
如果我想上一个最新的 100 条记录,即 801 到 900 怎么办
这个解决方案实际上确实有办法“分页”浏览结果。
让我们在表格中插入一些行:
> INSERT INTO employee_updates (datebucket, record_id , address , name ) VALUES ('20160309',now(),'123 main st.','Bob Kerman');
> INSERT INTO employee_updates (datebucket, record_id , address , name ) VALUES ('20160309',now(),'456 Gene ave.','Bill Kerman');
> INSERT INTO employee_updates (datebucket, record_id , address , name ) VALUES ('20160309',now(),'34534 Water st.','Jebediah Kerman');
> INSERT INTO employee_updates (datebucket, record_id , address , name ) VALUES ('20160309',now(),'843 Rocket dr.','Valentina Kerman');
> INSERT INTO employee_updates (datebucket, record_id , address , name ) VALUES ('20160309',now(),'33476 Booster way','Isabella Kerman');
> INSERT INTO employee_updates (datebucket, record_id , address , name ) VALUES ('20160309',now(),'43 Solid Rocket pl.','Helcine Kerman');
现在让我选择今天最近的前 3 个:
> SELECT datebucket, record_id, dateof(record_id), name
FROm employee_updates WHERE datebucket='20160309' LIMIT 3;
datebucket | record_id | system.dateof(record_id) | name
------------+--------------------------------------+--------------------------+------------------
20160309 | 511f9150-e5db-11e5-a4ba-a52893cc9f36 | 2016-03-09 09:43:02+0000 | Helcine Kerman
20160309 | 2f9f3670-e5db-11e5-a4ba-a52893cc9f36 | 2016-03-09 09:42:06+0000 | Isabella Kerman
20160309 | 23b0dc60-e5db-11e5-a4ba-a52893cc9f36 | 2016-03-09 09:41:46+0000 | Valentina Kerman
(3 rows)
由于我已按 DESCending 顺序将该表聚集在 record_id 上,因此只需查询比我读到的最后一条记录少的 record_id 即可获得接下来的 3 条记录。在这种情况下,那就是23b0dc60-e5db-11e5-a4ba-a52893cc9f36:
> SELECT datebucket, record_id, dateof(record_id), name
FROm employee_updates WHERE datebucket='20160309'
AND record_id < 23b0dc60-e5db-11e5-a4ba-a52893cc9f36 LIMIT 3;
datebucket | record_id | system.dateof(record_id) | name
------------+--------------------------------------+--------------------------+-----------------
20160309 | 16400100-e5db-11e5-a4ba-a52893cc9f36 | 2016-03-09 09:41:23+0000 | Jebediah Kerman
20160309 | 0b239cf0-e5db-11e5-a4ba-a52893cc9f36 | 2016-03-09 09:41:05+0000 | Bill Kerman
20160309 | 00d648b0-e5db-11e5-a4ba-a52893cc9f36 | 2016-03-09 09:40:47+0000 | Bob Kerman
(3 rows)