Oracle 11gR2 Exadata
我需要唯一标识何时创建记录。序列缓存意味着我不能使用基于序列的 ID,而批量插入意味着在一个批次中插入的所有记录都将具有相同的时间戳值(即使使用 TIMESTAMP(9))。类似于 Twitter 的since_id 概念。
到目前为止我想到的最好的选择
这是我的要求:我有一个 API,它允许用户提供一个序列作为标记并请求自那时以来的所有记录。例如,他们请求 1000 条标记为 7 的记录,他们将从我的表中获得 1000 条 ID 大于 1007 的记录。例如,假设返回的 1000 条记录的数字最大 ID 是 2045,因此我们返回 2045 作为标记 后来客户端请求 1000 条记录,标记为 2045,期望获得下一批 1000 条记录和一个新标记。
一种非常简单的方法,允许他们获取适合他们的任何大小的所有记录而不会丢失任何记录。但是,由于跨多个 Exadata 节点的序列缓存,在客户端请求 1000 条标记为 1007 的记录时,可能尚未创建 ID 为 2020 的记录。因此,当他们使用标记 2045 执行下一个请求时,他们将永远错过记录 2020。使用 ID 获取关联记录的时间戳可以解决这个问题,但是我必须确保始终将记录单独插入表中以保证唯一的时间戳。
假设:
希望我只是没有找到正确的术语来搜索现有答案。我觉得这是一个多年来应该通过某些模式解决的问题。我认为 Twitter 已经解决了它......
我有一个带有日志数据的大型 postgreSQL 数据库。所有这些数据都有时间戳,我想对时间戳之间的差异小于 1500 毫秒的连续行进行分组。
例如:
1349427083272
1349427083669
1349427083707
1349427084277
1349427084787
1349427093471
1349427094031
1349427094307
1349427094980
1349427095879
1349427097211
1349437622947
1349437623813
1349437624316
1349437624815
1349437624938
Run Code Online (Sandbox Code Playgroud)
应导致以下组:
1349427083272
1349427083669
1349427083707
1349427084277
1349427084787
1349427093471
1349427094031
1349427094307
1349427094980
1349427095879
1349427097211
1349437622947
1349437623813
1349437624316
1349437624815
1349437624938
Run Code Online (Sandbox Code Playgroud)
组标识符可以只是一个唯一的整数。
在 MySQL 中,我发现了一个类似的例子,它使用了很多变量,但我不知道如何在 postgreSQL 中做到这一点。有人可以帮我吗?
在 Sql Server 中,使用主键的缺点和缺点是:
两个字符表标识符 + YEAR + MONTH + DAY + HOUR + MINUTE + MILLISECOND + 0 到 100 之间的随机整数?
为什么这比使用 Integer Auto_Incremented 字段更受欢迎?(除非它不会,那我也想知道。)
我很想知道为什么这是一个非常糟糕的设计实践。为了取回该整数值而强制转换所有内容也是一件非常痛苦的事情。
我基本上有机会让我的小开发团队访问以帮助改进我们的应用程序数据库,这是非常需要的 - 避免像主键 Varchar(50) 字段左填充零这样的情况,或者只是开始改进非- 规范化的数据库,或一个字段中的逗号分隔列表。
database-design sql-server best-practices primary-key timestamp
我有一张名为accounts. 我有兴趣检索状态超过 10 天未更新的那些帐户。我想过这个查询,它似乎有效,但我不确定这是最好的方法:
SELECT * from accounts
WHERE status = 'PENDING_PAYMENT'
AND (date_part('day', (now() - status_updated_at)) > 10);
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个now()部分的一件事是。如果now()不是为每个记录计算而是在开始时计算单个时间戳值,那将是理想的。此外,我希望这个例子返回1:
假设对于一条记录,该status_updated_at列具有以下值:2015-10-05 23:00:00。并now()返回2015-10-06 01:00:00。尽管只有几个小时的差异,但我希望结果是1.
我的公司正在启动一项旨在从头开始构建财务数据库的新计划。
我们将通过以下方式使用它:
数据的大致范围:
周期:每日、每月、每季度、每年
20 年的回顾会随着时间的推移而增长
问题:在我们的 PostgreSQL 数据库中,我们应该使用什么模式?现在我正在考虑每个公司的一个时间序列表,完全规范化数据库的每个数据字段类别。例如,一个表用于 IBM 的所有资产负债表字段,另一个表用于 IBM 的现金流项目等,用于所有类别的数据和每个公司。时间戳作为记录和数据字段作为列/字段。然后对于快速查询,创建一个仓库和视图等,它们没有完全规范化,但针对我上面列出的用例的查询进行了优化。但是,如果您查看我上面的公司和领域的数量,如果我的表格很宽,我可能会得到超过 200,000 个表格,仅用于我的基本财务数据,这也不是很好。这是很多表,但我没有看到另一种好的方法来做到这一点。
如果有更好的地方问这个问题,请告诉我。
如果您需要更多信息,我很乐意编辑我的问题并添加它。
PS - 我在 SO Quant 网站上问了一个类似的问题,但没有得到太多的架构帮助。此外,非模式集中的答案是可以的,但请注意,我正在寻求模式设计方面的帮助。
该表reports按天分区表,例如reports_20170414,reports_20170415
约束 SQL 定义如下
CHECK (
rpt_datetime >= '2017-04-14 00:00:00+00'::timestamp with time zone
AND
rpt_datetime < '2017-04-15 00:00:00+00'::timestamp with time zone
)
Run Code Online (Sandbox Code Playgroud)
让我们考虑两种类型的查询
SELECT SUM(rpt_unique_clicks)
FROM reports WHERE rpt_datetime >= '2017-04-14 00:00:00';
Run Code Online (Sandbox Code Playgroud)
以上查询在亚秒内运行,一切正常。
SELECT SUM(rpt_unique_clicks)
FROM reports WHERE rpt_datetime >=
date_trunc('day', current_timestamp);
Run Code Online (Sandbox Code Playgroud)
相反,上面的查询运行至少 15 秒。
SELECT date_trunc('day', CURRENT_TIMESTAMP), '2017-04-14 00:00:00';
Run Code Online (Sandbox Code Playgroud)
返回
2017-04-14 00:00:00 +00:00 | 2017-04-14 00:00:00
Run Code Online (Sandbox Code Playgroud)
当我检查为什么后者运行时间长(使用解释分析)时,我完成了它访问并扫描每个表(~500)的结果,但前者仅访问,reports_20170414因此约束检查存在问题。
我想查询今天,而不是像后一个查询那样使用准备好的语句。为什么date_trunc('day', CURRENT_TIMESTAMP)不等于 2017-04-14 00:00:00?
postgresql constraint partitioning timestamp check-constraints
大多数情况下,我们使用整数序列作为主键来保持表中行的唯一性。为此,我们不能使用时间戳而不是整数吗?该策略是否有任何缺陷,因为我认为机器不能同时“同时”做两件事......对吗?
我正在处理一个在键中包含大量休眠序列的数据库,所以我想使用时间戳作为解决方案。在实践中是否有任何类似的方法可以与任何数据库一起使用?要是知道就好了。
编辑:我要问的是,由于对我们(人类)来说,没有两个时刻是相同的,这对计算机也适用吗?我知道计算机通过某些晶体的振动来跟踪时间(不确定它可以测量多小的时间)。
在数据库中,我有一些表,除了时间(审计跟踪)外没有主键适用,并且指定一个序列(hibernate_sequence)将数字增加到极高的程度,这使得使用其他表不方便,因为它会影响所有表序列作为主键。
因此,如果 PostgreSQL 可以保证不会在同一时间戳上发生两次插入/更新操作,那么我可以将其用作主键,但如果不能,则显然我不能使用此解决方案。
基本问题是:PostgreSQL的规定,任何两个记录将被插入/同时更新任何保证(通过某些方法或配置)“时间”?
谢谢
我知道,在 PostgreSQL 中,返回值NOW()是事务开始时间戳。因此,如果您NOW()在同一事务中多次使用,它将始终返回相同的值。
这在我的书中是很好的。
但是我在客户端应用程序中的单元测试方面遇到了一个小问题,并且希望能够告诉 PostgreSQL 如果可能的话(暂时)禁用它。
我不想(不能)使用另一个时间戳函数的原因是clock_timestamp()因为函数调用NOW()位于触发器内部,并且在生产代码中我想要“事务开始”行为。
但在我的单元测试中,我正在修补 API 级“提交”功能,这样我就不会在测试期间意外地将真实数据提交到数据库(不用担心,我在测试期间不使用生产数据库)。因此,在单元测试期间,commit永远不会访问数据库,因此我没有获得新的事务时间戳。
数据库使用时态表,如果时间戳发生更改,新条目仅会附加到历史表中,以确保每个事务仅合并历史表中的一个条目。
但是,当测试时态表行为时,这会导致历史表中不会出现任何条目。时态表触发器的关键片段是这样的:
new_validity_period = tstzrange(
lower(OLD.validity_period),
NOW(),
'[)'
);
IF isempty(new_validity_period) THEN
RAISE DEBUG 'New entry % will not introduce a new history item', OLD;
RETURN OLD;
END IF;
Run Code Online (Sandbox Code Playgroud)
因此,当我在单元测试中执行“插入”操作,且交易时间为“2020-01-01 01:02:03”时,该条目的有效期将为[2020-01-01 01:02:02,)。如果仍然在同一个单元测试中,我删除该条目(并测试它是否出现在历史表中),则该操作发生在同一个 TX 中,上面的代码将如下所示:
new_validity_perion = tstzrange(
'2020-01-01 01:02:03', -- the lower-bound of the 'OLD' row
'2020-01-01 01:02:03', -- the result of …Run Code Online (Sandbox Code Playgroud) PostgreSQL 允许time/timestamp指定精度:
time,timestamp, 并interval接受一个可选的精度值p,该值指定保留在秒字段中的小数位数。默认情况下,没有明确的精度限制。的允许范围p是 0 到 6。
然而它指出的存储空间是一个常数8字节(timestamp和time without timezone为)和12字节time with timezone的无论p。
在不需要额外精度的情况下——比如毫秒(p = 3)或秒(p=0)就足够了——显式降低精度是否有优势?
TLDR:我可以创建一个由以下WHERE子句使用的索引吗:
WHERE foo_date <@ tsrange('2018-01-01', '2018-02-01')
Run Code Online (Sandbox Code Playgroud)
创建表 foo
(
foo_id INTEGER 由默认身份生成,
不带时区的 foo_date 时间戳 NOT NULL,
约束 foo_pkey 主键 (foo_id)
);
此表包含 100,000 条记录,日期从2009-01-01到2018-12-29。我希望能够查询给定日期范围内的行(例如 2018 年 1 月的行)。
一种方法是使用BETWEEN运算符:
SELECT * FROM foo WHERE foo_date BETWEEN '2018-01-01' AND '2018-01-31';
这种方法的问题是,如果foo_date发生在2018-01-31午夜之后,它们将不会包含在此查询中。所以我可以将查询更改为BETWEEN '2018-01-01' AND '2018-02-01'. 那么问题来了,然而,上发生的记录2018-02-01 00:00:00。这些将被包括在内,这是我不想要的。
Aaron Bertrand提出的另一种选择是使用这个结构:
foo_date >= '2018-01-01' AND foo_date < '2018-02-01'
Run Code Online (Sandbox Code Playgroud)
(是的,此博客适用于 …
timestamp ×10
postgresql ×7
primary-key ×2
constraint ×1
disk-space ×1
group-by ×1
index ×1
oracle ×1
partitioning ×1
performance ×1
range-types ×1
schema ×1
sequence ×1
sql-server ×1