相关疑难解决方法(0)

表如何违反它自己的主键索引?

我有一个PostgreSQL数据库,它有一个表,主键应用于三列.根据数据库,密钥上有一个索引:

Indexes:
    "full_log_pkey" PRIMARY KEY, btree (server_name, line_number, log_generation)
Run Code Online (Sandbox Code Playgroud)

然而一些简单的测试表明我有重复的键:

select count(*) from full_log;
  count
----------
 60644405

select count(*) from 
    (select distinct server_name, 
                     line_number, 
                     log_generation 
            from     full_log) as foo;
  count
----------
 60636564
Run Code Online (Sandbox Code Playgroud)

显然,与行相比,不同的行(基于主键)更少.我的问题是,这怎么可能?

编辑:完整的表定义是这样的:

                 Table "public.full_log"
     Column     |            Type             | Modifiers
----------------+-----------------------------+-----------
 activity       | character(1)                |
 archivaldate   | timestamp without time zone |
 media_type     | character varying(5)        |
 vsn            | text                        |
 archive_set    | character varying(20)       |
 copy           | smallint                    |
 file_start     | integer                     |
 file_offset    | integer                     |
 fs_name …
Run Code Online (Sandbox Code Playgroud)

sql postgresql primary-key composite-primary-key

6
推荐指数
1
解决办法
277
查看次数

使用规则插入辅助表自动递增序列

要在第二个表中自动添加列以通过唯一索引将其绑定到第一个表,我有一个如下规则:

CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (NEW.userid);
Run Code Online (Sandbox Code Playgroud)

如果user.userid是一个整数,这可以正常工作.但是,如果它是一个序列(例如,类型为serialbigserial),那么插入到lastlogin表中的是下一个序列id.所以这个命令:

INSERT INTO user (username) VALUES ('john');
Run Code Online (Sandbox Code Playgroud)

将列[1,'john',...]插入用户,但将列[2,...]插入lastlogin.以下2个解决方法确实有效,但第二个解决方案消耗了两倍的序列号,因为序列仍然是自动递增的:

CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (lastval());

CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (NEW.userid-1);
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果我插入多行,解决方法不起作用:

INSERT INTO user (username) …
Run Code Online (Sandbox Code Playgroud)

postgresql rules

5
推荐指数
1
解决办法
3849
查看次数

PostgreSQL-插入记录的干净方法(如果它们不存在,则更新)

这是我的情况。我有一个带有一堆URL和与之关联的爬网日期的表。当我的程序处理URL时,我想插入一个具有爬网日期的新行。如果URL已经存在,我想将爬网日期更新为当前日期时间。对于MS SQL或Oracle,我可能为此使用MERGE命令。对于mySQL,我可能会使用ON DUPLICATE KEY UPDATE语法。

我可以在程序中执行多个查询,这些查询可能是线程安全的,也可能不是线程安全的。我可以编写一个具有各种IF ... ELSE逻辑的SQL函数。但是,为了试用以前从未使用过的Postgres功能,我正在考虑创建INSERT规则-类似于以下内容:

CREATE RULE Pages_Upsert AS ON INSERT TO Pages
  WHERE EXISTS (SELECT 1 from Pages P where NEW.Url = P.Url)
  DO INSTEAD
     UPDATE Pages SET LastCrawled = NOW(), Html = NEW.Html WHERE Url = NEW.Url;
Run Code Online (Sandbox Code Playgroud)

这实际上看起来很棒。从“代码可读性”的角度来看,它可能会失去一些意义,因为初次查看我的代码的人必须神奇地知道此规则,但是我想可以通过良好的代码注释和文档来解决。

此想法是否还有其他缺点,或者“您的想法糟透了,您应该/ this /方式代替”注释?如果那很重要,我将使用PG 9.0。

更新:查询计划,因为有人想要它:)

"Insert  (cost=2.79..2.81 rows=1 width=0)"
"  InitPlan 1 (returns $0)"
"    ->  Seq Scan on pages p  (cost=0.00..2.79 rows=1 width=0)"
"          Filter: ('http://www.foo.com'::text = lower((url)::text))"
"  ->  Result  (cost=0.00..0.01 rows=1 width=0)"
" …
Run Code Online (Sandbox Code Playgroud)

database postgresql rules upsert

4
推荐指数
1
解决办法
7246
查看次数

将插入的id插入到另一个表中

这是场景:

create table a (
 id serial primary key,
 val text
);

create table b (
 id serial primary key,
 a_id integer references a(id)
);

create rule a_inserted as on insert to a do also insert into b (a_id) values (new.id);
Run Code Online (Sandbox Code Playgroud)

b我正在尝试创建一条引用a插入表时的记录a。但我得到的是new.idnull,因为它是从序列自动生成的。我也尝试了触发器AFTER插入FOR EACH ROW,但结果是相同的。有办法解决这个问题吗?

sql postgresql triggers entity-relationship primary-key

2
推荐指数
1
解决办法
5742
查看次数