我正在处理Rails和Postgres中的日期和时间并遇到这个问题:
数据库采用UTC格式.
用户在Rails应用程序中设置选择的时区,但仅在获取用户本地时间来比较时间时使用.
用户存储时间,例如2012年3月17日晚上7点.我不希望存储时区转换或时区.我只想保存日期和时间.这样,如果用户改变他们的时区,它仍将显示2012年3月17日,晚上7点.
我只使用用户指定的时区来获取用户本地时区当前时间之前或之后的记录.
我目前正在使用"没有时区的时间戳",但是当我检索记录时,rails(?)会将它们转换为应用程序中的时区,这是我不想要的.
Appointment.first.time
=> Fri, 02 Mar 2012 19:00:00 UTC +00:00
Run Code Online (Sandbox Code Playgroud)
因为数据库中的记录似乎是以UTC形式出现的,我的黑客是用当前时间,用'Date.strptime(str,"%m /%d /%Y")删除时区,然后做我的查询:
.where("time >= ?", date_start)
Run Code Online (Sandbox Code Playgroud)
似乎必须有一种更简单的方法来忽略周围的时区.有任何想法吗?
由于Postgres能够进行LATERAL
连接,我一直在阅读它,因为我目前为我的团队执行复杂的数据转储,其中包含大量低效的子查询,这使得整个查询需要四分钟或更长时间.
我知道LATERAL
联接可能能够帮助我,但即使在阅读了像Heap Analytics 这样的文章之后,我仍然没有完全遵循.
LATERAL
加入的用例是什么?LATERAL
连接和子查询之间有什么区别?
我正在使用Postgres(PL/pgSQL)开发一个算法,我需要计算两个时间戳之间的工作小时数,考虑到周末不工作,剩下的时间只计算在上午8点到下午15点.
例子:
从12月3日下午14点到12月4日上午9点应该计算2个小时:
3rd = 1, 4th = 1
Run Code Online (Sandbox Code Playgroud)从12月3日下午15点到12月7日上午8点,应该计算8小时:
3rd = 0, 4th = 8, 5th = 0, 6th = 0, 7th = 0
Run Code Online (Sandbox Code Playgroud)考虑小时分数也会很棒.
我正在创建一个在PostgreSQL 9.2.4中存储任意日期/时间范围的数据库.我想在这个数据库上设置一个约束,它强制日期/时间范围不重叠,不相邻(因为两个相邻的范围可以表示为单个连续范围).
为此,我使用EXCLUDE
带有GiST索引的约束.这是我目前的约束:
ADD CONSTRAINT overlap_exclude EXCLUDE USING GIST (
box(
point (
extract(EPOCH FROM "from") - 1,
extract(EPOCH FROM "from") - 1
),
point (
extract(EPOCH FROM "to"),
extract(EPOCH FROM "to")
)
) WITH &&
);
Run Code Online (Sandbox Code Playgroud)
列from
和to
都是TIMESTAMP WITHOUT TIME ZONE
,并且是以UTC格式存储的日期/时间(在我的应用程序中将数据插入这些列之前,我转换为UTC,并且我在postgresql.conf中将我的数据库的时区设置为"UTC").
但是,我想我可能遇到的问题是,这个约束正在做出(错误的)假设,即没有小于一秒的时间增量.
值得注意的是,对于我存储的特定数据,我只需要第二个分辨率.不过,我觉得我可能还是需要处理这个,因为SQL类型timestamp
和timestamptz
都超过一秒更高的分辨率.
我的问题是:是否有任何问题,只是假设第二个解决方案,因为这是我的所有应用程序需要(或想要),或者,如果有,我怎么能改变这个约束来处理一个秒的分数健壮的方式?
我有一个简单的表,其中有一个带有日期类型的 user_birthday 字段(可以是 NULL 值)
CREATE TABLE users
(
user_id bigserial NOT NULL,
user_email text NOT NULL,
user_password text,
user_first_name text NOT NULL,
user_middle_name text,
user_last_name text NOT NULL,
user_birthday date,
CONSTRAINT pk_users PRIMARY KEY (user_id)
)
Run Code Online (Sandbox Code Playgroud)
该字段上定义了一个索引(btree),其规则为 NOT user_birthday IS NULL。
CREATE INDEX ix_users_birthday
ON users
USING btree
(user_birthday)
WHERE NOT user_birthday IS NULL;
Run Code Online (Sandbox Code Playgroud)
为了跟进另一个想法,我添加了扩展btree_gist
并创建了以下索引:
CREATE INDEX ix_users_birthday_gist
ON glances.users
USING gist
(user_birthday)
WHERE NOT user_birthday IS NULL;
Run Code Online (Sandbox Code Playgroud)
但它也没有影响,因为据我所知,它不用于范围检查。
PostgreSQL 版本为 9.3.4.0 (22) Postgres.app ,问题也存在于 9.3.3.0 (21) …
我需要有相当于这个exclusion
约束的东西
drop table if exists t;
create table t (
i int,
tsr tstzrange,
exclude using gist (i with =, tsr with &&)
);
ERROR: data type integer has no default operator class for access method "gist"
HINT: You must specify an operator class for the index or define a default operator class for the data type.
Run Code Online (Sandbox Code Playgroud)
我想从错误消息中可以看出问题是显而易见的。怎么做?
CREATE TABLE operating_period (
id SERIAL NOT NULL PRIMARY KEY,
during TSTZRANGE NOT NULL,
-- other meta fields
);
Run Code Online (Sandbox Code Playgroud)
要求:1.运营期间不得相互重叠
题:
(start_at, end_at)
还是GIST索引快速tstzrange
?tstzrange
常用吗?或者我最好用两列?postgresql ×7
range-types ×3
sql ×3
datetime ×2
indexing ×2
b-tree-index ×1
constraints ×1
date-range ×1
gist-index ×1
lateral-join ×1
operators ×1
range ×1
subquery ×1
timezone ×1