- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要将表从Cassandra迁移到PostgreSQL。
我需要迁移的内容:该表具有一个TimeUUID列,用于将时间存储为UUID。该列也用作聚类键。时间存储为UUID,以避免在同一毫秒内插入行时发生冲突。另外,此列涉及where子句(通常为timeUUID between 'foo' and 'bar'
),并且产生了正确的结果。
我需要将其迁移到的位置:我正在迁移到Postgres,因此需要找到合适的替代方法。 PostgreSQL具有UUID数据类型,但是到目前为止,我已经阅读并尝试将它存储为4字节int,但是在带关系运算符的where子句中使用时,UUID类似于String对待。select * from table where timeUUID > 'foo'
将在结果中包含xyz
。
根据我的理解,UUID甚至TimeUUID不必总是增加。因此,与具有相同数据集的Cassandra相比,Postgres产生了错误的结果。
到目前为止,我已经考虑了什么:我考虑将其存储为BIGINT,但是对于时间分辨率(以毫秒为单位),它很容易受到冲突的影响。我可以争取mirco / nano秒的分辨率,但恐怕BIGINT会用尽它。
将UUID存储为CHAR可以防止冲突,但是我将失去在列上应用关系运算符的功能。
TIMESTAMP最适合,但我担心时区和碰撞。
我到底需要什么(tl; dr):
具有较高时间分辨率的某种方式或避免冲突的方式(唯一值生成)。
该列应支持关系运算符,即uuid_col < 'uuid_for_some_timestamp'
。
PS:这是一个Java应用程序。
最佳答案
tl; dr
别再用卡桑德拉语思考了。设计师在设计中做出了一些错误的决定。
将UUID用作identifier。
使用日期时间类型来跟踪时间。
➥请勿将两者混用。
混合两者是Cassandra的缺陷。
卡桑德拉滥用UUID
不幸的是,Cassandra滥用UUID。您的困境显示了他们的做法很不幸。
UUID的目的严格是生成标识符,而无需与其他方法(例如序列号)所需的中央机构进行协调。
Cassandra使用Version 1 UUIDs,它采用当前时刻加上任意小的数字,并与发行计算机的MAC address组合。所有这些数据将构成UUID中的大多数128 bits。
Cassandra做出了糟糕的设计决策,无法及时提取该时刻用于时间跟踪,这违反了UUID设计的意图。 UUID从未打算用于时间跟踪。
UUID标准中有多个替代版本。这些替代方案不一定包含时间。例如,Version 4 UUIDs而是使用从加密强度较高的生成器生成的随机数。
如果要生成版本1 UUID,请安装通常与Postgres捆绑在一起的uuid-ossp插件(“扩展名”)(包装OSSP uuid库)。该插件提供了一些函数,您可以调用这些函数来生成UUID值。
[Postgres]将其存储为4字节int
Postgres将UUID定义为本机数据类型。因此,如何存储这些值实际上与我们无关,在将来的Postgres版本(或其新的可插拔存储方法)中可能会发生变化。您传入一个UUID,然后您将获得一个UUID,这就是我们作为Postgres用户所知道的。另外,很高兴得知Postgres(以其当前的“堆”存储方法)将UUID值有效地存储为128位,而不是效率不高,例如,存储用于规范地显示UUID的十六进制字符串的文本对人类。
请注意,Postgres内置支持存储UUID值,而不生成UUID值。生成值:
有些人使用pgcrypto扩展名(如果已安装在他们的数据库中)。该插件只能生成版本4几乎所有的UUID。
我建议您改为使用uuid-ossp扩展名。这为您提供了多种UUID版本供您选择。
要了解更多信息,请参见:Generating a UUID in Postgres for Insert statement?
至于您的迁移,我建议将“讲真话”作为一般的好方法。日期时间值应存储在带有适当标记名称的日期类型列中。标识符应存储在具有适当标签名称的适当类型(通常为整数类型或UUID)的主键列中。
因此,不要再玩卡桑德拉(Cassandra)玩的愚蠢的聪明游戏了。
提取日期时间值,将其存储在日期时间列中。 Postgres具有出色的日期时间支持。具体来说,您需要将值存储在SQL标准类型TIMESTAMP WITH TIME ZONE
的列中。此数据类型表示时刻,即时间轴上的特定点。
Java中表示时刻的等效类型为Instant
或OffsetDateTime
或ZonedDateTime
。 JDBC 4.2规范仅要求对第二个(而不是第一个或第三个)的支持。在Stack Overflow上搜索有关此Java和JDBC信息的更多信息,因为已经对此进行了很多次讨论。
继续使用UUID,但仅将其用作Postgres中新表的指定主键列。您可以告诉Postgres自动生成这些值。
将UUID存储为CHAR
不,请勿将UUID存储为文本。
TIMESTAMP最适合,但我担心时区和碰撞。TIMESTAMP WITH TIME ZONE
和TIMESTAMP WITHOUT TIME ZONE
之间存在很大的差异。所以永远不要只说时间戳。
Postgres始终在UTC中存储TIMESTAMP WITH TIME ZONE
。提交的值中包含的任何时区或偏移量信息都将用于调整为UTC,然后将其丢弃。 Java将此类型的值检索为UTC。所以没问题。
当使用其他工具时,就会出现问题,这些工具具有很好的意图,但存在可悲的缺陷,即在生成文本以显示字段值时动态应用默认时区。从Postgres检索的值始终在UCT中,但是其显示方式可能已调整为另一个偏移量或区域。避免使用此类工具,或者确保将默认区域设置为UTC本身。所有程序员,DBA和系统管理员都应在工作中学习使用UTC进行工作和思考。TIMESTAMP WITHOUT TIME ZONE
完全不同。此类型缺少时区或从UTC偏移的上下文。因此,这种类型不能代表片刻。它具有日期和时间,仅此而已。这当然是模棱两可的。如果值是今年1月23日中午,我们不知道您是指东京中午,德黑兰中午还是托莱多中午-都是非常不同的时刻,相隔几个小时。等效
Java中的类型是LocalDateTime
。搜索堆栈溢出以了解更多信息。
时间存储为UUID,以避免在同一毫秒内插入行时发生冲突。
如果主机硬件时钟可以做到,则版本1 UUID跟踪和时间的分辨率可以达到100纳秒(1/10微秒)。 java.time类以微秒的分辨率捕获时间(从Java 9和更高版本开始)。 Postgres以微秒的分辨率存储时刻。因此,使用Java&Postgres,您将在这方面与Cassandra保持紧密联系。
存储当前时刻。
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
clock sequence
)的原因,因为当重置/调整时钟时,当前时刻可能会重复。负责任的UUID实现应注意时钟回落,然后递增该小数字以补偿并避免重复。根据RFC 4122第4.1.5节:
关于database - PostgreSQL中支持关系操作的Cassandra的TimeUUID的替代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57673085/
我们有 2 个 cassandra 集群,第一个有旧数据,第二个有新数据。 现在我们想要将旧数据从第一个集群移动或复制到第二个集群。什么是最好的方法来做到这一点以及如何做到这一点? 我们正在使用 DS
我正在考虑安装 OpsCenter 来监控我们在 RackSpace VM 上运行的 24 节点 Cassandra 集群。过去我听说 OpsCenter 减慢了集群速度。我有点担心 OpsCente
假设我有一个复制因子(RF)= 2 的 2 节点集群。 我使用一致性 2 触发插入。当客户端等待响应时,Cassandra 开始写入这 2 个节点。中间一个节点失败,无法完成写入,而另一节点上的写入成
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足 Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以
我在 Cassandra 中有一个表,其中我用 1000 多个条目填充了一些行(每行有 10000 多列)。行中的条目更新非常频繁,基本上只是一个字段(它是一个整数)被更新为不同的值。列的所有其他值保
当Cassandra端有“掉落的突变”时,它是否向调用客户端返回相应的失败?或者即使在服务器端丢弃相应的突变并导致数据丢失,它总是成功响应调用事务的调用客户端? 在一个特定实例中,当我们的 TPS 约
我有一个 Multi-Tenancy 应用程序,其中 tenantId 将成为每个查询的一部分,因此我将其放入所有表的分区键中。 例子: CREATE TABLE users { tenantId t
根据 Datastax 文档,在 Cassandra 中先读后写是一种反模式。 每当我们在 CQLSH 中使用 UPDATE 或使用 Datastax 驱动程序来设置几列(带有 IF 和集合更新)时,
是否有命令或任何方式可以知道 Cassandra 的哪些节点上存储了哪些数据? 我对 Cassandra 很陌生,在谷歌上搜索这个问题并没有多少运气。 谢谢! 最佳答案 您可以使用 nodetool
我们有一个包含 1500 万条记录的表,而我们的表是一个 10 节点的 cassandra 集群。我们有一列有接近 20 个可重复值。是否建议在此列上建立二级索引? 最佳答案 假设在该列上完全均匀分布
Cassandra 发布了它的 technical limitations但没有提到允许的最大列数。是否有最大列数?我需要存储 400 多个字段。这在 Cassandra 中可能吗? 最佳答案 每行的
我想知道当表中有多个非 PK 列时会发生什么。我读过这个例子: http://johnsanda.blogspot.co.uk/2012/10/why-i-am-ready-to-move-to-cq
我有两个关于 Cassandra 查询结果的问题。 当我在 Cassandra 中对表进行“完全”选择(即 select * from table )时,是否保证结果将按分区标记的递增顺序返回? 例如
我无法为 Cassandra 设置 Hector。我已经浏览了 documentation和 Cassandra wiki .这些文档的问题在于,那里的很多信息都已经过时或过时(或者我缺乏知识)。无论
我正在使用 DataStax Enterprise 中 cassandra 中提供的压力测试。如果有人知道的话,我也想要一些关于它和 cassandra 的信息。 - 首先,压力测试使用哪些节点?我的
当我在 CQL 中创建表时,列的顺序是否必须精确 不是 在主键和 中不是 聚类列: CREATE TABLE user ( a ascii, b ascii, c ascii,
我有一张如下表: CREATE TABLE tab( categoryid text, id text, name text, author text, des
我正在尝试学习 Cassandra,但对术语感到困惑。 很多情况下它表示该行存储键/值对。 但是,当我定义一个表时,它更像是声明一个 SQL 表,即;您创建一个表并指定列名和数据类型。 谁能澄清一下?
如何对 cassandra 数据实现审计? 我正在寻找一个开源选项。 cassandra 是否有任何有助于审计的功能? 我可以使用触发器将记录记录到表中吗?我关注了 Triggers示例并且能够将记录
我遇到了一个问题“me.prettyprint.hector.api.exceptions.HUnavailableException:: 可能没有足够的副本来处理一致性级别。”当我有 RF=1 时,
我是一名优秀的程序员,十分优秀!