Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 应存储在带有适当标记名称的日期类型列中。标识符应存储在具有适当标记名称的适当类型(通常为整数类型或UUID)的主键列中_Database_Postgresql_Cassandra_Uuid - Fatal编程技术网

Database 应存储在带有适当标记名称的日期类型列中。标识符应存储在具有适当标记名称的适当类型(通常为整数类型或UUID)的主键列中

Database 应存储在带有适当标记名称的日期类型列中。标识符应存储在具有适当标记名称的适当类型(通常为整数类型或UUID)的主键列中,database,postgresql,cassandra,uuid,Database,Postgresql,Cassandra,Uuid,所以不要再玩卡桑德拉玩的那些愚蠢聪明的游戏了 提取日期时间值,将其存储在日期时间列中。Postgres具有出色的日期时间支持。具体来说,您需要将该值存储在SQL标准类型TIMESTAMP和时区的列中。此数据类型表示一个时刻,即时间线上的特定点 Java中表示时刻的等效类型是Instant或OffsetDateTime或ZonedDateTime。JDBC4.2规范只需要支持第二个,令人费解的是,不需要支持第一个或第三个。搜索堆栈溢出以获取更多Java和JDBC信息,因为它已经被多次介绍过了 继续

所以不要再玩卡桑德拉玩的那些愚蠢聪明的游戏了

提取日期时间值,将其存储在日期时间列中。Postgres具有出色的日期时间支持。具体来说,您需要将该值存储在SQL标准类型
TIMESTAMP和时区的列中。此数据类型表示一个时刻,即时间线上的特定点

Java中表示时刻的等效类型是
Instant
OffsetDateTime
ZonedDateTime
。JDBC4.2规范只需要支持第二个,令人费解的是,不需要支持第一个或第三个。搜索堆栈溢出以获取更多Java和JDBC信息,因为它已经被多次介绍过了

继续使用UUID,但仅作为Postgres中新表的指定主键列。您可以告诉Postgres自动生成这些值

将UUID存储为字符

否,不要将UUID存储为文本

时间戳最合适,但我担心时区和碰撞

有时区的
时间戳与没有时区的
时间戳之间有着天壤之别。所以永远不要只说时间戳

Postgres始终以UTC格式存储带时区的时间戳。提交值中包含的任何时区或偏移量信息都将用于调整到UTC,然后丢弃。Java将此类型的值检索为UTC。所以没问题

当使用其他工具时,问题就来了,这些工具具有良好的意图,但有悲惨的缺陷,即在生成文本以显示字段值的同时动态应用默认时区。从Postgres检索到的值始终在UCT中,但其表示形式可能已调整到另一个偏移或区域。避免使用此类工具,或者确保将默认区域设置为UTC本身。所有程序员、DBA和系统管理员在工作时都应该学习使用UTC进行工作和思考

没有时区的时间戳
完全不同。此类型缺少时区或UTC偏移量的上下文。所以这种类型不能代表一个时刻。它有日期和时间,但仅此而已。这当然是模棱两可的。如果这个值是今年1月23日的中午,我们不知道你是指东京的中午,德黑兰的中午,还是托莱多的中午——所有的时刻都非常不同,相隔几个小时。等价物 Java中的类型是
LocalDateTime
。搜索堆栈溢出以了解更多信息

时间被存储为UUID,以避免在相同毫秒内插入行时发生冲突

版本1 UUID跟踪和时间,分辨率高达100纳秒(1/10微秒),前提是主机硬件时钟可以这样做。time类以微秒的分辨率捕获时间(从Java9和更高版本开始)。Postgres以微秒的分辨率存储瞬间。因此,有了Java&Postgres,您将在这方面接近Cassandra

存储当前时刻

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
检索

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
我可以用米尔科/纳秒的分辨率

不,你不能。如今,传统的计算机时钟无法精确跟踪纳秒级的时间

而仅将时间跟踪用作标识符值是一个有缺陷的想法

UUID甚至TimeUUID不必总是增加

你永远不能指望时钟总是在增加。时钟得到调整和重置。计算机硬件时钟没有那么精确。不理解计算机时钟的局限性是卡桑德拉设计中天真和不合理的方面之一

这就是为什么版本1 UUID在当前时刻使用任意小的数字(称为
时钟序列
)的原因,因为当时钟被重置/调整时,当前时刻可能会重复。一个负责任的UUID实现应该注意到时钟的下降,然后增加这个小数字以补偿和避免重复。根据RFC 4122第4.1.5节:

对于UUID版本1,时钟序列用于帮助避免在时钟向后设置或节点ID更改时可能出现的重复

如果时钟设置向后,或者可能设置向后 (例如,当系统断电时),UUID生成器可以 不确定没有生成时间戳大于的UUID 时钟设置为的值,则时钟序列必须 可以改变。如果已知时钟序列的先前值,则 可以直接递增;否则,应将其设置为随机或随机 高质量伪随机值


世界上没有任何东西承诺“总是增加”
。回到我的开场白,卡桑德拉滥用UUID。

Postgres中的
序列类型已被标识栏取代。请参阅:感谢您的回答,但我关心的是如何以高分辨率存储时间,并能够应用关系运算符。我可以在应用程序中生成UUID,而不需要任何插件。我还应该提到,由于某些原因,我不能使用插件!感谢您提供有关标识列的提示和外观极佳的链接,我会查看它。@MePsyDuck-我不知道Cassandra,也不清楚“应用关系运算符”是什么意思。在Postgres中,您有一些强大的选项。例如,生成_series()以获得一个合成记录集,该记录集的间隔为任意间隔,例如每2小时一次。然后左键将数据与之关联。除了你的行(高粒度)DTS值,使用DATE_TRUNC()或EXTRACT将DTS更改为粒度较小的值,如小时等,效果很好。这是一个输入错误。我的用例