我有下表:
CREATE TABLE post (
id bigint primary key,
thread_id bigint,
is_notice boolean,
title text,
content text
)
Run Code Online (Sandbox Code Playgroud)
我使用以下查询显示列表:
SELECT * FROM post ORDER BY is_notice desc, thread_id desc, id
Run Code Online (Sandbox Code Playgroud)
然后,给定由 id(ie SELECT * FROM post where id=3)选择的帖子,我如何检索下一个和上一个帖子?
我有这个UNIQUE限制:
ALTER TABLE table ADD CONSTRAINT "abc123" UNIQUE
("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8");
Run Code Online (Sandbox Code Playgroud)
然后我这样做:
INSERT INTO table ("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8")
VALUES ('a', 'b', 'c', 'd', 'e', 'f', null, true);
INSERT INTO table ("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8")
VALUES ('a', 'b', 'c', 'd', 'e', 'f', null, true);
Run Code Online (Sandbox Code Playgroud)
两者都有效。两行已添加到表中。从逻辑上讲,第二个应该失败。但事实并非如此。
我究竟做错了什么?这让我发疯。
注意:如果这是我自己的数据,我将拥有一个真正独特的列,而不是这个“疯狂”的UNIQUE约束。问题是这个表保存了我的银行帐户的记录,而且他们愚蠢地在 CSV 转储中没有真正的“唯一”列,我可以用它来实际确保不插入重复的行,所以我有提出一个组合整个表中所有列以确定唯一性的方法。
我注意到最近会话以红色突出显示,尽管过去从未发生过这种情况,这让我相信这是一个新功能。它似乎只发生在挂起的查询上。我查看了 PgAdmin 文档以及所有最近更新的更改日志,但找不到解释。下面是它的显示方式的示例:
在教授数据库基础课程时,一名学生询问外键的数据类型与他们引用的事物(例如主键)的数据类型不匹配。
例如,可以存储在INTEGER列中的所有数字都可以表示为TEXT,因此只要应用适当的类型转换/转换,TEXT列的数据就可以用于引用列中的数据。INTEGER
我们在教学中使用 PostgreSQL(因为它的文档非常好等等),所以我们就去看了一下。你瞧,关于外键的“简化”章节告诉我们:
当然,受约束列的数量和类型需要与引用列的数量和类型相匹配。
不过,有关CREATE TABLE 的“功能完整”部分的进一步研究并未明确提及数据类型。这部分只讲价值观。
我们尝试了各种数据类型的组合,其中一些比其他组合更有说服力(例如上面的INTEGER-变体)。TEXTDBMS 不相信并回复42804:不兼容的类型。
到目前为止,一切都很好。想象一下,当我们发现 PostgreSQL 的各种整数类型实际上可以工作时,我们会多么惊讶。
他们甚至正确地考虑了符号,这意味着他们不仅仅是匹配位。
当然,这应该有一个方向:拥有一个由列INTEGER引用的列BIGINT总是有效的,因为适合引用列的所有内容也适合引用列。
令人惊讶的是,PostgreSQL 允许另一个方向(在本例中使用INTEGER和SMALLINT):
CREATE TABLE this_should_not_work
(
this_should_not_work_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
data TEXT
);
CREATE TABLE this_should_not_work_detail
(
detail_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
detail_data TEXT,
-- This Foreign Key references a column of …Run Code Online (Sandbox Code Playgroud) 在 PostgreSQL (8.4) 中,我试图将字符串参数转换为 SQL 查询中的日期,然后返回到now()字符串不是有效日期(或为空)时。
在“伪SQL”中,这将是这样的:
SELECT CASE WHEN ? is not a valid date THEN now()::DATE ELSE CAST(? AS DATE) END;
Run Code Online (Sandbox Code Playgroud)
我尝试使用这两个查询来简化问题以检测空字符串:
SELECT CASE WHEN ?='' THEN now()::DATE ELSE CAST(? AS DATE) END;
SELECT DATE(CASE WHEN ?='' THEN now() ELSE ? END);
Run Code Online (Sandbox Code Playgroud)
例如,如果参数是'',则相当于:
SELECT CASE WHEN ''='' THEN now()::DATE ELSE CAST('' AS DATE) END;
SELECT DATE(CASE WHEN ''='' THEN now() ELSE '' END);
Run Code Online (Sandbox Code Playgroud)
两者都失败了ERROR: invalid input syntax for type timestamp with time zone: …
首先,我搜索并找到了几篇与此错误相关的帖子,其中大多数都指向 RAM 问题或 SSL 问题,我尝试通过在命令行中添加 sslmode=disabled 来克服 SSL 的可能性:
psql -U waypoint -d waypoint -W -c "alter table telemetria_data.historico alter clase type smallint, alter valor type real[], alter power type smallint, alter voltaje type real;" -h localhost -v sslmode=disable
Run Code Online (Sandbox Code Playgroud)
但同样的消息出现了:
SSL SYSCALL error: EOF detected
connection to server was lost
Run Code Online (Sandbox Code Playgroud)
关于可能的内存问题,我不知道如何解决。
数据结构是这个问题中描述的数据结构,正如您可能发现的那样,这将是一个非常长的运行查询,以完成对所有继承表的完整更改表。
操作系统:
Linux ip-10-1-0-9 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
PostgreSQL:
PostgreSQL 9.4.9 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
Run Code Online (Sandbox Code Playgroud)
更新 2017-06-01 13:50 …
Microsoft SQL Server 提供了NEWID生成新 GUID(UUID的 Microsoft 版本)值的命令,该值可用作主键值(在其uniqueidentifier数据类型中)。这些本质上不是顺序的,因此更新索引可能效率低下。
或者,MS SQL Server 提供该NEWSEQUENTIALID命令。引用他们的文档:
创建一个 GUID,该 GUID 大于自 Windows 启动以来此函数在指定计算机上先前生成的任何 GUID。重新启动 Windows 后,GUID 可以从较低的范围再次启动,但仍然是全局唯一的。当 GUID 列用作行标识符时,使用 NEWSEQUENTIALID 比使用 NEWID 函数更快。这是因为 NEWID 函数会导致随机活动并使用较少的缓存数据页。使用 NEWSEQUENTIALID 还有助于完全填充数据和索引页。
有没有办法在 Postgres 中获得更有效索引的 UUID?
我在与 Lukas Eder的Twitter 对话中偶然发现了这个问题。
尽管正确的行为是在最外层查询上应用 ORDER BY 子句,因为在这里,我们没有在最外层查询中使用 DISTINCT、GROUP BY、JOIN 或任何其他 WHERE 子句,为什么 RDBMS 不只是通过传入的数据是按内部查询排序的吗?
SELECT *
FROM (
SELECT * FROM table ORDER BY time DESC
) AS t
Run Code Online (Sandbox Code Playgroud)
在 PostgreSQL 上运行此示例时,至少,您会为内部查询和此派生表示例获得相同的执行计划,以及相同的结果集。
因此,我假设 Planner 将简单地丢弃最外层的查询,因为它是多余的,或者只是通过内部表的结果。
有没有人认为情况可能并非如此?
我已经安装了 Windows 10 秋季更新 (1709),现在我的 PostgreSQL 9.5 服务器无法启动。它昨天在更新前工作,我没有对配置进行任何更改。
我检查了事件查看器并发现以下错误消息:
2017-10-19 11:32:32 CEST LOG: invalid value for parameter "lc_monetary": "Czech_Czech Republic.1250"
2017-10-19 11:32:32 CEST LOG: invalid value for parameter "lc_numeric": "Czech_Czech Republic.1250"
2017-10-19 11:32:32 CEST LOG: invalid value for parameter "lc_time": "Czech_Czech Republic.1250"
2017-10-19 11:32:32 CEST FATAL: configuration file "C:/Program Files/PostgreSQL/9.5/data/postgresql.conf" contains errors
Run Code Online (Sandbox Code Playgroud)
似乎微软在秋季更新时更改了语言环境名称,我找不到任何可用语言环境名称的列表,所以我决定安装 Postgres 10 并证实了我的怀疑,Postgres 10 中的 postgresql.conf 现在显示为:
# These settings are initialized by initdb, but they can be changed.
lc_messages = 'Czech_Czechia.1250' # locale for system error …Run Code Online (Sandbox Code Playgroud) 我有很多看起来像这样的表格:
CREATE TABLE table1(id INTEGER PRIMARY KEY, t1c1 INTEGER, t1c2 INTEGER);
CREATE TABLE table2(id INTEGER PRIMARY KEY, t1 INTEGER REFERENCES table1(id), t2c1 INTEGER);
Run Code Online (Sandbox Code Playgroud)
我做了很多连接,我试图过滤连接表以从第一个表中获取内容,如下所示:
SELECT t1c1
FROM table1
JOIN table2 ON table2.t1 = table1.id
WHERE t2c1 = 42;
Run Code Online (Sandbox Code Playgroud)
当我为表编写索引时,我会查看 WHERE 子句中使用的列并构建索引以满足它们。所以对于这个查询,我最终会写一个这样的索引:
CREATE INDEX ON table2 (t2c1);
Run Code Online (Sandbox Code Playgroud)
并且这个索引至少有资格在该查询中使用。
我的问题是,如果我写这样的索引:
CREATE INDEX ON table2 (t2c1, t1);
Run Code Online (Sandbox Code Playgroud)
索引会不会作为覆盖索引来帮助上面查询中的JOIN?我应该改变我的索引编写策略来覆盖外键列吗?
postgresql ×10
index ×2
aws ×1
datatypes ×1
foreign-key ×1
mysql ×1
null ×1
optimization ×1
oracle ×1
order-by ×1
pgadmin ×1
pgadmin-4 ×1
primary-key ×1
select ×1
uuid ×1
windows-10 ×1