Sybase中神秘的'timestamp'数据类型是什么?

时间:2010-08-17 08:39:47

标签: sql sybase

我最近在Sybase数据库中发现了一个使用“timestamp”类型列的表。如果我使用这个神秘的时间戳数据类型创建一个表

create table dropme (
    foo timestamp,  
    roo int null
)
insert into dropme (roo) values(123)
insert into dropme (roo) values(122)
insert into dropme (roo) values(121)
select * from dropme
go

我从'select * from dropme'获得以下内容:

 foo                  roo
 -------------------- -----------
   0x000100000e1ce4ea         123
   0x000100000e1ce4ed         122
   0x000100000e1ce509         121

0x000100000e1ce4ea对我来说看起来不是很时间。另外,我从'sp_help timestamp'看到了这个输出:

 Type_name Storage_type Length Prec Scale Nulls Default_name Rule_name Access_Rule_name Identity
 --------- ------------ ------ ---- ----- ----- ------------ --------- ---------------- ----------
 timestamp varbinary         8 NULL  NULL     1 NULL         NULL      NULL                   NULL

我的问题如下

  1. 什么是时间戳?
  2. 它与时间或日期有任何关系吗?
  3. 我可以将其转换为日期时间吗?
  4. 如果不是时间或日期,你会用它做什么?

5 个答案:

答案 0 :(得分:16)

什么是时间戳?

timestamp数据类型定义为

varbinary(8) null

它与时间或日期有任何关系吗?

没有。这个名字选择不当。

我可以将其转换为日期时间吗?

没有

如果不是时间或日期,您使用它做什么?

每次插入或更新带有时间戳列的行时,时间戳列都会自动更新。请注意,实际上有两种时间戳。 TIMESTAMPCURRENT TIMESTAMP。不同之处在于CURRENT TIMESTAMP仅在插入时设置。

Sybase documentation停在那里让我想知道为什么f * rainbow!* k任何人都会使用数据类型时间戳。令人高兴的是,我发现了一些other discussions,并在实现乐观并发控制时推断出它的使用。

并发控制是一种确保多个事务可以在同一时间/大约同时运行并且仍然可以生成正确数据的方法。 乐观并发控制是一种并发控制方法,它假定多个事务可以完成而不会相互干扰。即不需要锁定。维基百科描述了以下算法:

  1. 记录交易开始时的日期/时间标记
  2. 读取/更新数据
  3. 检查另一个交易是否修改了数据
  4. 提交或回滚
  5. Sybase的timestamp数据类型可以在此算法的步骤1和3中使用,而不是使用日期/时间。但在我看来,它并不像使用datetime数据类型节省了很多工作。我想它可能表现得更好。

答案 1 :(得分:8)

最近,有人问我是否可以将TIMESTAMP SYBASE IQ 数据类型转换为DATE;我总是避免这种数据类型,因为它是黑暗的。经过几个小时的阅读SYBASE documentation并进行一些测试,这是我的结论:

TIMESTAMP:

  • 是12位数,存储为BINARY(这可能会有所不同 关于环境)
  • 它表示自1970年1月1日以来的微秒值
  • Sybase不包含转换它们的直接功能
  • 每次记录INSERTED时都会自动建立

以下是将TIMESTAMP转换为DATE的SQL语句:

SELECT timestamp as TS, CONVERT(decimal, timestamp) as TS_IN_MS,
   CONVERT(date, dateadd(SS, CONVERT(int, SUBSTRING(CONVERT(varchar,                     
      CONVERT(decimal, timestamp)), 1, 9)), '1/1/1970'), 123)  as TS_AS_DATE  
   FROM TheTable

转换可以通过使用如下的在线EPOCH转换器来证明:

注意:对于 SYBASE ASE ,TIMESTAMP类型不是有效的UNIX-EPOCH

答案 2 :(得分:2)

(这是一个单独的问题Answers to the mysterious Sybase ASE 'timestamp' datatype questions作为一个单独的问题{{3}}发布的,没有代表将其添加到此处。我已将其复制为社区Wiki,因为我不想为此声明信誉但是它应该在这里)

回答问题1:'时间戳到底是什么?'

•Sybase ASE数据库的时间戳集中保存在该数据库的内部内存表“dbtable”中 - 此表是在数据库联机时构建的。您可以通过选择@@ dbts来查询当前的数据库时间戳 - 请注意,此varbinary(8)'数据库'时间戳值取决于平台,即受大和小端的影响。

•每个用户表可以有一个时间戳列,用于保存给定行的INSERT / UPDATE的“数据库”时间戳值。成功完成TSQL DML命令后,所有'Table'时间戳列值都由ASE自动维护(就像标识列一样)。但是,与“数据库”时间戳不同,“表”时间戳值与平台无关,因为无论O / S平台的字节顺序如何,它们始终以Big-endian字节顺序保留(有关详细信息,请参阅下面的详细信息)。


回答问题2:“它与时间或日期有任何关系吗?”

不,“数据库”时间戳和页面“本地”时间戳中的值不反映实际日期/时间。


回答问题3:'我可以将其转换为日期时间吗?'

不,您无法将其网页的“数据库”时间戳或“本地”时间戳转换为日期/时间值。


回答问题4:'如果不是时间或日期,你用它做什么?'

•每当修改或创建数据库中的页面时,“数据库”时间戳加1,而受影响页面的“本地”时间戳(在其页眉中)随后与该点的“数据库”时间戳同步时间。

•与当前时间的“数据库”时间戳进行比较时,数据库页面的“本地”时间戳反映了该页面上次更新或首次创建的相对年龄;因此,ASE可以告知数据库中所有页面的更新/创建的时间顺序。

•应用程序可以以与标识列类似的方式使用“表”时间戳列,以查找最近或最近最少插入/更新的行,而不管行的键值。


进一步的信息,警告和警告: -

(1)'数据库'和'本地'时间戳存储在3个部分中,并且依赖于OS平台字节顺序。 例如0xHHHH 0000 LLLLLLLL

  • 2字节高阶 - 0xHHHH
  • 2字节填充符 - 0x0000
  • 4字节低位 - 0xLLLLLLLL

(2)用户'Table'时间戳也存储在3个部分中,但始终处于Big-endian方向。 例如0x0000 HHHH LLLLLLLL

  • 2字节填充符 - 0x0000
  • 2字节高阶 - 0xHHHH
  • 4字节低位 - 0xLLLLLLLL

(3)数据库时间戳保存在给定数据库的内存系统表dbtable中(在数据库联机时创建)。

  • Note1 -'Table'时间戳列值与数据库表的数据和/或索引页中的其他列值一样,其中定义了timestamp列。
  • 注意2 - 请注意,SELECT @@ dbts查询当前数据库的“数据库”时间戳将返回其十六进制表示形式,该表示形式受OS平台的Endianness的影响。
  • 注3 - 相反,通过DBCC dbtable(不推荐)查询“数据库”时间戳会返回其Big-endian十六进制表示,因此,它与平台无关。
  • 警告 - 当给定数据库的“数据库”时间戳接近其最大限制(即0xFFFF,0xFFFFFFFF)时,可能需要十年或更长时间才能达到此点,具体取决于数据库中插入/更新操作的频率,ASE将发出警告,不可能进一步插入/更新 - 唯一的选择是使用BCP从所有对象导出数据(加上通过sp_showtext的存储过程),删除数据库,再次创建它(使用新的近zer '数据库'时间戳)并导入数据(和存储过程)。

仅供参考 - 以上答案,提示和我在Sybase工作时提示是真实准确的,现在工作的是SAP,他拥有产品ASE。

答案 3 :(得分:1)

假设您将数据提取到应用程序中。做完之后你想确保这条记录已经改变,直到你得到(低级别!)?

在这种情况下,您应该有一个 TIMESTAMP 列。首先,您必须保存该列。在更新数据之前,您应该比较每个值以确保。

这就是存在这种数据类型的原因!

答案 4 :(得分:-2)

在Sybase ASE中,时间戳对于同一服务器中的不同数据库具有不同的值。

使用database_name

选择@@ dbts

因此很明显它与Unix Epoch或任何其他时间相关的参考无关。

它与Sybase SQL Anywhere的时间戳不同。