【问题标题】:Inserting arbitrary columns in Cassandra using CQL3使用 CQL3 在 Cassandra 中插入任意列
【发布时间】:2013-06-30 14:57:01
【问题描述】:

在 CQL3 之前,可以插入任意列,例如以日期命名的列:

cqlsh:test>CREATE TABLE seen_ships (day text PRIMARY KEY)
                WITH comparator=timestamp AND default_validation=text;
cqlsh:test>INSERT INTO seen_ships (day, '2013-02-02 00:08:22')
                VALUES ('Tuesday', 'Sunrise');

Per this post CQL3 中的情况似乎有所不同。是否仍然可以插入任意列?这是我失败的尝试:

cqlsh:test>CREATE TABLE seen_ships (
    day text,
    time_seen timestamp,
    shipname text,
    PRIMARY KEY (day, time_seen)
);

cqlsh:test>INSERT INTO seen_ships (day, 'foo') VALUES ('Tuesday', 'bar');

我在这里得到Bad Request: line 1:29 no viable alternative at input 'foo'

所以我尝试了一个稍微不同的表,因为这可能是复合键的限制:

cqlsh:test>CREATE TABLE seen_ships ( day text PRIMARY KEY );
cqlsh:test>INSERT INTO seen_ships (day, 'foo') VALUES ('Tuesday', 'bar');

再次使用Bad Request: line 1:29 no viable alternative at input 'foo'

我在这里错过了什么?

【问题讨论】:

    标签: cassandra cql cql3


    【解决方案1】:

    Datastax 博客上有一篇关于此的好博文:http://www.datastax.com/dev/blog/does-cql-support-dynamic-columns-wide-rows

    答案是肯定的,CQL3 支持动态列,只是它在早期版本的 CQL 中的工作方式不同。我不太了解您的示例,您将日期戳与字符串混合在一起,我也看不到它在 CQL2 中的工作方式。如果我理解正确,您想制作一个船舶目击事件的时间线,其中分区键(行键)是日期,每个目击事件都是时间/名称对。这是一个建议:

    CREATE TABLE ship_sightings (
      day TEXT,
      time TIMESTAMP,
      ship TEXT,
      PRIMARY KEY (day, time)
    )
    

    然后你插入条目

    INSERT INTO ship_sightings (day, time, ship) VALUES ('Tuesday', NOW(), 'Titanic')
    

    但是,您可能应该使用 TIMEUUID 而不是 TIMESTAMP(主键可以是 DATE),否则您可能会添加两个具有相同时间戳的目击事件,并且只有一个会存活。

    这是一个宽行的例子,但是还有动态列的问题,这不完全一样。这是 CQL3 中的一个示例:

    CREATE TABLE ship_sightings_with_properties (
      day TEXT,
      time TIMEUUID,
      ship TEXT,
      property TEXT,
      value TEXT,
      PRIMARY KEY (day, time, ship, property)
    )
    

    你可以这样插入:

    INSERT INTO ship_sightings_with_properties (day, time, ship, property, value)
    VALUES ('Sunday', NOW(), 'Titanic', 'Color', 'Black')
    # you need to repeat the INSERT INTO for each statement, multiple VALUES isn't
    # supported, but I've not included them here to make this example shorter
    VALUES ('Sunday', NOW(), 'Titanic', 'Captain', 'Edward John Smith')
    VALUES ('Sunday', NOW(), 'Titanic', 'Status', 'Steaming on')
    VALUES ('Monday', NOW(), 'Carapathia', 'Status', 'Saving the passengers off the Titanic')
    

    这种动态列的缺点是属性名称将被存储多次(因此,如果您连续有一千次目击事件,并且每个目击事件都有一个名为“Captain”的属性,则该字符串会被保存一千次) .磁盘压缩消除了大部分开销,而且大部分时间都无需担心。

    最后是关于 CQL3 中集合的说明。它们是一个有用的功能,但它们不是实现宽行或动态列的方法。首先,它们有 65536 个项目的限制,但 Cassandra 无法强制执行此限制,因此如果添加太多元素,您以后可能无法读取它们。集合主要用于小型多值字段——典型示例是地址簿,其中每一行都是一个条目,其中条目只有一个名称,但有多个电话号码、电子邮件地址等。

    【讨论】:

    • 多次调用“NOW()”不会创建不同的值吗?因此每个泰坦尼克号物品的钥匙都会不同?
    • 在这种情况下,我们希望值不同,它们是不同事件的 ID。但是,IIRC Cassandra 和大多数数据库将为每个语句评估一次 NOW() 的值(这并不意味着 ID 相同,NOW() 返回一个 TIMEUUID,它是唯一的,但还包含一个时间戳,所以NOW()NOW() 在同一语句中将创建两个不同的TIMEUUID 值,它们具有相同的时间分量)。
    【解决方案2】:

    这不是真正的动态列,但大多数时候您可以摆脱收藏。使用 Map 列,您可能会存储一些动态数据

    【讨论】:

    • -1 怎么不是“真正的动态”栏目?没有提供解释。并且收集对于具有大范围的动态数据来说是一个糟糕的替代品。
    猜你喜欢
    • 1970-01-01
    • 2014-03-09
    • 2013-08-09
    • 2013-05-15
    • 2015-05-06
    • 2013-02-07
    • 2016-07-06
    • 2012-06-07
    • 1970-01-01
    相关资源
    最近更新 更多